打开一个网页发生了什么?
输入一个网址,打开一个网页
- DNS 查询
- TCP 连接
- HTTP 请求即响应
- 服务器响应
- 客户端渲染
浏览器对内容的渲染便发生在第五步。
客户端渲染具体过程
- 处理 HTML 标记并构建 DOM 树。
- 处理 CSS 标记并构建 CSSOM 树。
- 将 DOM 与 CSSOM 合并成一个渲染树。
- 根据渲染树来布局,以计算每个节点的几何信息。(Layout)
- 将各个节点绘制到屏幕上。(Paint)
关于布局部分,简单提一句,请注意 visibility: hidden 与 display: none 是不一样的。前者隐藏元素,但元素仍占据着布局空间(即将其渲染成一个空框),而后者 (display: none) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分。
以上过程不会只执行一遍,如果 DOM 或 CSSOM 被修改,只能再执行一遍以上所有步骤,以确定哪些像素需要在屏幕上进行重新渲染。
关键渲染路径即指以上过程。那么,优化关键渲染路径,就是指最大限度缩短执行上述第 1 步至第 5 步耗费的总时间.
当我们谈论关键渲染路径时,通常谈论的是 HTML 标记、CSS 和 JavaScript。图像不会阻止页面的首次渲染,不过,我们当然也应该尽力确保系统尽快绘制图像!
优化关键渲染路径
在渲染树构建中,我们看到关键渲染路径要求我们同时具有 DOM 和 CSSOM 才能构建渲染树。这会给性能造成严重影响:HTML 和 CSS 都是阻塞渲染的资源。 HTML 显然是必需的,则针对CSSOM进行优化。
CSS 是阻塞渲染的资源(阻止呈现)。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。
JavaScript 也会阻止 DOM 构建和延缓网页渲染。 为了实现最佳性能,可以让您的 JavaScript 异步执行,并去除关键渲染路径中任何不必要的 JavaScript。
解析到Script标签
默认情况下,JavaScript 执行会“阻止解析器”(阻止解析)
- JavaScript 可以查询和修改 DOM 与 CSSOM。
- JavaScript 执行会阻止 CSSOM。
- 除非将 JavaScript 显式声明为异步,否则它会阻止构建 DOM。
我们的脚本在文档的何处插入,就在何处执行。当 HTML 解析器遇到一个 script 标记时,它会暂停构建 DOM,将控制权移交给 JavaScript 引擎;等 JavaScript 引擎运行完毕,浏览器会从中断的地方恢复 DOM 构建。
执行我们的内联脚本会阻止 DOM 构建,也就延缓了首次渲染。
因为JavaScript也可以操作css,所以
浏览器将延迟脚本执行和 DOM 构建,直至其完成 CSSOM 的下载和构建。
简言之,JavaScript 在 DOM、CSSOM 和 JavaScript 执行之间引入了大量新的依赖关系,从而可能导致浏览器在处理以及在屏幕上渲染网页时出现大幅延迟:
- 脚本在文档中的位置很重要。
- 当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行。
- JavaScript 可以查询和修改 DOM 与 CSSOM。
- JavaScript 执行将暂停,直至 CSSOM 就绪。
解决JavaScript带来的阻塞
- defer
defer 属性表示延迟执行引入的 JavaScript,即这段 JavaScript 加载时 HTML 并未停止解析,这两个过程是并行的。整个 document 解析完毕且 defer-script 也加载完成之后(这两件事情的顺序无关),会执行所有由 defer-script 加载的 JavaScript 代码,然后触发 DOMContentLoaded 事件。 - async
async 属性表示异步执行引入的 JavaScript,与 defer 的区别在于,如果已经加载好,就会开始执行——无论此刻是 HTML 解析阶段还是 DOMContentLoaded 触发之后。需要注意的是,这种方式加载的 JavaScript 依然会阻塞 load 事件。换句话说,async-script 可能在 DOMContentLoaded 触发之前或之后执行,但一定在 load 触发之前执行。
从上一段也能推出,多个 async-script 的执行顺序是不确定的。值得注意的是,向 document 动态添加 script 标签时,async 属性默认是 true。
总结
- 关键资源的数量。
- 关键路径长度。
- 关键字节的数量(大小)。
注意
现代浏览器拥有预加载器,会提前扫描发现需要下载的文件
详情:https://andydavies.me/blog/2013/10/22/how-the-browser-pre-loader-makes-pages-load-faster/
其他
优化 CSS 发送过程
如果外部 CSS 资源较小,您可将它们直接插入到 HTML 文档中,这称为“内嵌”。以这种方式内嵌较小的 CSS 文件可让浏览器顺畅无阻地呈现网页。 请注意,如果 CSS 文件较大,完全内嵌 CSS 则可能会导致 PageSpeed Insights 通过优先加载可见内容规则向您发出网页首屏部分体积过大的警告。 如果 CSS 文件较大,您便需要确定和内嵌用于呈现首屏内容的 CSS,并暂缓加载其余样式,直到首屏内容显示出来为止。
参考:
https://developers.google.com/web/fundamentals/performance/critical-rendering-path/
最后
最近观看了https://classroom.udacity.com/courses/ud884/lessons/1469569174/concepts/15577986410923
这是一个由谷歌前端工程师主讲的关于页面渲染和优化的一个课程。
收获良多
具体如果优化网站
- 先应用内容特定优化:CSS、JS 和 HTML 压缩源码程序。
- 采用 GZIP 对压缩源码后的输出进行压缩。
- HTTP 缓存