重绘和回流以及如何优化

重绘和回流以及如何优化1 浏览器渲染机制浏览器采用流式布局模型 FlowBasedLay 浏览器会把 HTML 解析成 DOM 把 CSS 解析成 CSSOM DOM 和 CSSOM 合并就产生了渲染树 RenderTree 有了 RenderTree 我们就知道了所有节点的样式 然后计算他们在页面上的大小和位置 最后把节点绘制到页面上 由于浏览器使用流式布局 对 RenderTree 的计算通常只需要遍历一

1、浏览器渲染机制

2、回流 (refolw)

节点的几何属性或者布局发生改变被称为回流,一个元素的回流可能会导致了其所有子元素以及DOM中紧随其后的节点、祖先节点元素的随后的回流,所以一个节点的回流会引起页面某个部分甚至整个页面的回流。

3、重绘(repaint)

节点的样式改变且不影响布局的,比如color,visibility等,称为重绘。

重绘不一定回流,回流一定重绘。

4、 浏览器优化

5、减少回流和重绘

5.1、批量修改DOM或者样式

const el = document.getElementById('test'); el.style.padding = '5px'; el.style.borderLeft = '1px'; el.style.borderRight = '2px'; //可以优化为使用cssText或者class统一添加 const el = document.getElementById('test'); el.style.cssText += 'border-left: 1px; border-right: 2px; padding: 5px;'; //或者 const el = document.getElementById('test'); el.className += ' active';
function appendDataToElement(appendToElement, data) { let li; for (let i = 0; i < data.length; i++) { li = document.createElement('li'); li.textContent = 'text'; appendToElement.appendChild(li); } } const ul = document.getElementById('list'); appendDataToElement(ul, data);
const ul = document.getElementById('list'); const fragment = document.createDocumentFragment(); appendDataToElement(fragment, data); ul.appendChild(fragment);
function appendDataToElement(appendToElement, data) { let li; for (let i = 0; i < data.length; i++) { li = document.createElement('li'); li.textContent = 'text'; appendToElement.appendChild(li); } } const ul = document.getElementById('list'); ul.style.display = 'none'; appendDataToElement(ul, data); ul.style.display = 'block';

5.2、避免触发同步UI渲染

function initP() { for (let i = 0; i < paragraphs.length; i++) { paragraphs[i].style.width = box.offsetWidth + 'px'; } }

这段代码看上去是没有什么问题,可是其实会造成很大的性能问题。在每次循环的时候,都读取了box的一个offsetWidth属性值,然后利用它来更新p标签的width属性。这就导致了每一次循环的时候,浏览器都必须先使上一次循环中的样式更新操作生效,才能响应本次循环的样式读取操作。每一次循环都会强制浏览器刷新队列。我们可以优化为:

const width = box.offsetWidth; function initP() { for (let i = 0; i < paragraphs.length; i++) { paragraphs[i].style.width = width + 'px'; } }

5.3、对于复杂动画效果,使用绝对定位让其脱离文档流

例子中在未优化前,元素未绝对定位,依靠margin的变化进行动画,引起大量的回流,而当使用了绝对定位,明显感觉FPS稳定在每秒60次,也就是16.6ms一次。

5.4、css3硬件加速(GPU加速)

  1. 使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。
  2. 对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能
    如何使用
    常见的触发硬件加速的css属性:
    transform
    opacity
    filters
    Will-change
    效果
    我们可以先看个例子。我通过使用chrome的Performance捕获了动画一段时间里的回流重绘情况,实际结果如下图:
    1264683-20190902164913999-466046388.png








转载于:https://www.cnblogs.com/chenlei987/p/11447484.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233263.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机端口大全_计算机网络常见的端口号

    计算机端口大全_计算机网络常见的端口号计算机端口大全0端口:无效端口,通常用于分析操作系统1端口:传输控制协议端口服务多路开关选择器2端口:管理实用程序3端口:压缩进程5端口:远程作业登录7端口:回显9端口:丢弃11端口:在线用户13端口:时间17端口:每日引用18端口:消息发送协议19端口:字符发生器20端口:FTP文件传输协议(默认数据口)21端口:FTP文件传输协议(控制)22端口:SSH远程登录协议23端口:telnet(终端仿真协议),木马TinyTelnetServer开放此端口24端口:预留

    2025年9月4日
    21
  • java实现四种常用排序算法

    java实现四种常用排序算法四种常用排序算法冒泡排序特点:效率低,实现简单思想(从小到大排):每一趟将待排序序列中最大元素移到最后,剩下的为新的待排序序列,重复上述步骤直到排完所有元素。这只是冒泡排序的一种,当然也可以从后往前排。publicvoidbubbleSort(intarray[]){intt=0;for(inti=0;i&amp;amp;lt;…

    2022年7月25日
    10
  • 安装tcping

    安装tcpingcping在windows和linux系统中都不是内建的命令,需要我们自己去下载下载命令wgethttps://sources.voidlinux.eu/tcping-1.3.5/tcping-1.3.5.tar.gzsudoyuminstallepel-releaseyuminstalltcpingtcpingwww.baidu.com443详细见图…

    2022年6月23日
    40
  • StringUtils里面的 isEmpty方法和isBlank方法的区别[通俗易懂]

    StringUtils里面的 isEmpty方法和isBlank方法的区别[通俗易懂]写在前面:我是扬帆向海,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。这博客是对自己学习的一点点总结及记录,如果您对Java、算法感兴趣,可以关注我的动态,我们一起学习。 用知识改变命运,让我们的家人过上更好的生活。文章目录1、isEmpty()方法2、isBlank()方法3、总结1、isEmpty()方法源码:…

    2022年6月11日
    39
  • navicat手动激活码【2021最新】

    (navicat手动激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月30日
    633
  • intel处理器_bios cppc

    intel处理器_bios cppcC++string类的find()函数怎么用

    2025年8月14日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号