浏览器的渲染流程--重排、重绘、合成

HTMLCSSJavaScript 数据,经过浏览器中间渲染模块的处理,再加上重排重绘合成的一个个环节,才最终输出为屏幕上的像素视图画面。本文就逐一介绍重排重绘合成的基本概念、触发时机、影响范围以及其优化策略。

重排、重绘、合成

一、浏览器渲染原理

一个完整的渲染流程一般都经历如下过程:

  1. HTML被HTML解析器解析成DOM Tree
  2. CSS则被CSS解析器解析成CSSOM Tree
  3. DOM TreeCSSOM Tree解析完成后,被附加到一起,形成渲染树(Render Tree
  4. 布局,根据渲染树计算每个节点的几何信息生成布局树Layout Tree
  5. 对布局树进行分层,并生成分层树Layer Tree
  6. 为每个图层生成绘制列表
  7. 渲染绘制(Paint)。根据计算好的绘制列表信息绘制整个页面,并将其提交到合成线程
  8. 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图,发送绘制图块命令 DrawQuad 给浏览器进程
  9. 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上

二、重排

定义: 当通过JS或css改变了元素的宽度、高度等,修改了元素的几何位置属性,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排。无疑, 重排需要更新完整的渲染流水线,所以开销也是最大的。

触发时机和影响范围: DOM节点信息更改,触发重排时,这个DOM更改程度会决定周边DOM更改范围。

全局范围: 就是从根节点html开始对整个渲染树进行重新布局,例如当我们改变了窗口尺寸或方向或者是修改了根元素的尺寸或者字体大小等。

局部范围: 对渲染树的某部分或某一个渲染对象进行重新布局。

三、重绘

定义: 如果修改了元素的背景颜色,并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。

触发时机和影响范围: 每一次的dom更改或者css几何属性更改,都会引起一次浏览器的重排/重绘过程,而如果是css的非几何属性更改,则只会引起重绘过程。

四、合成

定义: 合成是一种将页面的各个部分分离成层(Layer Tree),分别将它们栅格化,然后在称为“合成线程”的中组合为页面的技术。

触发时机和影响范围: 在GUI渲染线程后执行,将GUI渲染线程生成的绘制列表转换为位图,然后发送绘制图块命令 DrawQuad 给浏览器进程,浏览器进程根据 DrawQuad 消息生成页面,将页面显示到显示器上

优点: 我们使用了 CSS 的 transform 来实现动画效果,避开了重排重绘阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。

五、常见的触发重排、重绘的属性和方法

1.引发重排的操作:

  • 页面首次渲染。
  • 浏览器窗口大小发生改变——resize事件发生时。
  • 元素尺寸或位置发生改变——定位、边距、填充、边框、宽度和高度。
  • 元素内容变化(文字数量或图片大小等等)。
  • 元素字体大小变化。
  • 添加或者删除可见的DOM元素。
  • 激活CSS伪类(例如::hover)。
  • 设置style属性
  • 查询某些属性或调用某些方法。

2.引起重排属性和方法:

width、 display、 clientWidth、 offsetWidth、 scrollWidth、 scrollIntoView()、 
getBoundingClientRect()、 height、 border、 clientHeight、 offsetHeight、 
scrollHeight、 scrollTo()、 scrollIntoViewIfNeeded()、 margin、 position、 
clientTop、 offsetTop、 scrollTop、 getComputedStyle()、 padding、 overflow、 
clientLeft、 offsetLeft、 scrollLeft

3.引起重绘的属性:

color、 text-decoration、 outline-color、 outline-width、 
border-style、 background-image、 outline、 box-shadow、 
visibility、 background-position、 outline-style、 
background-size、 background、 background-repeat、 border-radius

六、优化策略

1.减少DOM操作

  • 最小化DOM访问次数,尽量缓存访问DOM的样式信息,避免过度触发重排。
  • 如果在一个局部方法中需要多次访问同一个dom,可以在第一次获取元素时用变量保存下来,减少遍历时间。
  • 用事件委托来减少事件处理器的数量。
  • 用querySelectorAll()替代getElementByXX()。
  • querySelectorAll():获取静态集合,通过函数获取元素之后,元素之后的改变并不会影响之前获取后存储到的变量。也就是获取到元素之后就和html中的这个元素没有关系了
  • getElementByXX():获取动态集合,通过函数获取元素之后,元素之后的改变还是会动态添加到已经获取的这个元素中。换句话说,通过这个方法获取到元素存储到变量的时候,以后每一次在Javascript函数中使用这个变量的时候都会再去访问一下这个变量对应的html元素。

2.减少重排

  • 放弃传统操作DOM的时代,基于vue/react开始数据影响视图模式。
  • 避免设置大量的style内联属性,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性。
  • 不要使用table布局,因为table中某个元素一旦触发了reflow,那么整个table的元素都会触发reflow。那么在不得已使用table的场合,可以设置table-layout:auto;或者是table-layout:fixed这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
  • 尽量少使用display:none可以使用visibility:hidden代替,display:none会造成重排,visibility:hidden只会造成重绘。
  • 使用resize事件时,做防抖和节流处理。
  • 分离读写操作(现代的浏览器都有渲染队列的机制)
  • 分离读写减少重排的原理
<style>
  #box{
    width:100px;
    height:100px;
    border:10px solid #ddd;
  }
