博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《高性能javascript》读书笔记:第三章 DOM编程
阅读量:7155 次
发布时间:2019-06-29

本文共 4002 字,大约阅读时间需要 13 分钟。

 

文档对象模型(DOM)用于操作XML和HTML文档的应用程序接口,与语言无关。

各浏览器中DOM和javascript独立实现,如表

浏览器 DOM javascript
IE Trident(mshtml.dll) JScript(jscript.dll)
Safari Webkit中的WebCore JavaScriptCore(最新版叫SquirrelFish)
Google Webkit中的WebCore V8
Firefox Gecko SpiderMonkey(最新版叫TraceMonkey)

DOM和javascript(ECMAScript)通过接口连接,所以访问和修改DOM会影响性能。

 

innerHTML: 

document.getElementById("aaa").innerHTML="
"

DOM:         

var tr = document.CreateElement("tr");       var td=document.CreateElement("td");       td.appendChild(document.createTextNode('aaa'));       tr.appendChild(td);                  td=document.createElement("td");       var a=document.createElement("a");       a.setAttribute("href","http://baidu.com");       td.appendChild(a);       tr.appendChild(td);

上面两种方式生成html的性能比较,innerHTML的优势在老版本浏览器中很明显,只有基于WebKit内核的新版浏览器中DOM方法略胜。

更新一大段HTML推荐使用innerHTML

 

创建重复的元素时,第一个用document.createElement,后面的用 tr.cloneNode(false)速度会略快一点点

 

HTML集合包括:

document.getElementsByName();

document.getElementsByClassName();

document.getElementsByTagName();

document.images

document.links

document.forms

document.forms[0].elements

 

html集合是类似数组的列表(没有push()或slice()之类的方法所以不是数组)。但是能以数字索引的方式访问列表中的元素,还有length属性。

 

html集合非常低效,因为它是实时和文档保持一致的,包括访问length属性都会重复执行查询的过程。

比如下面的就是一个死循环

