浏览器渲染原理及过程

浏览器渲染过程如下:

  1. 解析HTML,生成DOM树,解析CSS,生成CSSOM树
  2. 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
  3. Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
  4. Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  5. Display:将像素发送给GPU,展示在页面上。(这一步其实还有很多内容,比如会在GPU将多个合成层合并为同一个层,并展示在页面中。而css3硬件加速的原理则是新建合成层)

解析DOM树和CSSOM树

HTML标记进行Dom树解析

浏览器接收到html代码,可能是一份完整的文档,也可能是一个chunk,即开始解析。解析过程是先构建dom树,再根据dom树构建渲染树,最后浏览器将渲染树绘制到页面上。
构建dom树的过程即根据html代码自上而下进行构建,当遇到script文件加载/执行会阻塞后面dom树的构建(javascript可能会改变dom树),而遇到css文件则会阻塞Render Tree的构建,即dom树依然继续构建(除非遇到script标签并且css文件依旧未加载完成),但不会渲染绘制到页面上。而无论哪个阻塞,该加载的文件还是会加载,例如html文档中的其他css/js/图片文件。
另外javascript被加载后就会被执行,执行的过程也阻塞DOM树的构建。是执行完了才解析其他内容,而不是执行完了才加载其他内容。

img的加载不会阻塞html的解析,但img加载后并不渲染,它需要等待Render Tree

生成完后才和Render Tree一起渲染出来。未下载完的图片需等下载完后才渲染。

CSS标记进行CSSOM树解析

注意

render tree不是等到CSSOM树和DOM树构建完成才构建的,边解析CSS和DOM就会渲染了。

JS异步脚本

CSS和JS阻塞问题总结

总结:

  • CSS
    • css加载不会阻塞DOM树的解析,但会阻塞Render Tree的构建 (即DOM树的渲染)
    • css加载和解析会阻塞后面js语句的执行
  • JS
    • JS的加载和执行都会阻塞页面的渲染
    • JS不阻塞资源的加载(这有赖于chrome的预加载机制)
    • JS顺序执行,阻塞后续JS逻辑的执行

提高css加载速度:

  • 使用CDN(因为CDN会根据你的网络状况,替你挑选最近的一个具有缓存内容的节点为你提供资源,因此可以减少加载时间)
  • 对css进行压缩(可以用很多打包工具,比如webpack,gulp等,也可以通过开启gzip压缩)
  • 合理的使用缓存(设置cache-control,expires,以及E-tag都是不错的,不过要注意一个问题,就是文件更新后,你要避免缓存而带来的影响。其中一个解决防范是在文件名字后面加一个版本号)
  • 减少http请求数,将多个css文件合并,或者是干脆直接写成内联样式(内联样式的一个缺点就是不能缓存)
-------------要说再见啦感谢大佬的光临~-------------