重绘和回流以及如何优化

重绘和回流以及如何优化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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 15个你可能不知道的开源云平台

    15个你可能不知道的开源云平台1.1云服务环境Eucalyptus1.1.1介绍ElasticUtilityComputingArchitectureforLinkingYourProgramsToUsef

    2022年7月2日
    18
  • clone fail smartgit_SmartGit

    clone fail smartgit_SmartGit安装选择非商业的第三个设置username和邮箱简单的配置ignore忽略一些不需要上传的配置文件,需要配置.gitignore文件.可以在github上搜索到所有编程语言需要忽略的配置文件ignore列表,从列表中找到对应的OC语言需要忽略的文件就可以了。修改ignore文件删除某一类文件的命令在SVN版本控制的project中,drag文件到git版本控制下的project中时…

    2025年8月25日
    2
  • sunlime 激活码(最新序列号破解)

    sunlime 激活码(最新序列号破解),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月20日
    55
  • 绕过问题也是一种能力–记一次接口的问题「建议收藏」

    绕过问题也是一种能力–记一次接口的问题

    2022年1月19日
    82
  • WIN10环境JAVA的JDK环境变量设置教程

    WIN10环境JAVA的JDK环境变量设置教程大一时装JDK时对着网上的摆弄了好久,然后自己出了个图文教程在同学间流传甚广,最近同学帮大一的问我怎么装,此处将当时的教程完整的复制过来。希望能解决你们的问题。应用JAVA程序之前必须设置系统变量,就像每个生物都得有适合自己生存的环境一样,只有设置成功了才能成功运行JAV软件建议按照系统默认路径安装到C盘,如果你是高手就算了。系统变量设置步骤:(以下图片教…

    2022年7月8日
    23
  • c语言fread函数的功能_C语言strchr

    c语言fread函数的功能_C语言strchr目录一.fread函数简介二.fread函数使用三.猜你喜欢零基础C/C++学习路线推荐:C/C++学习目录>>C语言基础入门一.fread函数简介C语言fread函数用于读取文件中的数据到指定缓冲区中,fread函数声明如下:/**描述:关闭文件**参数:*[out]ptr:缓冲区,用于存放读取到的数据*[in]size:每个元素的大小(单位是字节)*[in]nmemb:要读取的元素个数*[in

    2025年8月27日
    7

发表回复

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

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