揭露JavaScript DOM操作基本原则

开发 前端
本文向大家描述一下JavaScript DOM操作基本原则,在Web开发中,JavaScript的一个很重要的作用就是对DOM进行操作。

我们都知道,JavaScript DOM操作的效率是很低的,而且不是一般的慢,而且这也是引发性能问题的常见问题之一。为什么会慢呢?因为对DOM的修改为影响网页的用户界面,重绘页面是一项昂贵的操作。

JavaScript DOM操作基本原则

在Web开发中,JavaScript的一个很重要的作用就是对DOM进行操作,我们都知道,JavaScript DOM操作的效率是很低的,而且不是一般的慢,而且这也是引发性能问题的常见问题之一。为什么会慢呢?因为对DOM的修改为影响网页的用户界面,重绘页面是一项昂贵的操作。太多的JavaScript DOM操作会导致一系列的重绘操作,为了确保执行结果的准确性,所有的修改操作是按顺序同步执行的。我们称这个过程叫做回流(reflow),同时这也是最昂贵的浏览器操作之一。回流操作主要会发生在几种情况下:

◆当对DOM节点执行新增或者删除操作时。

◆动态设置一个样式时(比如element.style.width="10px")。

◆当获取一个必须经过计算的尺寸值时,比如访问offsetWidth、clientHeight或者其他需要经过计算的CSS值(在兼容DOM的浏览器中,可以通过getComputedStyle函数获取;在IE中,可以通过currentStyle属性获取)。

解决问题的关键,就是限制通过JavaScript DOM操作所引发回流的次数。大部分浏览器都不会在JavaScript的执行过程中更新DOM。相应的,这些浏览器将对对DOM的操作放进一个队列,并在JavaScript脚本执行完毕以后按顺序一次执行完毕。也就是说,在JavaScript执行的过程中,用户不能和浏览器进行互动,直到一个回流操作被执行。(失控脚本对话框会触发回流操作,因为他执行了一个中止JavaScript执行的操作,此时会对用户界面进行更新)

如果要减少由于DOM修改带来的回流操作,有两个基本的方法。***个就是在对当前DOM进行操作之前,尽可能多的做一些准备工作。一个经典的例子就是向document对象中添加很多DOM节点:

  1. for(vari=0;i<items.length;i++){  
  2. varitem=document.createElement("li");  
  3. item.appendChild(document.createTextNode("Option"+i);  
  4. list.appendChild(item);  

这段代码的效率是很低的,因为他在每次循环中都会修改当前DOM结构。为了提高性能,我们需要将这个次数降到***,对于这个案例来说,***的办法是建立一个文档碎片(documentfragment),作为那些已创建元素元素的临时容器,***一次将容器的内容直接添加到父节点中: 

  1. varfragment=document.createDocumentFragment();  
  2. for(vari=0;i<items.length;i++){  
  3. varitem=document.createElement("li");  
  4. item.appendChild(document.createTextNode("Option"+i);  
  5. fragment.appendChild(item);  
  6. }  
  7. list.appendChild(fragment); 

经过调整的代码,只会修改一次当前DOM的结构,就在***一行,而在这之前,我们用文档碎片来保存那些中间结果。因为文档碎片没有任何可见内容,所以这类修改不会触发回流操作。实际上,文档碎片也不能被添加到DOM中,我们需要将它作为参数传给appendChild函数,而实际上添加的不是文档碎片本身,而是它下面的所有子元素。
避免不必要回流操作的另外一种方法,就是在对JavaScript DOM操作之前,把要操作的元素,先从当前DOM结构中删除。对于删除一个元素,基本有两种方法:

◆通过removeChild()或者replaceChild()实现真正意义上的删除。

◆设置该元素的display样式为“none”。

而一旦修改操作完成,上面这个过程就需要反转过来,将删除的元素重新添加到当前的DOM结构中,我们还是拿上面的例子来做说明: 

  1. list.style.display="none";  
  2. for(vari=0;i<items.length;i++){  
  3. varitem=document.createElement("li");  
  4. item.appendChild(document.createTextNode("Option"+i);  
  5. list.appendChild(item);  
  6. }  
  7. list.style.display=""

将list的display样式设置为“none”后,就将这个元素从当前的DOM结构中删除了,因为这个节点不再可视。在将display属性设置回之前的默认值之前,向其下添加子元素是不会触发回流操作的。

另外一个经常引起回流操作的情况是通过style属性对元素的外观进行修改。比如下面这个例子: 

  1. element.style.backgroundColor="blue";  
  2. element.style.color="red";  
  3. element.style.fontSize="12em"

【编辑推荐】

  1. 技术分享 如何获取Dom元素的X/Y坐标
  2. JQuery创建DOM元素方法解析
  3. JavaScript获取HTML DOM节点元素详解
  4. JavaScript和DOM轻松实现数据访问
  5. 减少浏览器重解析 JavaScript DOM操作优化方案

 

责任编辑:佚名 来源: school.cnd8.com
相关推荐

2019-09-18 18:56:34

JavascriptOOP前端

2010-08-12 10:03:21

Flex性能优化

2017-04-17 20:50:50

2022-10-25 09:50:56

2024-04-28 11:32:32

软件架构开发

2010-09-09 13:59:55

CSS

2021-09-13 10:30:42

C++代码设计模式

2010-09-08 13:53:31

CSS

2020-01-08 18:27:53

七项基本原则高效漏洞管理IT

2012-03-06 09:02:41

软件开发

2015-06-04 10:13:56

DCIM运维管理

2015-06-09 11:08:20

2011-04-22 16:17:53

电脑维修

2010-09-28 14:52:57

JavaScriptDOM

2010-05-21 11:22:04

2010-07-19 15:58:12

面试原则

2018-01-07 00:10:39

数据中心运营IT

2011-06-16 13:45:14

2020-01-09 08:55:45

漏洞漏洞管理VM

2010-08-10 09:53:45

Flex性能优化
点赞
收藏

51CTO技术栈公众号