[前端] 重排和重绘

这篇具有很好参考价值的文章主要介绍了[前端] 重排和重绘。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

网页的生成过程

  1. 解析HTML,生成DOM树。
  2. 解析CSS,生成CSSOM树。
  3. 结合DOM树和CSSOM树,为每一个节点计算CSS属性,生成渲染树,RenderTree。
  4. 生成布局(Flow),计算渲染树上所有节点的位置。
  5. 将布局绘制(Paint)到屏幕上。
  • 布局生成和绘制的过程就是渲染。
  • 网页生成的时候至少渲染一次。
  • 用户交互可能导致重新渲染。
  • 渲染是耗时的,应减少不必要的重新渲染以提高网页性能。

重排和重绘的概念

  • 重新生成布局,就叫重排(Reflow),也叫回流。
  • 重新绘制,就是重绘(Repaint)。

由于布局生成和绘制存在先后顺序关系,重排必定导致重绘,但重绘不一定需要重排。

重排 Reflow

重排与布局有关,当布局发生变化时,也就是元素的几何信息(DOM节点的尺寸和位置)发生变化时,将会触发重排,重新计算元素的几何位置,然后重新绘制。

常见引起重排的属性和方法

  • 添加或删除可见的DOM元素;
  • 元素尺寸改变——边距、填充、边框、宽度高度;
  • 内容变化,比如input框中输入文字;
  • 浏览器窗口尺寸改变——resize事件发生时;
  • 读取offsetWidth、offsetHeight等属性(浏览器为确保数据准确性,会先强制重排);
  • 设置style属性的值(改变了元素的尺寸或位置);

重排影响范围

  • 全局范围重排:从根节点html开始对整个渲染树进行重排;

    当一个DOM节点变小,它后续的元素可能位置也发生变化,而它的父元素如果没有固定宽高也可能发生收缩,因此:

    一个节点的重排可能影响到它的相邻节点、父节点......从而引发全局范围的重排。

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

    将一个DOM的几何信息固定,当其内部的节点发生重排,则不会影响到外部的节点,是局部范围的重排。

重排总结

  • 重排的性能开销渲染树上需要重新构建的节点数有关。
  • 尽量以局部布局的形式组织html,将重排控制在局部范围内。

重绘 Repaint

一个元素的外观发生改变,但不改变布局,不影响周围的元素,只是重新绘制该元素的外观,这个过程叫做重绘。

常见引起重绘的属性和方法

  • color
  • border-style
  • background
  • visibility
  • border-radius
  • box-shadow
  • outline
  • text-decoration

渲染队列机制

当元素的几何属性被修改,不会立刻导致重排。这个操作会被放到渲染队列,等到队列中的操作到达一定数量或者达到一定的时间间隔,浏览器才会批量执行这些操作。

如下的代码执行了四次对于元素的几何属性的修改,但是只会触发一次重排。

div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';

强制刷新队列

当访问与布局相关的属性时,浏览器为确保其准确性、准时性,会强制立即执行渲染队列中的任务,即立即重排和重绘。

如下这段代码会触发4次重排和重绘:

div.style.left = '10px';
console.log(div.offsetLeft);
div.style.top = '10px';
console.log(div.offsetTop);
div.style.width = '20px';
console.log(div.offsetWidth);
div.style.height = '20px';
console.log(div.offsetHeight);

强制刷新队列的属性和方法

  • offsetTop, offsetLeft, offsetWidth, offsetHeight
  • scrollTop, scrollLeft, scrollWidth, scrollHeight
  • clientTop, clientLeft, clientWidth, clientHeight
  • getComputedStyle(), 或者 IE的 currentStyle

在开发过程中应该尽可能少地访问这些属性,避免多次重排。

重排优化策略

1. 分离读写操作

div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
console.log(div.offsetLeft);
console.log(div.offsetTop);
console.log(div.offsetWidth);
console.log(div.offsetHeight);

统一读,再统一写,而不是边读边写。这样可以将重排次数降低到1次。第一个console.log将渲染队列清空,触发一次重排,而后续的console.log由于渲染队列本身是空的因此不会触发重排。

2. 样式集中改变

不要分批次的修改样式属性,而是一次性修改。

建议提前写好若干个CSS的class选择器,然后 JS 负责切换。

// bad
box.style.left = '10px';
box.style.top = '200px';
box.style.transform = 'scale(1.1)';

// good
box.classList.add('className1');
box.classList.remove('className2');

3. 缓存布局信息

布局信息的每一次读取都会导致强制重排,如果确保布局信息在当前情景下不会有变动,可以使用一个临时变量缓存使用。

// bad 强制刷新 触发两次重排
div.style.left = div.offsetLeft + 1 + 'px';
div.style.top = div.offsetTop + 1 + 'px';

// good 
var curLeft = div.offsetLeft;
var curTop = div.offsetTop;
div.style.left = curLeft + 1 + 'px';
div.style.top = curTop + 1 + 'px';

4. 离线修改DOM

DOM设置display: none;,将其从渲染树中移除,然后再进行复杂修改操作,最后再将其显示出来。

整个过程包含隐藏和显示共两次重排。

或者使用DocumentFragment创建一个DOM碎片,然后在其上面批量操作DOM,操作完成之后再添加到文档中,这样只会触发一次重排。

