1.DOM的重绘和回流Repaint&Reflow


1.1重绘:元素样式的改变(但宽高、大小、位置等不变)


如outline、visibility、color、background-color等

1.2回流:元素的大小或者位置发生了变化(当页面布局和几何信息发生变化的时候),触发了重新布局,导致渲染树重新设计布局和渲染。


如添加或删除可见的DOM元素;元素的位置发生变化,元素的尺寸发生变化,内容发生变化(比如文本变化或者图片被另一个尺寸不一样的图片替换);页面一开始渲染的时候(这是无法避免);因为回流是根据视口的大小来计算元素的位置和大小的,所以浏览器的窗口尺寸变化也会引发回流。

注意回流一定会触发重绘,重绘不一定会回流。

2.前端性能优化:避免DOM的回流


2.1放弃传统操作DOM,基于vue/react开始数据影响视图模式


可通过vue或react等框架中的virtual dom/dom diff,避免对DOM的直接操作。

2.2分离读写操作(现代的浏览器都有渲染队列的机制)


style样式

<style>
#box {
width: 100px;
height: 100px;
background-color: red;
border: 1px solid yellow;
}
</style>

body代码

<body>
<div id="box"></div>
<script>
//(1)
let box = document.getElementById('box');
box.style.width = '200px'; //大小发生变化,引发一次回流
box.style.height = '200px';
box.style.margin = '10px';
//因为浏览器存在渲染队列机制,如果引发回流的语句挨在一起写,只会引发一次回流 //(2)
box.style.height = '300px';
console.log(box.clientWidth); //不引发回流
box.style.margin = '20px';
//中间插入非引发回流语句,打断了任务队列,所以总共回流2次 //(3)
box.style.height = '300px';
box.style.margin = '30px';
console.log(box.clientWidth); //只引发一次DOM回流
/*分离读写:就是把能引发回流的"写语句"与不能引发回流的"读语句"分开写,以减少回流次数*/
</script>
</body>

2.3样式集中改变


style样式

<style>
#box {
width: 100px;
height: 100px;
background-color: red;
border: 1px solid yellow;
} .a {
width: 200px;
}
</style>

body代码

<body>
<div id="box"></div>
<script>
let box = document.getElementById('box');
/*批量处理:把元素的多个样式统一修改减少DOM的回流*/
//(1)直接添加多种样式
// box.style.cssText = 'width:200pxl;height:200px;';
//(2)通过添加类名添加多种样式
box.className = 'a';
</script>
</body>

2.4缓存布局信息


body代码

<body>
<script>
let box = document.getElementById('box');
//缓存处理(实质上属于分离读写)
//(1)
box.style.width = box.clientWidth + 10 + 'px';
box.style.height = box.clientHeight + 10 + 'px';
//由于box.clientWidth获取操作,终端了任务队列,上面语句触发两次DOM回流 //(2)
let a = box.clientWidth;
let b = box.clientHeight;
box.style.width = a + 10 + 'px';
box.style.height = b + 10 + 'px';
//先使用一个变量存储获取的数据,再进行写操作,就不会中断任务队列,只触发一次DOM回流。
</script>
</body>

2.5元素批量修改


body代码

<body>
<ul id="box"> </ul>
<script>
//批量处理:在ul中动态创建5个li
var box = document.querySelector('#box'); //(1)
for (let i = 0; i < 5; i++) {
let newLi = document.createElement('li');
newLi.innerHTML = i;
box.appendChild(newLi);
}
//这种写法循环几次便会引发几次回流不可取 //(2) 文档碎片
let frg = document.createDocumentFragment(); //创建一个文档碎片的临时容器
for (let i = 0; i < 5; i++) {
let newLi = document.createElement('li');
newLi.innerHTML = i;
//创建的li先储存在文档碎片中
frg.appendChild(newLi);
}
box.appendChild(frg);
frg = null; //对于不用的容器,要进行销毁释放
//相当于把文档碎片frg中的对象一次性添加到box中只引发一次文档回流。可取 //(3)模板字符串拼接 (最优)
let str = ``;
for (let i = 0; i < 5; i++) {
str += `<li>${i}</li>`;
}
box.innerHTML = str; //只引发一次回流
//运用ES6的模板字符串,添加标签十分方便,并且能够有效减少文档回流,为最优方法。
</script>
</body>

2.6动画效果应该使用position属性absolute或者fixed(脱离文档流)


如果使用margin等属性对元素进行定位,会对其他元素的位置造成影响并导致回流。而使用position属性进行定位的元素能够脱离文档流,在一个新的平面上操作,虽然也会引起回流,但是不会影响其他元素,性能更好。

2.7CSS3硬件加速(GPU加速)


比起考虑如何减少回流、重绘,我们更期望的是,根本不需要回流和重绘;transform、opacity、filters...这些属性会触发硬件加速,不会引发回流和重绘。

通常用的比较多的是transform(能用transform改变的样式绝对不用普通样式)。比如用translate属性来移动元素不会引起回流。

