02. 浏览器渲染流程 - 2023-02-12

前置

  • 浏览器输入url,浏览器主进程接管,开一个下载线程,
    然后进行 http请求(略去DNS查询,IP寻址等等操作),然后等待响应,获取内容,
    随后将内容通过RendererHost接口转交给Renderer进程

  • 浏览器渲染流程开始

浏览器内核渲染流程

  1. 解析html建立dom树
  2. 解析css构建render树将CSS代码解析成树形的数据结构,然后结合DOM合并成render树
  3. 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
  4. 绘制render树(paint),绘制页面像素信息
  5. 浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上。

所有详细步骤都已经略去,渲染完毕后就是load事件了,之后就是自己的JS逻辑处理了


image.png

load事件与DOMContentLoaded事件的先后

  • 当 DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片。
    (譬如如果有async加载的脚本就不一定完成)
  • 当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片都已经加载完成了。
    (渲染完毕了)

所以,顺序是:DOMContentLoaded -> load

css加载是否会阻塞dom树渲染
css是由单独的下载线程异步下载的

  • css加载不会阻塞DOM树解析(异步加载时DOM照常构建)
  • 但会阻塞render树渲染(渲染时需等css加载完毕,因为render树需要css信息)

因为你加载css的时候,可能会修改下面DOM节点的样式,
如果css加载不阻塞render树渲染的话,那么当css加载完之后,
render树可能又得重新重绘或者回流了,这就造成了一些没有必要的损耗。
所以干脆就先把DOM树的结构先解析完,把可以做的工作做完,然后等你css加载完之后,
在根据最终的样式来渲染render树,这种做法性能方面确实会比较好一点。

普通图层和复合图层

渲染步骤中就提到了composite概念。

可以简单的这样理解,浏览器渲染的图层一般包含两大类:普通图层以及复合图层

首先,普通文档流内可以理解为一个复合图层(这里称为默认复合层,里面不管添加多少元素,其实都是在同一个复合图层中)

其次,absolute布局(fixed也一样),虽然可以脱离普通文档流,但它仍然属于默认复合层

然后,可以通过硬件加速的方式,声明一个新的复合图层,它会单独分配资源
(当然也会脱离普通文档流,这样一来,不管这个复合图层中怎么变化,也不会影响默认复合层里的回流重绘)

可以简单理解下:GPU中,各个复合图层是单独绘制的,所以互不影响,这也是为什么某些场景硬件加速效果一级棒

可以Chrome源码调试 -> More Tools -> Rendering -> Layer borders中看到,黄色的就是复合图层信息

如何变成复合图层(硬件加速)
将该元素变成一个复合图层,就是传说中的硬件加速技术

  • 最常用的方式:translate3d、translateZ
  • opacity属性/过渡动画(需要动画执行的过程中才会创建合成层,动画没有开始或结束后元素还会回到之前的状态)
  • will-chang属性(这个比较偏僻),一般配合opacity与translate使用(而且经测试,除了上述可以引发硬件加速的属性外,其它属性并不会变成复合层)

作用是提前告诉浏览器要变化,这样浏览器会开始做一些优化工作(这个最好用完后就释放)

  • <video><iframe><canvas><webgl>等元素
  • 其它,譬如以前的flash插件

absolute和硬件加速的区别
可以看到,absolute虽然可以脱离普通文档流,但是无法脱离默认复合层。
所以,就算absolute中信息改变时不会改变普通文档流中render树,
但是,浏览器最终绘制时,是整个复合层绘制的,所以absolute中信息的改变,仍然会影响整个复合层的绘制。
(浏览器会重绘它,如果复合层中内容多,absolute带来的绘制信息变化过大,资源消耗是非常严重的)

而硬件加速直接就是在另一个复合层了(另起炉灶),所以它的信息改变不会影响默认复合层
(当然了,内部肯定会影响属于自己的复合层),仅仅是引发最后的合成(输出视图)

硬件加速时请使用index
使用硬件加速时,尽可能的使用index,防止浏览器默认给后续的元素创建复合层渲染

具体的原理时这样的:
webkit CSS3中,如果这个元素添加了硬件加速,并且index层级比较低,
那么在这个元素的后面其它元素(层级比这个元素高的,或者相同的,并且releative或absolute属性相同的),
会默认变为复合层渲染,如果处理不当会极大的影响性能

简单点理解,其实可以认为是一个隐式合成的概念:如果a是一个复合图层,而且b在a上面,那么b也会被隐式转为一个复合图层,这点需要特别注意

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一、进程与线程 进程 是cpu资源分配的最小单位(是能拥有资源和独立运行的最小单位)线程 是cpu调度的最小单位(...
    昫嵐阅读 449评论 0 1
  • 浏览器内核拿到内容后,渲染步骤大致可以分为以下几步: 解析HTML,构建DOM树 解析CSS,生成CSS规则树 合...
    amCow阅读 890评论 0 1
  • 前言 移动互联网时代,用户对于网页的打开速度要求越来越高。百度用户体验部研究表明,页面放弃率和页面的打开时间关系如...
    AI乔治阅读 820评论 0 3
  • 对于前端的新手来说,都知道js是单线程的,但对线程、进程等知识傻傻分不清,特别是对js单线程理解不够明白,今天我们...
    Erric_Zhang阅读 1,595评论 1 6
  • 浏览器组成 主要包括用户界面、浏览器引擎、渲染引擎、网络、Js解释器、UI后端、数据存储。 渲染流程 解析HTML...
    八菜冰阅读 338评论 0 0

友情链接更多精彩内容