漫谈网站优化提速
前几天的一个晚上,在和一个偶然认识的小白,聊了半个晚上的网站加速的事情,总觉自己最后没有讲清楚,固有此文产生。
本篇文章只涉及前端优化,暂不涉及后端操作,默认后端能抗住所有访问,算力无限大,响应时间无限小。因为加上后端的话,这个命题不是短短的几篇文章搞的定的,大多数都要依据具体的业务来确定。
本文涉及到的浏览器为Chrome浏览器,不具有统一性,仅供参考使用。
用户和网站的交互是通过浏览器来完成的,要谈前端优化,那么,我们就要搞清楚,从用户输入了一串url以后,浏览器到底做了什么。
1. 浏览器如何打开一个网页
这里我们先不考虑路由寻址的事情,后面我们再细细道来,在Chrome浏览器中先打开F12,打开network,可以看到一个网站从输入url到页面显示,具体发送了多少请求。我们以百度为示例,看一下:
首先第一行,可以看到浏览器请求了百度这个页面的主题文件HTML,当浏览器收到这个HTML之后,浏览器和这个页面的缘分,就此开始。
1.1 浏览器渲染流程
用户请求的HTML文本(text/html)通过浏览器的网络层到达渲染引擎后,渲染工作开始。每次通常渲染不会超过8K的数据块,其中基础的渲染流程图:
webkit引擎渲染的详细流程,其他引擎渲染流程稍有不同:
渲染流程有四个主要步骤:
解析HTML生成DOM树 - 渲染引擎首先解析HTML文档,生成DOM树
构建Render树 - 接下来不管是内联式,外联式还是嵌入式引入的CSS样式会被解析生成CSSOM树,根据DOM树与CSSOM树生成另外一棵用于渲染的树-渲染树(Render tree),
布局Render树 - 然后对渲染树的每个节点进行布局处理,确定其在屏幕上的显示位置
绘制Render树 - 最后遍历渲染树并用UI后端层将每一个节点绘制出来
以上步骤是一个渐进的过程,为了提高用户体验,渲染引擎试图尽可能快的把结果显示给最终用户。它不会等到所有HTML都被解析完才创建并布局渲染树。它会在从网络层获取文档内容的同时把已经接收到的局部内容先展示出来。
1.2 渲染细节
浏览器渲染一个页面的过程叫做“关键渲染路径(Critical Rendering Path 简称CRP)”,下面我们来聊一下什么是CRP,这对我们进行代码级的优化有很大的指导意义。
- CRP的相关知识对于如何提升网站性能是相当有用的,共有6个步骤:
- 构建DOM树
- 构建CSSOM树
- 运行JavaScript
- 创建渲染树
- 生成布局
- 绘制页面
如下图:
下面详细聊一下什么是CRP,不感兴趣的童鞋可以直接跳过这一段看结论。
1.1.1 构建DOM树
DOM(Document Object Model)树是一个表示整个解析过的HTML页面的对象,从根节点开始,会创建页面中的每个元素/文本节点。
举个栗子:
Understanding the Critical Rendering Path
Understanding the Critical Rendering Path
Introduction
Lorem ipsum dolor sit amet
上面的 HTML 将会被解析成下面的DOM树:
HTML的优点在于它不必等待整个页面加载完成才呈现页面,可以解析一部分,显示一部分。
- 但是像CSS、JavaScript等其他资源会阻止页面渲染。
1.1.2 构建CSSOM树
CSSOM(CSS Object Model) 是一个跟DOM相关的样式对象。它跟DOM的表示方法是相似的,但是不论显式声明还是隐式继承,每个节点都存在关联样式。
在上面提到的html页面的style.css中的样式如下
body { font-size: 18px; }
header { color: plum; }
h1 { font-size: 28px; }
main { color: firebrick; }
h2 { font-size: 20px; }
footer { display: none; }
它会被构建成下面的CSSOM树
CSS 被认为是 “渲染阻塞资源”,它意味着如果不首先完全解析资源,渲染树是无法构建的。CSS由于它的层叠继承的性质,不能像HTML一样解析一部分,显示一部分。定义在文档后面的样式会覆盖或改写之前定义的样式,因为在整个样式表都被解析之前,如果我们使用了在样式表中较早定义的样式,那错误的样式将被应用。这意味着CSS必须被全部解析之后,才能开始下一步。
1.1.3 运行JavaScript
JavaScript被认为是解析阻塞资源,这意味着HTML的解析会被JavaScript阻塞。
当解析器解析到