</style>
<body>
  <div id="box"></div>
  <script>
    // 读写分离,一次重排
    let box = document.getElementById('box')
    box.style.width='200px';//(写)js改变样式,加入渲染队列中,顿一下,查看下一行是否还是修改样式,如果是则再加入到渲染队列,一直到下一行代码不是修改样式为止
    box.style.height='200px';//(写)
    box.style.margin='10px';//(写)
    console.log(box.clientWidth);//(读)
  </script>
  <script>
    // 没做到读写分离,两次重排
    box.style.width='200px';//(写)js改变样式,加入渲染队列中,顿一下,下一行不是修改样式的代码,浏览器就会直接渲染一次(重排)
    console.log(box.clientWidth);//(读)
    box.style.height='200px';//(写)
    box.style.margin='10px';//(写)
  </script>
</body>
  • 缓存布局信息
<script>
    // 两次重排 ’写‘操作中包含clientWidth属性,会刷新渲染队列
    box.style.width = box.clientWidth +10 + 'px'
    box.style.height= box.clientHeight +10 + 'px'
</script>
<script>
    let a=box.clientWidth //(读)缓存布局信息
    let b=box.clientHeight//(读)缓存布局信息
    // 一次重排 
    box.style.width = a+10 + 'px' // (写)
    box.style.height=  b+10 + 'px' // (写)
</script>

3.css及优化动画

  • 少用css表达式
  • 样式集中改变(批量处理) 减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画;
  • 可以把动画效果应用到position属性为absolute或fixed的元素上,这样对其他元素影响较小
  • 动画实现的速度的选择:牺牲平滑度换取速度。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
  • 开启css3动画硬件加速(GPU加速)把渲染计算交给GPU。(能用transform做的就不要用其他的,因为transform可以开启硬件加速,而硬件加速可以规避重排。直接跳过重排、重绘,走合成进程)
// 向右移动100px,一次重排
box.style.left='100px'
// 向右移动200px,不会引发重排
box.style.ctransform='translateX(200)' 

七、总结

重排一定会引起重绘,而重绘不一定会引起重排重绘的开销较小,重排的代价较高。在日常开发过程中应该尽量减少重排重绘操作。


欢迎访问:天問博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,825评论 6 546
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,814评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,980评论 0 384
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 64,064评论 1 319
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,779评论 6 414
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,109评论 1 330
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,099评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,287评论 0 291
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,799评论 1 338
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,515评论 3 361
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,750评论 1 375
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,221评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,933评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,327评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,667评论 1 296
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,492评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,703评论 2 380

推荐阅读更多精彩内容