JavaScript主要功能之一就是用来操作DOM,但操作DOM是非常昂贵的行为。
在初学阶段,达成目标是主要目标,随着技术的进步,会自然而然的关注代码的性能。
代码的性能对于小型的项目影响不是太大,但是对于大型项目或者操作量较高的项目则有明显的影响。
下面介绍一下常见的提高性能的方式。
一.遍历元素集合:
应用中,可能需要使用指定方法获取元素对象集合,然后对其进行遍历。
代码实例如下:
   [ 其他 ] 运行代码    下载代码
<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.51qianduan.com/" />
<title>JavaScript操作DOM性能优化</title>
<style type="text/css">
#box li {
  width: 350px;
  height: 25px;
  line-height: 25px;
  font-size: 12px;
}
</style>
<script>
addEventListener("DOMContentLoaded",function(){
  let lis=document.getElementsByTagName("li");
  for(let index=0;index<lis.length;index++){
    lis[index].style.color="blue";
  }
},false);
</script>
</head>
<body>
  <ul id="box">
    <li>51前端一</li>
    <li>51前端二</li>
    <li>51前端三</li>
    <li>51前端四</li>
    <li>51前端五</li>
    <li>51前端六</li>
  </ul>
</body>
</html>
代码分析如下:
(1).通过getElementsByTagName方法获取li元素集合。
(2).此集合是动态的,也就是它能够自动实时感知li元素的增加或者减少。
(3).然后通过for循环遍历每一个li元素,再将其字体元素设置为蓝色。
上述代码并不是最优方式,由于集合是动态的,所以lis.length获取集合中的元素数量性能较差。
那么可以将元素集合的数量事先缓存起来,而不是每循环一次获取一次,代码修改如下:
   [ 其他 ] 运行代码    下载代码
<script>
addEventListener("DOMContentLoaded",function(){
  let lis=document.getElementsByTagName("li");
  let len=lis.length;
  for(let index=0;index<len;index++){
    lis[index].style.color="blue";
  }
},false);
</script>
二.将多次样式操作合并为一次:
实际应用中,可能会使用如下方式设置元素的样式,代码片段如下:
   [ 其他 ] 运行代码    下载代码
<div>
let odiv = document.getElementById("ant");
odiv.style.color = "red";
odiv.style.background = "blue";
odiv.style.width = "200px";
odiv.style.height = "100px";
</div>
上述代码可以设置div元素的字体颜色、背景颜色和元素尺寸。
一切看起来很正常,但是性能比较低下,如果操作庞大,性能会有明显下降。
因为每一次使用style设置,都会引发页面的重绘或者重排,代码修改如下:
CSS代码如下:
   [ 其他 ] 运行代码    下载代码
<style type="text/css">
#ant {
  background: blue;
  color: red;
  width:200px;
  height: 200px;
}
</style>
JavaScript代码如下:
   [ 其他 ] 运行代码    下载代码
<script>
let odiv = document.getElementById("ant");
odiv.className = "ant";
</script>
使用上述代码,重绘和重排只有一次,可以极大提高想能。
三.经常需要重排的元素设置为绝对定位:
有些元素可能需要经常重排,那么可以将它们设置为绝对定位。
这样它们就可以脱离文档流,即便它们发生重排也不会影响其他元素,缩小了重排的范围。
四.使用fragment暂存节点:
假设我们需要依次创建若干个li元素,然后将其追加到ul中。
ul中追加li元素是一个重绘或者重排操作,很消耗性能,看如下代码片段:
   [ 其他 ] 运行代码    下载代码
<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.51qianduan.com/" />
<title>JavaScript操作DOM性能优化</title>
<script>
addEventListener("DOMContentLoaded",function(){
  let arr=["51前端一","51前端二","51前端三","51前端四","51前端五"];
  let oul=document.getElementById("box");
  for(let index=0;index<5;index++){
    let li=document.createElement("li");
    let oTxt=document.createTextNode("51前端"+arr[index]);
    li.appendChild(oTxt);
    oul.appendChild(li);
  }
},false);
</script>
</head>
<body>
<ul id="box"></ul>
</body>
</html>
上述代码通过for循环方式依次创建li元素,然后再依次将li元素追加到ul元素中。
虽然实现了预期效果,但是性能非常不好,因为进行了多次追加操作,进行了多次重绘重排。
所以可以将每一次附加操作暂存起来,然后一次性追加到ul中,进行一次重绘重排操作即可。
代码修改如下:
   [ 其他 ] 运行代码    下载代码
<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.51qianduan.com/" />
<title>JavaScript操作DOM性能优化</title>
<script>
addEventListener("DOMContentLoaded",function(){
  let arr=["51前端一","51前端二","51前端三","51前端四","51前端五"];
  let oFragment=document.createDocumentFragment();
  let oul=document.getElementById("box");
  for(let index=0;index<5;index++){
    let li=document.createElement("li");
    let oTxt=document.createTextNode("51前端"+arr[index]);
    li.appendChild(oTxt);
    oFragment.appendChild(li);
  }
  oul.appendChild(oFragment);
},false);
</script>
</head>
<body>
<ul id="box"></ul>
</body>
</html>
代码实现了相同的效果,但是性能更佳,分析如下:
(1).利用document.createDocumentFragment方法创建一个暂存器。
(2).然后将附加操作放入这个暂存器。
(3).最后将暂存器附加到ul中,事实就是将所有li元素一次性附加到ul。
五.巧用display:none元素:
隐藏元素不会影响不在渲染树中,对它的任何操作都不会引发重拍或者重绘操作。
所以要对元素进行比较复杂的各种操作时,如果允许的话,可以将其暂时隐藏起来。
操作完毕,再将其显示出来,这样只会产生一次重绘和重排操作。

代码描述:JavaScript DOM性能优化。JavaScript操作DOM性能优化



193 257



用户评论
大牛,别默默的看了,快登录帮我点评一下吧!:)      登录 | 注册



×
×
51前端

注册

×
绑定手机

请绑定手机号,在继续操作

×
单次下载支付

应付金额:279

支付完成后,回到下载页面,在进行下载

官方QQ群
意见反馈
qq群

扫描上面二维码加微信群

官方QQ群

jQuery/js讨论群
群号:642649996
Css3+Html5讨论群
群号:322131262

加群请备注:从官网了解到