17、重绘、重排(回流)

  • 先把dom节点生成dom树(解析dom)
  • 生成cssom(解析css)
  • 布局:构成渲染树render tree(从根节点递归,布局)
  • 绘制:绘制div等到页面上

重绘(repaint):一个元素外观的改变所触发的浏览器的行为,浏览器会根据元素的新属性重新绘制,使元素呈现新外观

回流(重排、重构reflow):当渲染树的一部分因为元素的尺寸、布局、隐藏等改变而需要重新构建称之为重排

重绘和重排的关系:在重排的过程中,浏览器会使渲染树中收到影响的部分失效,并且重新去构造这部分渲染树,完成重排之后,浏览器会重新绘制受影响的部分到屏幕中,该部分称为重绘。

重排(回流)一定会重绘,但是重绘不一定会重排。(重排=>布局 重绘=>样式)

触发重排的条件
  • 页面渲染初始化
  • 添加删除可见dom元素
  • 元素位置改变或者使用动画
  • 元素尺寸的改变——大小、外边距、边框
  • 浏览器窗口尺寸的变化(resize事件发生时)
  • 填充内容的改变,比如文本的改变导致的计算值的宽高改变
  • 读取某些元素属性(读取宽高offsetTop/Top/Height/width等)
重绘或者重排的代价:耗时、导致浏览器卡顿
重绘重排优化
  • 浏览器自己的优化:浏览器会维护一个队列,把所有会引起重绘或者重排的操作放入这个队列,等队列中的操作到了一定的哦时间间隔或者一定数量的时候,浏览器就会flush队列进行一个个处理,这样就会让多次回流和重绘便车个一次
  • 我们也可以合并多次对dom的操作以及对样式的修改为一次,并且减少对style的样式请求
    • 直接改变元素的className
    • 先设置元素的display:none然后进行页面布局等操作,设置完成之后再将display:block这样的话就之后出现两次重绘和重排
    • 使用cloneNode(ture or false)和replace技术只引发一次重绘和重排
    • 将需要毒刺重排的元素的position设置成absolte或者fixed,使其脱离文档流,那么它的变化不会影响到其他元素
    • 如果要插入多个dom节点可以创建一个documentFragment创建完成之后一次性加入document
var fragment = document.createDocumentFragment()
for(let i = 0;i<=1000;i++){
  var li = document.createElement('i')
  li.innerHTML = i + '</br>'
  fragment.append(li)
}
document.getElementById('container').appendChild(fragment)

results matching ""

    No results matching ""