blog icon indicating copy to clipboard operation
blog copied to clipboard

浏览器系列 - 页面渲染过程简析

Open HXWfromDJTU opened this issue 4 years ago • 0 comments

前言

为了项目的更好优化,为了提高浏览器的解析速率,减少页面无用的重绘,重置。

本文请结合其他笔记一起食用... [1] 前端性能优化 - 第一曲 总览
[2] 从渲染Timeline中深入交互优化

一个请求的生命周期:

  1. 用户输入网址(URL),浏览器查找DNS服务器,寻找对应的ip地址
    (DNS查询过程博文,传送门👉)

  2. 浏览器根据ip地址,向服务器发送获取资源的请求

  3. 服务器端返回一个HTML响应

  4. 浏览器收到返回的内容,浏览器开始解析HTML内容

浏览器的解析

  1. 将下载来的HTML字符串转化成浏览器能够识别的DOM Tree
  2. 根据 CSS内容内容生成CSSOM Tree (或者称之CSS Rule)
  3. CSSOM TreeDOM Tree合起来生成 Render Tree准备对页面进行排布和绘制。
  4. 先进行页面的布局(排布) (layout)
  5. 布局完之后就会开始进行着色渲染,我们称之为“绘制” (paint)
  6. 复合图层化(Composite) 基于第三点的RenderTree,我们又延伸出了Render Layer的概念,一个Render Layer上有N个Render Object
chrome的 『Show composited layer borders』模式

最后,浏览器调用GPU进行渲染。
想了解更多内容的,请去访问我的另一篇博文《Render Layer与GUP加速》👉

小结

  • 所以我们通常会把script标签插入到DOM的底部
  • 因为js中可能有DOM操作,而此时DOM的加载可能没有完成,操作就会失败。
  • JS中若有DOM操作,改变页面的样式,那么DOM就有可能多次变动,造成页面不稳定。

其他情况说明

  1. 浏览器解析CSS过程不阻塞;

  2. 浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码。

服务器返回图片文件,由于图片占用了一定面积(宽度高度),影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;

rendingprocess
rendingtree

重绘与重排

Reflow
浏览器发现某个部分的变化,影响了布局,就需要重新回去渲染。

Repaint
浏览器发现,某些变化只是改变了背景颜色,文字颜色,不影响元素周围或者内容的属性,浏览器将只会进行repaint。

Reflow 相比 Repaint更加浪费时间,也就更加影响性能。需要尽量避免。

加载原则

  1. 外链css的异步加载不会阻塞HTML的解析,但会阻塞页面的渲染因为要等合成Render Tree

  2. 外链的script标签会阻塞HTML的加载,加载完后也会立即执行。内嵌的script标签的JS代码也会遇到就立即执行

  3. 执行的script内容中,有队DOM进行的操作,其中的操作有可能引起浏览器的重绘或者重新渲染

  4. 用户若有异步的JS操作,也同样会引起浏览器的重绘或者重新渲染。(例如用户点击按钮,某个部分隐藏)

  5. 无论外链,还是内嵌。JS代码中的运行若出错,HTML会停止解析。(包括页面的渲染、其它资源的下载)

简单优化建议

  1. 将所有script内容放置到body标签的末尾去,最大程度避免页面加载的阻塞,也避免操作到未加载的DOM内容
  2. 尽可能地减少 script 外链的数目,减少网络请求次数(对此,可以使用gulpwebpack等打包工具整合JS实现)
  3. 使用现代浏览器的异步非阻塞加载
    • defer属性
    • 使用JS代码动态插入script外链标签

参考文章

[1] 从URL输入到到加载完成的过程 - FEX baidu
[2] 浏览器工作原理
[3] css3硬件加速

HXWfromDJTU avatar Nov 08 '20 16:11 HXWfromDJTU