了解重排与重绘


Posted in Javascript onMay 29, 2019

前言

浏览器下载完页面中的所有内容:HTML、JavaScript、CSS、图片——之后会解析并生成两个内部数据结构:

  • DOM树:表示页面结构
  • 渲染树:表示DOM节点如何显示

DOM树中的每一个需要显示的节点在渲染树中至少存在一个对应的节点(隐藏的DOM元素在渲染树中没有对应的节点)。渲染树中的节点被称为“帧”或者“盒子”,理解页面元素为一个具有填充(padding)、边距(margin)、边框(border)和位置(position)的盒子。一旦DOM树和渲染树构建完成,浏览器就开始显示(绘制 paint)页面元素

当DOM的改变影响了元素几何属性(例如宽和高)——浏览器就需要重新计算元素的几何特性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排(reflow)。完成重排后,浏览器会重新绘制受到影响的部分到屏幕中,该过程称为重绘(repaint)

重绘和重排操作都是代价昂贵的操作,它们会导致web应用程序的UI反应迟钝,所以应该尽可能减少这类过程的发生。

引起重排的原因

  • 添加或删除可见的DOM元素
  • 元素位置改变
  • 元素尺寸改变
  • 内容改变(例如:文本改变或图片被另一个不同尺寸的图片替代)
  • 页面渲染初始化
  • 浏览器窗口尺寸改变

渲染树变化的排队与刷新

由于每次重排都会产生计算消耗,大多数浏览器通过队列化修改和批量执行来优化重排过程(将多个重排过程合并成一次)。然而,某些操作会强制刷新队列并要求队列中的重排立即执行(这样会使浏览器的优化策略失效)。

  • 获取布局信息的操作会导致强制刷新队列,使得浏览器不得不执行渲染队列中的“待处理变化”并触发重排以返回正确的值
    • offsetTop,offsetLeft,offsetWidth,offsetHeight
    • scrollTop,scrollLeft,scrollWidth,scrollHeight
    • clientTop,clientLeft,clientWidth,clientHeight
    • getComputedStyle()
  • 优化方法:尽量不要在布局信息改变时查询它,可以在布局信息改变完毕之后再去查询

最小化重绘和重排

重绘和重排的代价非常昂贵,因此一个好的提高程序响应速度的策略就是减少此类操作的发生。为了减少发生次数,应该合并多次对DOM和样式的修改,然后一次处理掉。

合并多次对样式的修改

var el = document.getElementById('myDiv')
el.style.borderLeft = '1px'
el.style.borderRight = '2px'
el.style.padding = '5px'

上面的例子中,存在两个问题:

  • 每个样式属性的改变都会影响元素的集合结构,最糟糕的情况下,会导致浏览器触发三次重排(大部分现代浏览器都为此做了优化,只会触发一次重排)
  • 上面的代码访问了4次DOM

优化方法:使用cssText属性,合并所有的改变然后一次处理

var el = document.getElementById('myDiv')
el.style.cssText +='border-left: 1px; border-right: 2px; padding: 5px;';

批量修改DOM

当需要对DOM元素进行一系列操作时,可以通过以下步骤来减少重绘和重排的次数

1.使元素脱离文档流

2.对其进行一些列操作

3.把元素带回文档中

  • 使元素脱离文档流的方法:
    • 隐藏元素,施加修改,重新显示
    • 使用document fragment在当前DOM之外构建一个子树,再把它拷贝会文档
    • 将元素元素拷贝到另一个脱离文档的节点中,修改副本,完成后再替换原始元素。

缓存布局信息

在上面的介绍中讲到了,浏览器通过队列化修改和批量执行的方式减少重排次数。但是当查询布局信息时(如获取偏移量、滚动位置、计算出的样式值),浏览器为了返回最新值,会刷新队列并应用所有的变更。因此最好的做法应该是尽量减少布局信息的获取次数,获取后把它复制给局部变量,然后再操作局部变量。

IE和:hover

