diff --git a/13-前端面试/02-性能优化/00-前言.md b/13-前端面试/02-前端性能优化/00-前言.md similarity index 100% rename from 13-前端面试/02-性能优化/00-前言.md rename to 13-前端面试/02-前端性能优化/00-前言.md diff --git a/13-前端面试/02-性能优化/前端性能优化(一):静态资源优化.md b/13-前端面试/02-前端性能优化/01-静态资源优化.md similarity index 69% rename from 13-前端面试/02-性能优化/前端性能优化(一):静态资源优化.md rename to 13-前端面试/02-前端性能优化/01-静态资源优化.md index 1853fbe..062f4e7 100644 --- a/13-前端面试/02-性能优化/前端性能优化(一):静态资源优化.md +++ b/13-前端面试/02-前端性能优化/01-静态资源优化.md @@ -361,10 +361,233 @@ CSS 加载不会阻塞 DOM tree 解析,但是会阻塞 DOM Tree 渲染,也 - Google 字体库因为某些不可抗拒原因,应该使用国内托管服务 -### 6、CSS 动画优化 +### 6、CSS 动画优化 - 尽量避免同时出现过多动画。 - 延迟动画初始化:让其他的重要的CSS样式优先渲染。 - 结合 SVG。 + + +## JavaScript 总体优化 + +### 提升 JavaScript 文件加载性能 + +加载元素的顺序 CSS 文件放在
里, JavaScript 文件放在 里。 + +### JavaScript 变量和函数优化 + +- 尽量使用 id 选择器 + +- 尽量避免使用 eval + +- JavaScript 函数尽可能保持简洁 + +- 使用事件节流函数 + +- 使用事件委托 + +### JavaScript 动画优化 + +- 避免添加大量 JavaScript 动画 + +- 尽量使用 CSS3 动画 + +- 尽量使用 Canvas 动画 + +- 合理使用 requestAnimationFrame 动画代替 setTimeout、setInterval + +- requestAnimationFrame可以在正确的时间进行渲染,setTimeout(callback)和setInterval(callback)无法保证 callback 回调函数的执行时机。 + +### 合理使用缓存 + +- 合理缓存 DOM 对象 + +- 缓存列表长度 + +- 使用可缓存的 Ajax + +## JavaScript 缓存优化 + +### Cookie + +通常由浏览器存储,然后将 Cookie 与每个后续请求一起发送到同一服务器。收到HTTP 请求时,服务器可以发送带有 Cookie 的 header 头。可以给 Cookie 设置有效时间。 + +应用: + +- 会话管理:登录名,购物车商品,游戏得分或服务器应要记录的其他任何内容 + +- 个性化:用户首选项,主题或其他设置 + +- 跟踪:记录和分析用户行为,比如visitkey + +### sessionStorage + +创建一个本地存储的键/值对。 + +应用: + +- 缓存。 + +- 页面应用页面之间传值。 + +### LocalStorage + +本地存储。 + +应用于: + +- 缓存静态文件内容 JavaScript /CSS(比如百度M站首页) + +- 缓存不常变更的 API 接口数据 + +- 储存地理位置信息 + +- 浏览在页面的具体位置 + +### IndexedDB + +索引数据库。 + +应用: + +- 客户端存储大量结构化数据 + +- 没有网络连接的情况下使用(比如 Google Doc、石墨文档) + +- 将冗余、很少修改、但经常访问的数据,以避免随时从服务器获取数据 + +## JavaScript 模块化加载方案和选型 + +- CommonJS + +旨在 Web 浏览器之外为 JavaScript 建立模块生态系统。Node.js 模块化方案受 CommonJS。 + + +- AMD (Asynchronous Module Definition)(异步模块定义)规范。 + +RequireJS 模块化加载器:基于 AMD API 实现。 + +- CMD( Common Module Definition)(通用模块定义)规范。 + +SeaJS 模块化加载器:遵循 CMD API 编写。 + +- ES6 import。 + +## 减少回流和重绘重要举措 + +### CSS + +- 避免过多样式嵌套 + +- 避免使用 CSS 表达式 + +- 使用绝对定位,可以让动画元素脱离文档流 + +- 避免使用 table 布局 + +- 尽量不使用 float 布局 + +- 图片最好设置好 width 和 height + +- 尽量简化浏览器不必要的任务,减少页面重新布局 + +- 使用 Viewport 设置屏幕缩放级别 + +- 避免频繁设置样式,最好把新 style 属性设置完成后,进行一次性更改 + +- 避免使用引起回流/重绘的属性,最好把相应变量缓存起来 + +### JavaScript + +- 最小化回流和重排:为了减少回流发生次数,避免频繁或操作 DOM,可以合并多次对 DOM 修改,然后一次性批量处理。 + +- 控制绘制过程和绘制区域:绘制过程开销比较大的属性设置应该尽量避免减少使用;同时,减少绘制区域范围。 + + +## DOM 编程优化的⽅式方法 + +### 控制 DOM 大小 + +众所周知,页面交互卡顿和流畅度很大一部分原因就是页面有大量 DOM 元素。想象一下,从一个上万节点的 DOM 树上,使用 querySelectorAll 或 getElementByTagName 方法查找某一个节点,是非常耗时的。另外元素绑定事件,事件冒泡和事件捕获的执行也会相对耗时。 + +通常控制 DOM 大小的技巧包括: + +- 合理的业务逻辑 + +- 延迟加载即将呈现的内容 + +### 简化 DOM 操作 + +对DOM节点的操作统一处理后,再统一插入到 DOM Tree中。 + +可以使用 fragment,尽量不在页面 DOM Tree 里直接操作。 + +现在流行的框架 Angular、React、Vue 都在使用虚拟 DOM 技术,通过 diff 算法简化和减少 DOM 操作。 + + +## 静态文件压缩工具介绍 + +HTML 压缩工具: + +- html-minifier:https://www.npmjs.com/package/html-minifier + + +CSS 压缩工具: + +- clean-css:https://www.npmjs.com/package/clean-css + +JavaScript 压缩工具: + +- uglify-js:https://www.npmjs.com/package/uglify-js + +- 使用方法:uglifyjs in.js -o out.js + +## 静态⽂文件打包⽅方案 + +- 公共组件拆分 + +- 压缩: JavaScript /CSS/图片 + +- 合并: JavaScript /CSS 文件合并,CSS Sprite + +- Combo: JavaScript /CSS 文件 + +## 静态⽂文件版本号更新策略 + +缓存更新:CDN 或 ng 后台刷新文件路径,更新文件header头。 + +文件 name.v1-v100.js: + +- 大功能迭代每次新增一个大版本,比如由 v1 到 v2 + +- 小功能迭代新增加 0.0.1 或者 0.1.0,比如从 v1.0.0 至 v1.0.1 + +- 年末 ng 统一配置所有版本 302 至最新版 + +时间戳.文件 name.js:以每次上线时间点做差异。 + +hash.文件。以文件内容 hash 值做 key。 + +## 前端构建工具介绍和选型建议 + +### 常用构建工具 + +- Gulp:通过流(Stream)来简化多个任务间的配置和输出,配置代码相对较少。 + +- Webpack:预编译,中间文件在内存中处理,支持多种模块化,配置相对很简单。 + +- FIS + + +### webpack 打包优化 + +- 定位体积大的模块 + +- 删除没有使用的依赖 + +- 生产模式进行公共依赖包抽离 + +- 开发模式进行 DLL & DllReference 方式优化 + diff --git a/13-前端面试/02-前端性能优化/02-页面渲染性能优化.md b/13-前端面试/02-前端性能优化/02-页面渲染性能优化.md new file mode 100644 index 0000000..31fea96 --- /dev/null +++ b/13-前端面试/02-前端性能优化/02-页面渲染性能优化.md @@ -0,0 +1,369 @@ +## 浏览器渲染过程 + +![](https://img.smyhvae.com/20210114_2115.png) + +1. 浏览器解析 HTML,生成 DOM Tree(Parse HTML)。 + +2. 浏览器解析 CSS,生成 CSSOM(CSS Object Model)Tree。 + +3. JavaScript 会通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree,浏览器将 DOM Tree 和 CSSOM Tree 合成渲染树(Render Tree)。 + +4. 布局(Layout):根据生成的 Render Tree,进行回流,以计算每个节点的几何信息(位置、大小、字体样式等等)。 + +5. 绘制(Painting):根据渲染树和回流得到的几何信息,得到每个节点的绝对像素。 + +6. 展示(Display):将像素发送给图形处理器(GPU),展示在页面上。 + +## 页面渲染技术方案总览 + +**服务端渲染**: + +- 后端同步渲染、同构直出、BigPipe。 + +**客户端渲染**: + +- JavaScript 渲染:静态化、前后端分离、单页面应用 + +- Web App:React、Vue、PWA + +- Hybrid App:PhoneGap 、AppCan 等 + +- 跨平台开发:RN 、Flutter 、小程序等。 + +- 原生 App:iOS 、Android + +建议: + +- 依赖业务形式、依赖团队规模、依赖技术水平。 + +## 静态化技术方案 + +静态化是使动态化的网站生成静态 HTML 页面以供用户更好访问的技术,一般分为纯动态化和伪动态化。 + +技术优势: + +- 提高了页面访问速度,降低了服务器的负担,因为访问页面时不需要每次去访问数据库。 + +- 提高网站内容被搜索引擎搜索到的几率,因为搜索引擎更喜欢静态页面。 + +- 网站更稳定,如果后端程序、数据库出现问题,会直接影响网站的正常访问,而静态化页面有缓存,更不容易出现问题。 + +技术不足: + +- 服务器存储占用问题,因为页面量级在增加,要占用大量硬盘空间。 + +- 静态页面中的链接更新问题会有死链或者错误链接问题。 + +技术实现: + +- 跑定时任务,将已有的动态内容进行重定,生成静态的 HTML 页面。 + +- 利用模板技术,将模板引擎中模板字符替换为从数据库字段中取出来的值, 同时生成 HTML 文件。 + +协作方式: + +- 前端统一写好带有交互的完整静态页面。 + +- 后端拆分出静态页面文件,并嵌套在后端模板文件中。 + +选型建议:后端研发人员充分,又需要考虑用户体验、服务器负载的业务。 + +## 前后端分离技术与实现 + +前后端分离是指研发人员分离、业务代码分离、后端实现业务接口,前端渲染页面。 + +技术实现: + +- 后端只负责功能接口实现,提供按照约定的数据格式并封装好的 API 接口。 + +- 前端负责业务具体实现,获取到 API 接口数据后,进行页面模板拼接和渲染,独立上线。 + +协作方式: + +- 前端负责实现页面前端交互,根据后端 API 接口拼装前端模板。 + +- 后端专注于业务功能实现和 API 接口封装。 + +技术优势: + +- 团队更加专注 + +- 提升了开发效率 + +- 增加代码可维护性 + +技术架构: + +- 后端架构:Java、C++、PHP、 + Nginx,使用微服务(比如 Dubbo 等)等实现业务的解耦,所有的服务使用某种协议提供不同的服务(比如 JSF 等) 。 + +- 前端架构:使用 Angular、React、Vue 前端框架并部署页面至 CDN。 + +- 前端架构 2:使用 Angular、React、Vue 前端框架并部署在 Node Server。 + +技术不足: + +- 因为前端需要负责一大部分业务逻辑实现,和服务端同步、静态化,需要前端人力非常多。 + +- 页面数据异步渲染,不利于 SEO,搜索引擎更喜欢纯静态页面。 + +选型建议: + +- 这是大型互联网公司正在采用的开发模式,一句话,如果考虑用户体验,以及前端人力够用,就可以积极采用。 + +## 单页面应用技术方案 + +单页应用(single-page application,缩写 SPA),通过动态重写当前页面,来与用户交互,而非传统的从服务器重新加载整个新页面。这种方法在使用过程中不需要重新加载页面,避免了页面之间切换打断用户体验,使应用程序更像一个桌面应用程序。 + +技术优点: + +- 不错的加载速度:用户往往感觉页面加载非常快,因为一进入页面就能看到页面元素; + +- 良好的交互体验:进行局部渲染,避免不必要的页面间跳转和重复渲染; + +- 前后端职责分离:前端进行页面交互逻辑,后端负责业务逻辑; + +- 减轻服务器负载:服务器只处理数据接口输出,不用考虑页面模板渲染和 HTML 展示。 + +技术缺点: + +- 开发成本相对较高 + +- 首次页面加载时间过多 + +- SEO 难度比较大 + +技术实现: + +- 使用 React、Vue 框架可以很好的。 + +## BigPipe 简介和工作模式 + +BigPipe 通过将页面加载到称为 Pagelet 的小部件中,来加快页面渲染速度,并允许浏览器在 PHB 服务器呈现页面的同时,一直请求页面不同区块的结构,类似一个“流”传输管道。 + +**技术实现**: + +1. 浏览器从服务器请求页面。 + +2. Server 迅速呈现一个包含 标记的页面框架,以及一个包含空 div 元素的主体,这些元素充当 Pagelet 的容器。由于该页面尚未完成,因此与浏览器的 HTTP 连接保持打开状态。 + +3. 浏览器将开始下载 bigpipe.js 文件,然后它将开始呈现页面。 + +4. PHP 服务器进程仍在执行,并且一次构建每个 Pagelet 。Pagelet 完成后,其结果将在`