缺点:用的多会导致占用大量内存,性能消耗严重。

2.8牺牲平滑度换取速度


简单地说就是动画总移动100px的情况下,每一秒钟移动1px,平滑度高,但是会引发100次回流;每一秒钟移动10px,平滑度相对较差,但是只会引起10次回流。当电脑比较快时可取前者,电脑较慢应取后者。

2.9避免使用table布局


由于table布局要一层一层的嵌套,添加完底层样式,才开始往外一层一层添加样式,不仅不好写样式,而且不利于DOM的性能优化。

DOM的重绘和回流及代码性能优化的更多相关文章

  1. 理解浏览器的重绘与回流(repaint&&reflow)

    今天在做练习的时候,遇到了重绘与回流这个词,表示连个毛都没有听过.遂查之,首先将网上的(http://blog.sina.com.cn/s/blog_8dace7290102wezv.html)关于这 ...

  2. 【web性能】页面呈现、重绘、回流

    在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...

  3. 重绘和回流(reflow和repaint)

    由于DOM操作会导致浏览器的回流,回流需要花费大量的时间进行样式计算和节点重绘与渲染,所以应当尽量减少回流次数. 以下是几种常见的减少重绘和回流的方法: 一.不要一项一项的更改页面的样式,尽量一口气写 ...

  4. 高性能WEB开发:深入理解页面呈现、重绘、回流

    在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...

  5. 浅谈JS重绘与回流

    在说浏览器渲染页面之前,我们需要先了解两个点,一个叫 浏览器解析 URL,另一个就是本章节将涉及的 重绘与回流: 重绘(repaint):当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新, ...

  6. Web前端性能优化-重绘与回流

    1.什么是重绘与回流 Render tree 的重新构建就叫回流.当布局和几何属性改变时就需要回流,鼠标移动到图片 图片变大 也会触发回流.回流 能避免就避免 Render tree 改变外观.风格 ...

  7. 介绍下重绘和回流(Repaint & Reflow),以及如何进行优化

    1. 浏览器渲染机制 浏览器采用流式布局模型(Flow Based Layout) 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了渲染树(Render Tre ...

  8. 重绘和回流(Repaint & Reflow)总结,以及如何进行优化

    1. 浏览器渲染机制 浏览器采用流式布局模型(Flow Based Layout) 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了渲染树(Render Tre ...

  9. Python 代码性能优化技巧(转)

    原文:Python 代码性能优化技巧 Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化. ...

随机推荐

  1. 修改robotframework的元素定位方式,使之支持带括号的xpath定位方式

    今天困扰我的一个问题终于解决了 robot框架默认的xpth定位方式是不支持带括号运算的xpth表达式的,例如: (//*[@content-desc="iv_message_icon_21 ...

  2. Putty 连接centOS7 超时问题

    方法1: #vim /etc/ssh/sshd_config(添加或修改以下配置) ClientAliveInterval 60(每隔60秒给SSH客户端发送一次信号)   ClientAliveCo ...

  3. requests---requests上传图片

    我们在做接口测试的时候肯定会遇到一些上传图片,然后进行校验,今天我们一起学习通过requests上传图片,查看是否上传成功 抓取上传接口 这里我以百度为例子进行操作,为啥要用百度呢,主要上传文件比较简 ...

  4. MATLAB聚类有效性评价指标(外部)

    MATLAB聚类有效性评价指标(外部) 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多内容,请看:MATLAB.聚类.MATLAB聚类有效性评价指 ...

  5. 史上最全的各种C++ STL容器全解析

    史上最全的C++ STL 容器大礼包 为什么\(C++\)比\(C\)更受人欢迎呢?除了\(C++\) 的编译令人感到更舒适,\(C++\)的标准模板库(\(STL\))也占了很重要的原因.当你还在用 ...

  6. codeforces 1260C. Infinite Fence (数学or裴蜀定理)

    只需要验证小间隔在大间隔之间有没有连续的k个 设小间隔为a,大间隔为b,那么a在b之间出现的次数在\(\lfloor \frac{b}{a}\rfloor\)或者\(\lfloor \frac{b}{ ...

  7. golang--连接redis数据库并进行增删查改

    (1)安装第三方开源的redis库: (2)在使用redis之前,需要安装第三方库,在GOPATH路径下执行安装指令--$GOPATH$:go get github.com/garyburd/redi ...

  8. Numpy 随机序列 shuffle & permutation

    1. numpy.random.shuffle(x) Modify a sequence in-place by shuffling its contents. This function only ...

  9. Http协议请求方法及body类型(思路比较清晰的)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u010244522/article/de ...

  10. tomcat程序生成的日志文件不可读问题 - 运维总结

    现象描述:线上机器的程序文件(包括TOMCAT自身)使用APP账号作为属主运行,同时禁止了APP账号的BASH.登录系统使用了统一认证,这样每个人都有自己的账号登录系统.为了方便开发人员登录查看日志, ...