避免在大量元素上使用:hover这种效果。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用javascript实现的仿Flash广告图片轮换效果
Apr 24 Javascript
checkbox设置复选框的只读效果不让用户勾选
Aug 12 Javascript
Javascript前端UI框架Kit使用指南之Kitjs简介
Nov 28 Javascript
JS扩展方法实例分析
Apr 15 Javascript
javascript实现点击后变换按钮显示文字的方法
May 13 Javascript
js钢琴按钮波浪式图片排列效果代码分享
Aug 26 Javascript
详解Vue.js组件可复用性的混合(mixin)方式和自定义指令
Sep 06 Javascript
js捆绑TypeScript声明文件的方法教程
Apr 13 Javascript
原生javascript AJAX 三级联动的实现代码
May 04 Javascript
Vue-cli@3.0 插件系统简析
Sep 05 Javascript
小程序根据手机机型设置自定义底部导航距离
Jun 04 Javascript
使用Vue-cli3.0创建的项目 如何发布npm包
Oct 10 Javascript
小程序如何构建骨架屏
May 29 #Javascript
新手简单了解vue
May 29 #Javascript
详细讲解如何创建, 发布自己的 Vue UI 组件库
May 29 #Javascript
基于JS实现一个随机生成验证码功能
May 29 #Javascript
微信小程序mpvue点击按钮获取button值的方法
May 29 #Javascript
深入了解响应式React Native Echarts组件
May 29 #Javascript
node将geojson转shp返回给前端的实现方法
May 29 #Javascript
You might like
PHP 高级课程笔记 面向对象
2009/06/21 PHP
php查找指定目录下指定大小文件的方法
2014/11/28 PHP
PHP开发中AJAX技术的简单应用
2015/12/11 PHP
PHP下载文件的函数实例代码
2016/05/18 PHP
PHP基于接口技术实现简单的多态应用完整实例
2017/04/26 PHP
非主流的textarea自增长实现js代码
2011/12/20 Javascript
你需要知道的10个最佳javascript开发实践小结
2012/04/15 Javascript
javascript实现json页面分页实例代码
2014/02/20 Javascript
javascript实现图片循环渐显播放的方法
2015/02/24 Javascript
jQuery实现淡入淡出二级下拉导航菜单的方法
2015/08/28 Javascript
浅谈JavaScript中面向对象的的深拷贝和浅拷贝
2016/08/01 Javascript
AngularJs定制样式插入到ueditor中的问题小结
2016/08/01 Javascript
用js实现简单算法的实例代码
2016/09/24 Javascript
原生js代码实现图片放大境效果
2016/10/30 Javascript
bootstrap-table实现服务器分页的示例 (spring 后台)
2017/09/01 Javascript
详解使用Typescript开发node.js项目(简单的环境配置)
2017/10/09 Javascript
JS Ajax请求会话过期处理问题解决方法分析
2019/11/16 Javascript
详解小程序横屏方案对比
2020/06/28 Javascript
JavaScript事件委托实现原理及优点进行
2020/08/29 Javascript
[01:10:58]KG vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
在Python的列表中利用remove()方法删除元素的教程
2015/05/21 Python
简单了解Python下用于监视文件系统的pyinotify包
2015/11/13 Python
Python学习小技巧之列表项的推导式与过滤操作
2017/05/20 Python
Django数据库操作的实例(增删改查)
2017/09/04 Python
Python中常用信号signal类型实例
2018/01/25 Python
python自动查询12306余票并发送邮箱提醒脚本
2018/05/21 Python
python tkinter实现界面切换的示例代码
2019/06/14 Python
HTML5 File接口在web页面上使用文件下载
2017/02/27 HTML / CSS
中考冲刺决心书
2014/03/11 职场文书
2014年电话客服工作总结
2014/12/09 职场文书
关于开学的感想
2015/08/10 职场文书
2020年元旦晚会策划书模板
2019/12/30 职场文书
Python数据清洗工具之Numpy的基本操作
2021/04/22 Python
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
2021/06/05 Python
浅谈Python响应式类库RxPy
2021/06/14 Python
一次SQL查询优化原理分析(900W+数据从17s到300ms)
2022/06/10 SQL Server