重绘与回流

首先要了解页面是如何呈现的

  1. HTML文档加载后生成DOM树(包括display:none;元素);
  2. 在DOM树的基础上配合css样式结构体生成render树(不包含display:none;、head节点,包含visibility:hidden;节点),即页面中的占位确定了.
  3. 最后绘制页面(也叫渲染),不会改变页面布局的一些属性: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)的更多相关文章

  1. 回流(reflow)与重绘(repaint)

    回流(reflow)与重绘(repaint) 很早之前就听说过回流与重绘这两个名词,但是并不理解它们的含义,也没有深究过,今天看了一套网易的题目,涉及到了这两个概念,于是想要把它们俩弄清楚... 一. ...

  2. 什么是回流(重排 reflow)?什么是重绘(repaint)?如何减少回流、重绘?

    什么是回流(重排 reflow)? 回流(重排 reflow):对DOM树进行渲染,只要修改DOM或修改元素的形状大小,就会触发reflow,reflow的时候,浏览器会使已渲染好受到影响的部分失效, ...

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

    前言 页面显示到浏览器上的过程: 1.1.生成一个DOM树. 浏览器将获取到的HTML代码解析成1个DOM树,包含了所有标签,包括display:none和动态添加的节点. 1.2.生成样式结构体. ...

  4. 页面优化,谈谈重绘(repaint)和回流(reflow)

    一.前言 偶尔在面试过程中遇到过重汇与回流reflow的问题,毕竟页面优化也是考核一个开发者能力的关键之一,上篇文章聊了下documentfragment也是为了减轻回流问题,那么本篇文章好好介绍下重 ...

  5. 前端性能优化--回流(reflow)和重绘(repaint)

    HTML加载时发生了什么 在页面加载时,浏览器把获取到的HTML代码解析成1个DOM树,DOM树里包含了所有HTML标签,包括display:none隐藏,还有用JS动态添加的元素等. 浏览器把所有样 ...

  6. 【笔记】web 的回流与重绘及优化

    最近看了幕课网 web 前端性能优化的课程,其中说到了浏览器的回流(reflow) 及 重绘(repaint).觉得以后面试或许会被问到所以做一下笔记: 课程从回流及重绘这两个点延伸出了一个知识点就是 ...

  7. DOM 操作成本究竟有多高,HTML、CSS构建过程 ,从什么方向出发避免重绘重排)

    前言: 2019年!我准备好了 正文:从我接触前端到现在,一直听到的一句话:操作DOM的成本很高,不要轻易去操作DOM.尤其是React.vue等MV*框架的出现,数据驱动视图的模式越发深入人心,jQ ...

  8. CSS重排和重绘

    一.什么是重绘Repaint和重排 (回流 reflow) 重绘:当元素的一部分属性发生改变,如外观.背景.颜色等不会引起布局变化,只需要浏览器根据元素的新属性重新绘制 ,使元素呈现新的外观叫做重绘. ...

  9. 重绘(Repaint)和回流(Reflow)

    重绘(Repaint)和回流(Reflow) 1.回流和重绘只是渲染步骤的一小节,是怎么做到影响性能的? css 会影响 javascrip 执行时间导致 javascript 脚本变慢 浏览器渲染一 ...

  10. 浏览器的回流与重绘 (Reflow & Repaint)

    写在前面 在讨论回流与重绘之前,我们要知道: 浏览器使用流式布局模型 (Flow Based Layout). 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了 ...

随机推荐

  1. 记一次Redis+Getshell经验分享

    前言: 当我们接到一个授权渗透测试的时候,常规漏洞如注入.文件上传等尝试无果后,扫描端口可能会发现意外收获. 知己知彼乃百战不殆,Redis介绍: 简单来说 redis 就是一个Key-Value类型 ...

  2. imp.load_source的用法

    imp.load_source(name,pathname[,file])的作用把源文件pathname导入到name模块中,name可以是自定义的名字或者内置的模块名称. 假设在路径E:/Code/ ...

  3. 虚拟机下安装Maven

    1.首先需要下载maven安装包(我下载的是apache-maven-3.5.3版本) 官网下载:http://maven.apache.org/download.cgi 2.将压缩包放到虚拟机下(我 ...

  4. P1082 射击比赛

    P1082 射击比赛 转跳点:

  5. maven启动报错No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

    [INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building th ...

  6. 设置虚拟机静态ip

    1.查看本机ip.网关.dns服务器 IPv4地址:本机局域网ip 路由器:网关地址 nameserver:局域网内部dns服务器 其他dns服务器 移动.电信和联通:114.114.114.114 ...

  7. tcp协议与dup协议知识总结

    在工作之余用xmind总结了一些UDP协议与TCP协议的知识点,如果有需要可以通过下方的留言,分享xmind文件和xmind软件.

  8. springmvc(@ResponseBody)无法跳转到对应的jsp页面

    项目框架:spring+springmvc+mybatis 问题描述:Controller返回jsp页面名称后,前端无法跳转到该页面,而是将该jsp名称打印到前端页面 前端异常信息:无 后端异常信息: ...

  9. TX2--安装跑一python3.5

    sudo add-apt-repository ppa:webupd8team/javasudo apt-get updatesudo apt-get install oracle-java8-ins ...

  10. Python Learning Day6

    selenium操作 点击.清除操作 from selenium import webdriver from selenium.webdriver.common.keys import Keys im ...