【JavaScript】回流(reflow)与重绘(repaint)
重绘与回流
首先要了解页面是如何呈现的:
- HTML文档加载后生成DOM树(包括display:none;元素);
- 在DOM树的基础上配合css样式结构体生成render树(不包含display:none;、head节点,包含visibility:hidden;节点),即页面中的占位确定了.
- 最后绘制页面(也叫渲染),不会改变页面布局的一些属性:color、背景色等。
- 重绘(repaint):更新页面元素的属性引起的,如颜色、透明度等不会改变页面布局而需要重新渲染的。
- 回流(reflow):render树中部分或全部元素的尺寸、布局、隐藏等(内容、结构、位置)改变引起的,每个页面至少有一次回流(即初始构建页面时),成本较高。
- DOM操作(对元素的增删改、顺序变化等)
- 内容变化,包括表单区域内的文本变化
- css属性的更改或者重新计算
- 增删样式表内容
- 修改class属性
- 浏览器窗口变化(滚动或缩放)
- 伪类样式激活(:hover等)
这些情况会引起回流,减少回流就是尽量避免或减少这写操作的执行次数。
减少页面重绘与回流:
页面中需要需要动态生成id为box的div中的内容,结果如下:
<div id="box">
<p class="btn-title"><i class="iconfont"></i>项目阶段</p>
<ul class="btn-group" id="proStepul">
<li class="btn-item" data_id="">全部</li>
<li class="btn-item" data_id="">全部</li>
<li class="btn-item" data_id="">全部</li>
<li class="btn-item" data_id="">全部</li>
<li class="btn-item" data_id="">全部</li>
</ul>
</div>
一般的做法可以用innerHTML或者createElement:
var Obox = document.getElementById("box");
Obox.innerHTML = '<p class="btn-title"><i class="iconfont"></i>项目阶段</p>';
Obox.innerHTML += '<ul class="btn-group" id="proStepul">';
for(var i=0;i<5;i++){
Obox.innerHTML += '<li class="btn-item" data_id="">全部</li>';
}
Obox.innerHTML +='</ul>';
这样写要向Obox中写入很多次。成本增高,建议的方法是用变量存储然后一次写入。
var Obox = document.getElementById("box");
var str = '';
str = '<p class="btn-title"><i class="iconfont"></i>项目阶段</p>';
str += '<ul class="btn-group" id="proStepul">';
for(var i=0;i<5;i++){
str += '<li class="btn-item" data_id="">全部</li>';
}
str +='</ul>';
Obox.innerHTML = str;
用createElement方法如下:可是这样的结构很糟糕,多次写入,增加很多重绘与回流。
var Obox = document.getElementById("box");
var Op = document.createElement("p");
Obox.appendChild(Op);
Op.setAttribute("class","btn-title");
Op.innerHTML ="项目阶段";
var Oi = document.createElement("i");
Op.appendChild(Oi);
Oi.setAttribute("class","iconfont");
var Oul = document.createElement("ul");
Obox.appendChild(Oul);
Oul.setAttribute("class","btn-group");
Oul.setAttribute("id","proStepul");
for(var i=0;i<5;i++){
var Oli = document.createElement("li");
Oul.appendChild(Oli);
Oli.setAttribute("class","btn-item");
}
合理的方法是:先构建元素,然后设置元素的属性等,最后再将元素添加到页面相应位置:
var Obox = document.getElementById("box");
var Op = document.createElement("p");
//Obox.appendChild(Op);
Op.setAttribute("class","btn-title");
Op.innerHTML ="项目阶段";
var Oi = document.createElement("i");
Op.appendChild(Oi);
Oi.setAttribute("class","iconfont");
var Oul = document.createElement("ul");
//Obox.appendChild(Oul);
Oul.setAttribute("class","btn-group");
Oul.setAttribute("id","proStepul");
for(var i=0;i<5;i++){
var Oli = document.createElement("li");
Oul.appendChild(Oli);
Oli.setAttribute("class","btn-item");
}
Obox.appendChild(Op);
Obox.appendChild(Oul);
这里只需将新建元素写入页面的操作移到最后即可,至于元素在未写入页面之前的操作顺序如何,对页面并没有什么影响,不会造成页面回流或者重绘。
有一种情况为:需要像页面中写入多个同一级的元素,如下:向ul元素中写入多个li元素
<ul class="btn-group on" id="proStepul">
<li class="btn-item on" >全部</li>
<li class="btn-item on" >全部</li>
<li class="btn-item on" >全部</li>
<li class="btn-item on" >全部</li>
<li class="btn-item on" >全部</li>
</ul>
如果用之前的方法,不可避免的要写五个Oul.appendChild("Oul");了,这时我们可以用JS提供的可以整合多个碎片的中介----document.createDocumentFragment();
var Oul = document.getElementById("proStepul");
var obj = document.createDocumentFragment();
for (var i = 0; i < 5; i++) {
var Oli = document.createElement("li");
Oli.setAttribute("class", "btn-item");
obj.appendChild(Oli);
}
Oul.appendChild(obj);
【JavaScript】回流(reflow)与重绘(repaint)的更多相关文章
- 回流(reflow)与重绘(repaint)
回流(reflow)与重绘(repaint) 很早之前就听说过回流与重绘这两个名词,但是并不理解它们的含义,也没有深究过,今天看了一套网易的题目,涉及到了这两个概念,于是想要把它们俩弄清楚... 一. ...
- 什么是回流(重排 reflow)?什么是重绘(repaint)?如何减少回流、重绘?
什么是回流(重排 reflow)? 回流(重排 reflow):对DOM树进行渲染,只要修改DOM或修改元素的形状大小,就会触发reflow,reflow的时候,浏览器会使已渲染好受到影响的部分失效, ...
- 页面重绘(repaint)和回流(reflow)
前言 页面显示到浏览器上的过程: 1.1.生成一个DOM树. 浏览器将获取到的HTML代码解析成1个DOM树,包含了所有标签,包括display:none和动态添加的节点. 1.2.生成样式结构体. ...
- 页面优化,谈谈重绘(repaint)和回流(reflow)
一.前言 偶尔在面试过程中遇到过重汇与回流reflow的问题,毕竟页面优化也是考核一个开发者能力的关键之一,上篇文章聊了下documentfragment也是为了减轻回流问题,那么本篇文章好好介绍下重 ...
- 前端性能优化--回流(reflow)和重绘(repaint)
HTML加载时发生了什么 在页面加载时,浏览器把获取到的HTML代码解析成1个DOM树,DOM树里包含了所有HTML标签,包括display:none隐藏,还有用JS动态添加的元素等. 浏览器把所有样 ...
- 【笔记】web 的回流与重绘及优化
最近看了幕课网 web 前端性能优化的课程,其中说到了浏览器的回流(reflow) 及 重绘(repaint).觉得以后面试或许会被问到所以做一下笔记: 课程从回流及重绘这两个点延伸出了一个知识点就是 ...
- DOM 操作成本究竟有多高,HTML、CSS构建过程 ,从什么方向出发避免重绘重排)
前言: 2019年!我准备好了 正文:从我接触前端到现在,一直听到的一句话:操作DOM的成本很高,不要轻易去操作DOM.尤其是React.vue等MV*框架的出现,数据驱动视图的模式越发深入人心,jQ ...
- CSS重排和重绘
一.什么是重绘Repaint和重排 (回流 reflow) 重绘:当元素的一部分属性发生改变,如外观.背景.颜色等不会引起布局变化,只需要浏览器根据元素的新属性重新绘制 ,使元素呈现新的外观叫做重绘. ...
- 重绘(Repaint)和回流(Reflow)
重绘(Repaint)和回流(Reflow) 1.回流和重绘只是渲染步骤的一小节,是怎么做到影响性能的? css 会影响 javascrip 执行时间导致 javascript 脚本变慢 浏览器渲染一 ...
- 浏览器的回流与重绘 (Reflow & Repaint)
写在前面 在讨论回流与重绘之前,我们要知道: 浏览器使用流式布局模型 (Flow Based Layout). 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了 ...
随机推荐
- Netty简单认识
简介 Netty 是由JBOSS提供的一个 Java开源框架, 现在是 Github上的开源项目 Netty 是一个异步的.基于事件驱动的网络应用框架式, 用以快速开发高性能.高可靠性的网路IO程序 ...
- 实验吧-杂项-pilot-logic、ROT-13变身了
1.pilot-logic 题上说password藏在文件里,直接丢到Winhex里,搜索pass就拿到flag了. 有的大佬提供了另一种方法,题上说是一个磁盘文件,有一个处理磁盘文件的软件autop ...
- Spring配置数据源以及hibernate
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 《Airbnb架构要点分享》阅读笔记
Airbnb成立于2008年8月,总部位于加利福尼亚州旧金山市.Airbnb是一个值得信赖的社区型市场,在这里人们可以通过网站.手机或平板电脑发布.发掘和预订世界各地的独特房源,其业务已经覆盖190个 ...
- Django(五)1 - 4章实战:从数据库读取图书列表并渲染出来、通过url传参urls.py path,re_path通过url传参设置、模板语法
一.从数据库读取图书数据并渲染出来 1)app1/views.py函数books编写 [1]从模型下导入bookinfo信息 [2]从数据库获取图书对象列表 [3]把获取到的图书对象赋值给books键 ...
- HttpClient测试
导入maven依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson&l ...
- 剑指offer自学系列(五)
题目描述:请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g".当从该字符流中读出 ...
- Adapter之自定义Adapter
前言: 在我们写程序是经常会用到适配器,当系统自带的适配器不够用时即可自己定义适配器 正文: 因为我们用到的ListView视图所以我们先初始化ListView,在我们的主活动中添加如下代码 < ...
- UVALive - 7752 Free Figurines
题意:有n个娃娃,如果大娃娃j直接套小娃娃i,则fa[i] = j.若fa[i] = 0,则该娃娃自由.给出每个娃娃初始的父亲,和改变后的父亲,在满足以下合法操作的条件下,问最少需要多少次变换. 1. ...
- UVA - 1451 Average (斜率优化)
题意:由01组成的长度为n的子串,AT由0表示,GC由1表示,求一段长度大于等于L且GC率最高的子串的起始终止坐标,若GC率相同,取长度较小,若长度相同,取起始坐标最小. 分析: 1.一个子串(i+1 ...