两种方式实现加速Javascript DOM操作优化
创始人
2024-07-15 04:30:46
0

你对加速Javascript DOM操作优化的方法是否熟悉,在我们开发互联网富应用(RIA)时,我们经常写一些javascript脚本来修改或者增加页面元素,这些工作最终是DOM——或者说文档对象模型——来完成的,而我们的实现方式会影响到应用的响应速度。

加速Javascript DOM操作优化

在我们开发互联网富应用(RIA)时,我们经常写一些javascript脚本来修改或者增加页面元素,这些工作最终是DOM——或者说文档对象模型——来完成的,而我们的实现方式会影响到应用的响应速度。

Javascript DOM操作会导致浏览器重解析(reflow),这是浏览器的一个决定页面元素如何展现的计算过程。直接修改DOM,修改元素的CSS样式,修改浏览器的窗口大小,都会触发重解析。读取元素的布局属性比如offsetHeithe或者offsetWidth也会触发重解析。重解析需要花费计算时间,因此重解析触发的越少,应用就会越快。

Javascript DOM操作通常要不就是修改已经存在的页面上的元素,要不就是创建新的页面元素。下面有两种优化方案,大致覆盖了修改和创建DOM节点两种方式,帮助你减少触发浏览器重解析的次数。

方案一:通过CSS类名切换来修改DOM

这个方案让我们可以一次性修改一个元素和它的子元素的多个样式属性而只触发一次重解析。

需求:

(emu注:原文作者写到这里的时候脑子显然短路了一下,把后面的Out-of-the-flowDOMManipulation模式要解决的问题给摆到这里来了,不过从示范代码中很容易明白作者真正想描述的问题,因此emu就不照翻原文了)

我们现在需要写一个函数来修改一个超链接的几个样式规则。要实现很简单,把这几个规则对应的属性逐一改了就好了。但是带来的问题是,每修改一个样式属性,都会导致一次页面的重解析。

  1. functionselectAnchor(element){  
  2. element.style.fontWeight='bold';  
  3. element.style.textDecoration='none';  
  4. element.style.color='#000';  

解决方案:

要解决这个问题,我们可以先创建一个样式名,并且把要修改的样式规则都放到这个类名上,然后我们给超链接添加上这个新类名,就可以实现添加几个样式规则而只触发一次重解析了。这个模式还有个好处是也实现了表现和逻辑相分离。

  1. .selectedAnchor{  
  2. font-weight:bold;  
  3. text-decoration:none;  
  4. color:#000;  
  5. }  
  6.  
  7. functionselectAnchor(element){  
  8. element.className='selectedAnchor';  
  9. }  
  10.  

 介绍了加速Javascript DOM操作优化的方案一,下面来看一下方案二。#p#

方案二:在非渲染区修改DOM

(emu注:作者在这里再次脑子短路,把DocumentFragmentDOMGeneration模式的介绍提前到这里来了,emu只好再次发挥一下)
上一个方案解决的是修改一个超链接的问题,当一次需要对很多个超链接进行相同修改的时候,这个方案就可以大显身手了。

需求:

需求是这样的,我们要写一个函数来修改一个指定元素的子元素中所有的超链接的样式名(className)属性。要实现很简单,我们可以通过遍历每个超链接并且修改它们的样式名来完成任务。但是带来的问题就是,每修改一个超链接都会导致一次重解析。

  1. functionupdateAllAnchors(element,anchorClass){  
  2. varanchors=element.getElementsByTagName('a');  
  3. for(vari=0,length=anchors.length;i
  4. anchors[i].className=anchorClass;  
  5. }  

解决方案:

要解决这个问题,我们可以把被修改的指定元素从DOM里面移除,再修改所有的超链接,然后在把这个元素插入回到它原来的位置上。为了完成这个复杂的操作,我们可以先写一个可重用的函数,它不但移除了这个DOM节点,还返回了一个把元素插回到原来的位置的函数。

  1. /**  
  2. *Removeanelementandprovideafunction  
  3. thatinsertsitintoitsoriginalposition  
  4. *@paramelement{Element}Theelementtobetemporarilyremoved  
  5. *@return{Function}Afunctionthatinsertstheelementintoitsoriginalposition  
  6. **/  
  7. functionremoveToInsertLater(element){  
  8. varparentNode=element.parentNode;  
  9. varnextSibling=element.nextSibling;  
  10. parentNode.removeChild(element);  
  11. returnfunction(){  
  12. if(nextSibling){  
  13. parentNode.insertBefore(element,nextSibling);  
  14. }else{  
  15. parentNode.appendChild(element);  
  16. }  
  17. };  

有了上面这个函数,现在我们就可以在一个不需要解析渲染的元素上面修改那些超链接了。这样只在移除和插入元素的时候各触发一次重解析。 

  1. functionupdateAllAnchors(element,anchorClass){  
  2. varinsertFunction=removeToInsertLater(element);  
  3. varanchors=element.getElementsByTagName('a');  
  4. for(vari=0,length=anchors.length;i
  5. anchors[i].className=anchorClass;  
  6. }  
  7. insertFunction();  
  8. }  
  9.  

【编辑推荐】

  1. 揭露JavaScript DOM操作基本原则
  2. 减少浏览器重解析 JavaScript DOM操作优化方案
  3. JavaScript获取HTML DOM节点元素详解
  4. JavaScript和DOM轻松实现数据访问
  5. HTML DOM与XML DOM的区别与联系探究

 

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...