var alldivs=document.getElementsByTagName("div"); for(var i=0;i

一般解决上面性能慢的方式,是设置一个集合,并把它拷贝到一个数组中,下面的可为通用转换函数:

function toArray(coll){
for(var i=0, a=[],len=coll.length;i

在DOM中爬行,也就是从某个DOM元素开始操作周围的元素,或者递归查找所有的子节点,建议使用nextSibling,别用childNodes

 

下面表格中建议用第一列的DOM属性,

性能好的属性名 被替换的属性名
children childNodes
childElementCount childNodes.length
firstElementChild firstChild
lastElementChild lastChild
nextElementSibling nextSibling
previousElementSibling previousSibling

querySelectorAll方法:可进行组合查询。此种方法反回的是数组对象,不是html集合,因此返回的节点不会对应实时的文档结构,避免了html集合引起的性能问题。支持的浏览器有IE8,Firefox3.5,Safari3.1,Chrome1,Opera.

var elements = document.querySelectorAll("#menu a");

 

浏览器下载完页面以后生成两个结构  DOM树和渲染树(渲染树中的节点称帧frames或盒boxes)

按css模型的定义,页面元素为具有填充(padding),边距(margins),边框(borders)和位置(position)的盒子。

浏览器显示的顺序:下载页面--构建DOM树和渲染树--显示(绘制paint)页面元素

当DOM的变化影响了元素的几何属性(宽和高),浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树,即重排reflow,重排后会重新绘制受影响部分到屏幕中,即重绘repaint

重排影响性能。重排在下面情况时会发生:添加或删除可见的DOM元素,元素位置改变,元素尺寸改变,内容改变,页面渲染器初始化,浏览器窗口尺寸改变。

浏览器通过队列化优化重排。但是下面的属性和方法需要返回最新的布局信息,所以会触发重排。

offsetTop,offsetLeft,offsetWidth,offsetHeigth

scrollTop,scrollLeft,scrollWidth,scrollHeigth

clientTop,clientLeft,clientWidth,clientHeigth

getComputedStyle()   //这个是在IE、Opera中

在修改样式的过程中,最好避免使用上面列出的属性。

 

减少能引起重排的操作,合并所有的改变最后一次处理,可使用cssText属性实现或改变css的class名称实现

var el=document.getElementById("mydiv"); el.style.cssText="border-left:1px;border-right:2px;padding:5px;";
el.className="active";//改变类时需要检查级联样式,有轻微的性能影响

排量修改DOM的三种方案(推荐第二种) :目的是减少改变DOM的次数提高性能

1,通过改变display属性,临时从文档中移除,做了所有的修改以后再恢复。这样最多只会更改DOM两次。

var ul=document.getElementById("mylist"); ul.style.display="none"; //这里可进行对mylist的任意多次修改 ul.style.display="block";

2,在文档之外更新一个文档片断,然后把它附加到原始列表中。只触发一次重排。

var fragment=document.createDocumentFragment(); //这里可进行任意修改 document.getElementById("mylist").appendChild(fragment);//附加一个片断到节点中时,实际上被添加的是该片断的子结点。

3,为需要修改的节点创建一个备份,修改完后再替代旧的节点。

var old=document.getElementById("mylist"); var clone=old.cloneNode(true); //修改 old.parentNode.replaceChild(clone,old);

 

少使用:hover这个CSS伪选择器。特别是在IE8中最影响性能。

 

页面中存在大量元素,并且其中很多元素都需要绑定事件处理器(onclick等),可能会影响性能。可以在用冒泡方式在父级元素捕获。

document.getElementById("parent").οnclick=function(e){
//假设parent是父元素,它含有很多子元素。   //浏览器target   e=e||window.event;   var target =e.target||e.srcElement;   var pageid,hrefparts;   //只关心hrefs,非链接点击则退出。这个示例中只演示捕获parent中子节点是A标签的情况   if(target.nodeName!=="a"){
    return;   }   //从链接中找出页面ID   hrefparts=target.href.split("/");   pageid=hrefparts[hrefparts.length-1];   pageid=pageid.replace(".html","");   //更新页面   ajaxRequest("xhr.php?page="+id,updatePageContents);   //浏览器组织默认行为并取消冒泡   if(typeof e.preventDefault==="function"){
    e.preventDefault();     e.stopPropagation();   }else{
    e.returnValue=false;     e.cancelBubble=true;   } };

 

 

转载于:https://www.cnblogs.com/liuchunmang/archive/2012/01/10/2318439.html

你可能感兴趣的文章
浅谈程序猿的职业规划,看你如何决定自己的未来吧。
查看>>
IOS debug网络PonyDebugger 实践篇
查看>>
Android 如何预置APK M
查看>>
《JAVA与模式》之命令模式
查看>>
U盘FAT32转换NTFS格式
查看>>
【iCore3双核心板】发布 iCore3 应用开发平台硬件原理图
查看>>
PhysX学习笔记(4): 动力学(3) Joint
查看>>
C#中海量数据的批量插入和更新
查看>>
使用C++判断两矩形是否相交
查看>>
Yahoo!网站性能最佳体验的34条黄金守则——服务器
查看>>
界面视频通话视频通话最新谍报
查看>>
我的第一次面试经历
查看>>
表格行mouse经过时高亮显示
查看>>
【GoLang】GoLang 官方 对 error 处理的意见
查看>>
MVC 5使用ViewData(对象)显示数据
查看>>
错误处理与调试 (14 章 )
查看>>
ytu 1985:C语言实验——保留字母(水题)
查看>>
java常见错误--Access restriction: The type BASE64Encoder
查看>>
Mybatis 对象关系映射之一对多 and 多对多 关系
查看>>
周下载量过 200 万的 npm 包被注入恶意代码,Vue等 项目恐受影响
查看>>