重绘和回流以及如何优化

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


相关推荐

  • 卡盟主站安装教程

    卡盟主站安装教程config.php数据库连接文件配置 视频密码confighttp://www.tudou.com/v/adVnUX3dMOM/&amp;rpid=61582914&amp;resourceId=61582914_04_05_99/v.swf卡盟主站搭建源码上传 视频密码kamengyuanmahttp://www.tudou.com/v/yv0tpzikiC8/&amp;rp…

    2022年8月12日
    6
  • python里for循环用法_python遍历循环

    python里for循环用法_python遍历循环python中使用for循环的方法发布时间:2020-12-0809:35:27来源:亿速云阅读:95作者:小新小编给大家分享一下python中使用for循环的方法,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!python循环方式有两个,一个是while循环,另一个就是for循环,while循环和if条件分支语句类似,即在条件(表达式)为真的情况下,会执行相应的代码块。…

    2022年8月12日
    8
  • Python动态爬虫爬取京东商品评论[通俗易懂]

    Python动态爬虫爬取京东商品评论[通俗易懂]Python动态爬虫爬取京东商品评论1.概述京东商城是Python爬虫初学者试手的经典平台,反爬虫程度较低,但评论采取了动态加载的方式,爬取京东商品评论是学习动态爬虫的一个极佳方法。动态爬虫,即针对动态加载JSON文件网页的爬虫,其原理与静态爬虫没有本质区别,只是不爬取所见的静态目标网页,而是寻找该网页所加载的JSON文件,爬取JSON文件中的内容。2.目标观察观察京东具体商品评论页面:点击商品评价页:发现商品评价翻页的url不改变,可推测出其采用动态加载的方式,同时,会发现直接获取该

    2022年7月26日
    9
  • android代码签名和混乱的包装

    android代码签名和混乱的包装

    2022年1月7日
    57
  • java 特点_JAVA的几个重要特点[通俗易懂]

    java 特点_JAVA的几个重要特点[通俗易懂]展开全部一.简单性:Java是纯62616964757a686964616fe58685e5aeb931333433663063面向对象语言,语法简单明了,易于掌握。Java使用接口取代了多重继承,并且取消了指针,因为多重继承和指针会使程序变得复杂。Java还会自动地收集内存垃圾,使得内存管理变得更为简单。Java还提供了丰富的类库、API文档以及第三方开发包,还有大量Java的开源项目。二.面向…

    2022年7月7日
    17
  • ES6 数组新增方法

    ES6 数组新增方法目录ES6数组新增方法1、.map2、some和every方法3、filter4、数组新增的reduce方法ES6数组新增方法1、.map.map()给数组中的每一个元素添加特殊处理,返回新的数组实现给定数组添加元letprices=[20,30,40]//20元30元40元letarr=prices.map(item=>item+”元”)给给定数据替换某内容letmovies=[{id:1,name:’逃学…

    2022年5月10日
    38

发表回复

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

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