前端性能优化实践# 知识体系与小册格局 ## 写给读者 提起性能优化,大家现在脑海里第一时间会映射出什么内容呢? 可能是类似[“雅虎军规”](https://developer.yahoo.com/performance/rules.html?guccounter=1)和[《高性能 JavaScript》](https://book.douban.com/subject/5362856/)这样历久弥香的经典之作,也可能是搜索引擎聚合给你的一篇又一篇以性能优化为主题的个人或团队实践而来的“私货”。至少当我确定自己的研发方向、并接到第一个性能优化任务时,我做的第一件事是向搜索引擎求助,第二件事是买书,然后开始了摸着石头过河,前后花费了大量的时间和精力。我深感性能优化实在是前端知识树中特别的一环——当你需要学习前端框架时,文档和源码几乎可以告诉你所有问题的答案,当你需要学习 Git 时,你也可以找到放之四海皆准的实践方案。但性能优化却不一样,它好像只能是一个摸索的过程。 这个摸索的过程是痛苦的、漫长的,也是紧要的。因为在如今的互联网环境下,一个前端团队如果只把性能优化这个任务写在纸上,而不投入实践,它将缺失最基本的竞争力。 笔者写这本小册,是希望通过短短十数个章节的讲解,尽可能降低一些大家学习性能优化的成本。 一方面,这本小册为没有接触过性能优化的新同学建立起一个正确的前端性能优化的“世界观”,知道性能优化是什么、为什么、怎么做,从而使性能优化这件事情有迹可循,有路可走。这样在面试现场被问到性能优化层面的问题时,能够做到滔滔不绝、言之有物,而非像背书一样罗列干巴巴的知识点,最终淹没在茫茫的求职大军中。另一方面,小册可以为在职的工程师们提供一线团队已经实践过的“方法论”,知道什么场景下该做什么事情,最终在脑海中留下一张涵盖核心原理和实践的、可随时查阅并且高度可扩展的性能优化思路索引表。然后在今后的开发生活中可以去践行它,更进一步去挖掘它。把性能优化变作你前端工程师生涯的一门必修课,进而演化为自己研发方面的核心竞争力。 同时,相信大家可以明确这样一个学习观念:任何技术的掌握,都离不开一定比例的理论基础和实际操作的支撑。 具体到前端性能优化这件事情上,我认为它是 20% 的理论,加上至少 80% 的实践,甚至很多理论本身也都是我们在具体的业务场景中实践出来的。所以希望大家阅读本小册时,能够读到一些“书本之外的东西”——最好是一边读一边回忆自己既有的开发经历,尝试去留意哪些知识是已知的,哪些是未知的。 这样读完之后,就可以有的放矢地把这些知识转换为自己的项目实践——前端技术日新月异,性能方案永远都在更迭,所以一定要形成自己的学习思路。 建议每一位读者都带着“学了就要用”的心态去读这本小册。如果阅读结束,能够为你带来哪怕一个小小的开发习惯或者优化观念上的改变,这数小时的阅读时间就算没有白费。 ## 知识体系: 从一道面试题说起 在展开性能优化的话题之前,我想先抛出一个老生常谈的面试问题: > 从输入 URL 到页面加载完成,发生了什么? 这个问题非常重要,因为我们后续的内容都将以这个问题的答案为骨架展开。我希望正在阅读这本小册的各位可以在心里琢磨一下这个问题——无须你调动太多计算机的专业知识,只需要你用最快的速度在脑海中架构起这个抽象的过程——我们接下来所有的工作,就是围绕这个过程来做文章。 我们现在站在性能优化的角度,一起简单地复习一遍这个经典的过程:首先我们需要通过 DNS(域名解析系统)将 URL 解析为对应的 IP 地址,然后与这个 IP 地址确定的那台服务器建立起 TCP 网络连接,随后我们向服务端抛出我们的 HTTP 请求,服务端处理完我们的请求之后,把目标数据放在 HTTP 响应里返回给客户端,拿到响应数据的浏览器就可以开始走一个渲染的流程。渲染完毕,页面便呈现给了用户,并时刻等待响应用户的操作(如下图所示)。 ![](https://user-gold-cdn.xitu.io/2018/10/18/16685737b823244c?w=489&h=329&f=png&s=19023) 我们将这个过程切分为如下的过程片段: 1. DNS 解析 2. TCP 连接 3. HTTP 请求抛出 4. 服务端处理请求,HTTP 响应返回 5. 浏览器拿到响应数据,解析响应内容,把解析的结果展示给用户 大家谨记,我们任何一个用户端的产品,都需要把这 5 个过程滴水不漏地考虑到自己的性能优化方案内、反复权衡,从而打磨出用户满意的速度。 ## 从原理到实践:各个击破 我们接下来要做的事情,就是针对这五个过程进行分解,各个提问,各个击破。 具体来说,DNS 解析花时间,能不能尽量减少解析次数 了解几棵重要的“树”概念:DOM树、CSSOM树、Render树。 我们需要明白,在浏览器中,当一个网页被加载后,其内容并不是直接被展示出来的,浏览器需要经过一系列复杂的处理过程。这个过程主要包含以下几个关键步骤: 1. **解析HTML:** 浏览器首先解析HTML文档,将标签转换为DOM树中的节点,这是文档结构的基础。 2. **构建CSSOM:** 浏览器同时解析页面中的CSS文件,构建CSS对象模型(CSSOM),它包含了所有的CSS规则和信息。 3. **生成Render树:** 浏览器将DOM树和CSSOM树合并,形成Render树。Render树是一个只包含页面上可见内容的树结构,它忽略了那些被CSS隐藏的元素。 4. **布局计算:** 浏览器会计算每个元素的位置和大小,这个步骤涉及到布局计算模块。布局是指确定元素的位置和尺寸的过程,它将影响到页面的视觉效果。 5. **绘制图层:** 浏览器遍历Render树,并在屏幕上绘制每一个节点,形成我们看到的页面。这个过程会使用视图绘制模块,将像素渲染到屏幕上。 6. **整合图层:** 在绘制图层完成后,浏览器将各个图层整合在一起,由CPU发送到GPU,最终通过GPU渲染到屏幕上。 以上步骤中,涉及到的几棵树: - **DOM树(Document Object Model):** HTML文档被解析后形成DOM树,它代表了文档的结构和内容。每个节点都是一个DOM元素,代表HTML标记中的一个标签。 - **CSSOM树(CSS Object Model):** 浏览器解析CSS文件后形成的树结构。CSSOM树包含了所有的CSS规则和节点,这些节点代表了样式的继承和层叠。 - **Render树:** 结合DOM树和CSSOM树生成的树结构,它专门用于渲染。Render树去除了DOM树中不需要显示的元素,只包含需要渲染的节点。 了解浏览器渲染机制的意义在于,前端开发者可以通过这些知识优化页面的性能。例如: - **减少重排(Reflow)和重绘(Repaint):** 重排和重绘是浏览器渲染过程中的两个关键性能消耗点。重排是当元素的布局改变时发生的,而重绘是当元素的样式改变(不涉及布局变化)时发生的。开发者应当尽量避免这两种操作,特别是在性能敏感的区域。 - **使用CSS3硬件加速:** 在支持硬件加速的浏览器中,合理使用`transform`和`opacity`等CSS3属性,可以将部分绘制工作交给GPU完成,从而加快渲染速度。 - **异步加载资源:** 对于外部资源,比如图片、脚本等,可以使用`async`和`defer`属性来异步加载,减少页面加载时的阻塞。 - **减少DOM操作:** DOM操作的开销很大,尤其是深度遍历DOM树。应当尽量避免不必要的DOM操作,通过优化数据结构和逻辑来减少DOM的交互。 - **优化JavaScript执行:** JavaScript执行会阻塞页面渲染。所以,应当尽量优化JavaScript代码的执行效率,避免执行时间过长的脚本,尤其是将JavaScript放在页面的底部。 通过掌握这些知识点,前端开发者能够更加深入地理解和优化浏览器的渲染过程,最终提升网页的性能和用户体验。
- 粉丝: 2530
- 资源: 337
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助