在展开性能优化的话题之前,我想先抛出一个老生常谈的面试问题:
从输入 URL 到页面加载完成,发生了什么?
这个问题非常重要,因为我们后续的内容都将以这个问题的答案为骨架展开。我希望正在阅读这本小册的各位可以在心里琢磨一下这个问题——无须你调动太多计算机的专业知识,只需要你用最快的速度在脑海中架构起这个抽象的过程——我们接下来所有的工作,就是围绕这个过程来做文章。
我们现在站在性能优化的角度,一起简单地复习一遍这个经典的过程:首先我们需要通过 DNS(域名解析系统)将 URL 解析为对应的 IP 地址,然后与这个 IP 地址确定的那台服务器建立起 TCP 网络连接,随后我们向服务端抛出我们的 HTTP 请求,服务端处理完我们的请求之后,把目标数据放在 HTTP 响应里返回给客户端,拿到响应数据的浏览器就可以开始走一个渲染的流程。渲染完毕,页面便呈现给了用户,并时刻等待响应用户的操作。
我们将这个过程切分为如下的过程片段:
大家谨记,我们任何一个用户端的产品,都需要把这 5 个过程滴水不漏地考虑到自己的性能优化方案内、反复权衡,从而打磨出用户满意的速度。
我们接下来要做的事情,就是针对这五个过程进行分解,各个提问,各个击破。
具体来说,DNS 解析花时间,能不能尽量减少解析次数或者把解析前置?能——浏览器 DNS 缓存和 DNS prefetch。TCP 每次的三次握手都急死人,有没有解决方案?有——长连接、预连接、接入 SPDY 协议。如果说这两个过程的优化往往需要我们和团队的服务端工程师协作完成,前端单方面可以做的努力有限,那么 HTTP 请求呢?——在减少请求次数和减小请求体积方面,我们应该是专家!再者,服务器越远,一次请求就越慢,那部署时就把静态资源放在离我们更近的 CDN 上是不是就能更快一些?
以上提到的都是网络层面的性能优化。再往下走就是浏览器端的性能优化——这部分涉及资源加载优化、服务端渲染、浏览器缓存机制的利用、DOM 树的构建、网页排版和渲染过程、回流与重绘的考量、DOM 操作的合理规避等等——这正是前端工程师可以真正一展拳脚的地方。学习这些知识,不仅可以帮助我们从根本上提升页面性能,更能够大大加深个人对浏览器底层原理、运行机制的理解,一举两得!
总的来说,我们将从网络层面和渲染层面两个大的维度来逐个点亮前端性能优化的技能树。
这两个维度的知识面貌各有千秋:在网络层面,我们需要学习一些必需的理论基础作为前置知识。这部分的学习或许不需要大家写特别多的代码,但需要大家对每一个知识点理解透彻,进而应用到自己日常优化的决策中去。网络层面结束后,由本地存储开始,我们会渐渐过渡到浏览器这一端的优化,大家喜闻乐见的“真代码”就会相应地多起来。
为了使同学们耐心学习一些理论性稍强的知识,我也会尽自己所能去讲述得有趣、易读、可用,同时希望大家可以真的沉下心去理解这些知识,它们与大家喜闻乐见的框架和工具无异,一样是实实在在的生产力。
“经验丰富的人读书用两只眼睛,一只眼睛看到纸面上的话,另一只眼睛看到纸的背面”。在这本小册,代码片段固然有用,它们是“纸面上的话”,我自然希望大家可以记下来、用起来。而代码之外那些反复讲解的原理,则是“纸的背面”,同样是我希望引起大家重视的内容。
现在相信大家已经对我们的优化观念、知识结构、小册格局都有了基本认知,那么我们就赶快趁热打铁,进入实战技能的学习吧~