5. 目标元素设置绝对定位

设置positionabsolutefixed,这样就只会影响子节点的重排,不会影响外部。

6. 不要使用table布局

table中的某一个元素触发重排将导致整个table重排。

如果是在维护远古项目不得不使用table布局,可以设置table-layout: fixed;或者table-layout: auto;,这样可以让table一行一行的渲染,限制重排的影响范围。文章来源地址https://www.toymoban.com/news/detail-798120.html

到了这里,关于[前端] 重排和重绘的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端进阶版本 ,性能优化—-防抖、节流、重绘与回流

    目录 【防抖】 【节流】 重绘(repaint) 回流(reflow):又叫重排(layout) 工作中要如何避免大量使用重绘与回流? 常见的会导致回流的元素 【防抖】 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。 【节流】 指定时间间隔内只会执行一次任务。

    2024年02月14日
    浏览(30)
  • 记录--记录用前端代替后端生成zip的过程,速度快了 57 倍!!!

    业务场景: 产品有个功能是设置主题。类似手机自动切换壁纸,以及其他功能颜色,icon,字体等。 管理员需要在后端管理系统多次下载不同主题,(至于要干啥就不说了...),主题中可能有 30 ~ 100个高清壁纸, icon 等。现在每次下载主题(31张高清图片)至少需要 10s。有什么

    2024年02月08日
    浏览(32)
  • 前端二维码生成工具小程序:构建营销神器的技术解析

    摘要: 随着数字化营销的不断深入,二维码作为一种快速、便捷的信息传递方式,已经广泛应用于各个领域。本文旨在探讨如何通过前端技术构建一个功能丰富、操作简便的二维码生成工具小程序,为企业和个人提供高效的营销支持。 一、引言 二维码作为一种特殊的编码方

    2024年04月14日
    浏览(32)
  • 前端 解析压缩包,并且读取Shp生成GeoJson在MapBox上渲染

    这里需要先安装shapefile;jszip;turf npm install shapefile npm install jszip npm install @turf/turf

    2024年01月17日
    浏览(30)
  • 【Midjourney】Midjourney 基本操作 ② ( 导出图片 | 设置图片宽高比 | 生成后的图片处理 - 生成变体 / 放大细化图片 / 更换算法重绘 / 浏览器显示 )

    生成图片后 , 可以右键点击图片 , 在弹出的右键菜单中 , 选择 \\\" 保存图片 \\\" , 即可将生成的图片保存到本地 ; 选择保存图片会弹出 \\\" 另存为 \\\" 对话框 , 选择一个路径保存即可 ; 也可以在点开大图后 , 右键点击弹出菜单 , 选择 \\\" 保存图片 \\\" 选项 ; 点击图像下方的 Web 按钮 , 可以在

    2024年02月09日
    浏览(32)
  • URL到页面: 探索网页加载的神秘过程

    当我们从浏览器的地址栏输入 URL, 按下回车, 再到最后出现需要的网页界面, 这中间究竟发生了什么, 接下来就一步步进行解析. 主要是如下过程: 输入网址 DNS 解析 客户端发送 HTTP 请求 建立 TCP 连接 服务器处理请求, 计算响应, 返回响应 浏览器渲染页面 关闭连接 本篇中只是概

    2024年02月08日
    浏览(34)
  • 通过Wireshark捕捉访问网页的全过程

    整个过程可以概括为以下几个部分: 1)域名解析成IP地址 2)与目的主机进行TCP连接(三次握手) 3)发送与收取数据(浏览器与目的主机开始HTTP访问过程) 4)与目的主机断开TCP连接(四次挥手) 打开一个无痕浏览器,并访问网站www.4399.com 访问完成后,停止抓包 DNS域名解

    2023年04月08日
    浏览(41)
  • Eclipse关于搭建JSP运行环境(超级详细过程附带网页地址)

    1.下载jdk 2.配置环境变量 3.下载安装Tomcat 4.下载安装Eclipse 5.配置Eclipse运行第一个JSP程序 百度地址栏搜索https://www.oracle.com/java/technologies/downloads/archive/ 点击自己想要下载版本即可 我们选择windows系统64位8.5的版本 下载完成双击运行按照安装向导安装即可,设置安装路径时要放到

    2024年02月07日
    浏览(33)
  • Python网页爬虫爬取起点小说——re解析网页数据

    !!注意:我们获取到的网页响应数据,可能会与网页源代码中呈现的格式不同。因为有些网页文件是用JavaScript加载的,浏览器会自动将其解析成html文档格式,而我们获取到的内容是JavaScript格式的文档。所以获取到响应数据之后先要查看内容是否与网页源码中的一致,不一

    2024年02月04日
    浏览(42)
  • 6.3.6 利用Wireshark进行协议分析(六)----网页提取过程的协议分析

    6.3.6 利用Wireshark进行协议分析(六)----网页提取过程的协议分析 利用Wireshark捕获网页访问过程中产生的应用协议报文,还原Web服务中报文的交互过程,为了防止网页直接从本地缓存中获取,我们首先需要清空浏览器保存的历史记录或者数据,具体操作步骤如下 清空浏览器保

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包