You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
当render tree 中的一部分或全部因为元素的尺寸,布局,隐藏等改变而需要重新构建,这个就是reflow。在reflow的时候,浏览器会使render tree中受到影响的部分失效,并重新构造这部分render tree。当完成reflow时,浏览器会重新绘制受影响的部分到屏幕中,该过程成为repaint。
当render tree 中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不影响布局的,比如background-color,这个就叫repaint
好久没有看这个问题,对这个知识点都忘的差不多了,现在想重新整理一下。
页面解析的过程大致可以分为以下几个步骤:
两者的区别
render tree 和 dom tree的区别是: render tree中的每个node是有自己的样式的,而且render tree不包 含隐藏的节点(display:none 和 head节点),因为这些节点不会呈现出来,所以不包含到render tree中。 visibility:hidden 隐藏的元素会包含到render tree中,因为他是占布局的,影响布局。
reflow和repaint分别出现在第三步和第四步。
对于DOM结构中的每个元素都有自己的盒子模型,这些都需要浏览器根据各种样式来计算并将元素放到它该出现的位置,这个叫reflow;
当各种盒子的位置,大小以及其他属性,如颜色,字体大小都确定下来以后,浏览器会把这些元素绘制一遍,所以页面上出现了内容,这个叫做repaint.
在过程中,怎么会出现这些情况呢:
怎么引起reflow/repaint
reflow的成本比repaint高很多。DOM tree中的每个节点都会有reflow方法,一个节点的reflow很可能会导致子节点,甚至父节点以及同级节点的reflow。
能引起reflow的方式:
引起repaint的操作: 一个元素的外观改变,但是没有改变布局的情况
对自己的opacity做CSS动画 是引起了一个新的图层
单纯修改opacity的值会引起 reflow 和 repaint的
translate不会引发 reflow
怎样减少reflow的影响
不要一条一条修改DOM样式。可以一次性操作
让需要操作的元素离线处理,处理完后再更新
不要把 DOM 节点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性
尽可能的修改层级比较低的 DOM节点。当然,改变层级比较底的 DOM节点有可能会造成大面积的 reflow,但是也可能影响范围很小.(因为改变 DOM 树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点。这导致大量时间耗费在执行 reflow 上面 )(减少不必要的 DOM 层级(DOM depth)。改变 DOM 树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点。这导致大量时间耗费在执行 reflow 上面。)
将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素为动画的 HTML 元素,例如动画,那么修改他们的 CSS 是会大大减小 reflow 。因为,它们不影响其他元素的布局,所它他们只会导致重新绘制,而不是一个完整回流。这样消耗会更低。
不要用tables布局的一个原因就是tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
避免使用CSS的JavaScript表达式,如果css里有expression,每次都会重新计算一遍。
不要经常去访问计算后的样式,如果可以,可以先将这些信息缓存下来 .
请求如下值offsetTop, offsetLeft, offsetWidth, offsetHeight,scrollTop/Left/Width/Height,clientTop/Left/Width/Height,浏览器会发生reflow,建议将他们合并到一起操作,可以减少回流的次数.
避免不必要的复杂的 CSS 选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的 CPU。
css里不要有表达式expression
权衡速度的平滑。比如实现一个动画,以1个像素为单位移动这样最平滑,但reflow就会过于频繁,CPU很快就会被完全占用。如果以3个像素为单位移动就会好很多。
实现元素的动画,对于经常要进行回流的组件,要抽离出来,它的position属性应当设为fixed或absolute
补充说明:
正常的渲染大概可以分为下面几个流程:
参考文章:
reflow(回流)和repaint(重绘)及其优化
reflow 和 repaint
前端性能优化 —— reflow(回流)和repaint(重绘)
reflow和repaint引发的性能问题
The text was updated successfully, but these errors were encountered: