zoukankan      html  css  js  c++  java
  • 浏览器重绘和重排

    本文地址: http://www.cnblogs.com/blackmanba/p/browser-repaint-reflow.html或者http://forkme.info/browser-repaint-reflow/, 转载请注明源地址。

    概述

    重排, 顾名思义就是重新排版的意思; 重绘, 就是浏览器重新绘制。理解重排和重绘的含义十分重要, 因为在评审页面交互效果的时候, 重绘和重排是必须考虑的因素。并不是说交互效果实现了就可以了, 必须同时考虑到这样做会引发什么性能问题。也就是说, 浏览器在进行重绘和重排的时候是要付出高昂的性能代价的。

    浏览器执行流程

    浏览器每次从服务器下载完页面后就会对页面进行渲染(Render), 这里面就包含了重绘以及重排。每种浏览器虽然工作原理略有差别, 但也遵循以下流程: 浏览器引擎会解析HTML文档来构建DOM树。树的每个节点都是标签, 有大小边距等等的属性, 这是因为每个HTML元素都遵循盒子模型(隐藏元素不包括在文档树中, 浏览器不会将其渲染)。渲染树构建完毕后, 浏览器就能够确定每个元素的位置并将元素放到正确的位置上, 再根据树节点的样式属性绘制出页面元素。由于浏览器的流布局的方式, 对渲染树的计算通常只需要遍历一遍即可。但table及其内部元素除外, 可能需要执行多次计算才能确定好在渲染树中的属性, 这个过程通常要耗费3倍以上的时间。这也是我们要避免使用table标签的其中一个原因。

    触发条件

    重绘

    重绘是元素改变外观时所触发的浏览器行为, 不包括修改元素的几何属性。例如改变visibility, outline, background等属性。浏览器会根据新的属性重新绘制, 使元素呈现新的外观。重绘不一定会带来新的布局, 并不一定伴随着重排。

    重排

    1. DOM元素的几何属性变化
      当DOM的几何属性变化时, 渲染树中的相关节点就会失效, 浏览器会重新构建渲染树中失效的节点。而且, 当前元素的重排也许会带来相关元素的重排。例如, 容器节点渲染树改变时, 会触发子节点的重新计算, 也会触发后续兄弟节点的重排, 祖先节点需要重新计算大小, 最后, 每个元素可能都会进行重绘。可见, 重排一定会引起重绘, 并且因为重排的元素很多, 导致重排从性能上来说比重绘更差。一个元素的重排通常都会带来一系列反应, 甚至触发整个文档的重绘和重排, 性能代价是高昂的。

    2. DOM树的结构变化
      当DOM树的结构变化时, 例如节点的增加, 减少, 删除, 也会触发重排。浏览器引擎渲染DOM树类似前序遍历, 也就是说当前元素不会影响前面已经遍历过的元素。所以, 如果在body前面插入一个元素, 就会导致整个文档的重新渲染, 而在其后插入一个元素, 就不会影响到前面元素的布局。

    3. 获取某些属性
      浏览器会对重排进行优化, 可能会等到有足够数量的变化发生, 或者等到一定时间, 或者等一个线程结束, 再一起处理。这样就只会发生一次重排。但如果渲染树直接发生变化, 当获取一些属性时, 浏览器为了取得正确的值也会触发重排。这样就使得浏览器的优化失效。这些属性包括: offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。所以,在多次使用这些值时应进行缓存。

    4. 其他: 比如改变元素的某些样式, 调整浏览器窗口等等也会触发重排。

    最佳实践

    • 避免在document上直接进行频繁的DOM操作, 如果确实需要可以采用off-document方式进行;
    • 集中修改样式
    • 缓存layout属性值
    • 设置position为absolute或者fixed
    • 权衡动画速度和CPU性能
    • 不要使用table布局
    • 不要在css中写expression

    判别方式

    如何判断页面重绘和重排的性能, 在google chrome 上可以使用Timeline面板, 具体使用请查看这篇文章

    参考文章

  • 相关阅读:
    列式存储hbase系统架构学习
    使用Phoenix通过sql语句更新操作hbase数据
    分布式实时日志系统(四) 环境搭建之centos 6.4下hbase 1.0.1 分布式集群搭建
    布式实时日志系统(三) 环境搭建之centos 6.4下hadoop 2.5.2完全分布式集群搭建最全资料
    GDI+绘制五星红旗
    C#模拟登录后请求查询
    ubuntu下安装mysql
    配置nginx实现windows/iis应用负载均衡
    23种设计模式之原型模式(Prototype)
    23种设计模式之访问者模式(Visitor)
  • 原文地址:https://www.cnblogs.com/blackmanba/p/browser-repaint-reflow.html
Copyright © 2011-2022 走看看