高性能WEB开发:DOM编程

  我们知道,DOM是用于操作XML和HTML文档的应用程序接口,用脚本进行DOM操作的代价很昂贵。有个贴切的比喻,把DOM和Javascript(这里指ECMscript)各自想象为一个岛屿,它们之间用收费桥梁连接,ECMAscript每次访问DOM,都要途径这座桥,并交纳“过桥费”,访问DOM的次数越多,费用也就越高。因此,推荐的做法是尽量减少过桥的次数,努力待在ECMAscript岛上。我们不可能不用DOM的接口,那么,怎样才能提高程序的效率?

1、DOM访问与修改

  访问DOM元素是有代价的,修改元素代价更是昂贵,因为它会导致浏览器重新计算页面的几何变化(重排和重绘)。

  当然最坏的情况是在循环中访问或者修改元素,看下面两段代码:

var times = 15000;
// code1
console.time(1);
for(var i = 0; i < times; i++) {
  document.getElementById(‘myDiv1‘).innerHTML += ‘a‘;
}
console.timeEnd(1);

// code2
console.time(2);
var str = ‘‘;
for(var i = 0; i < times; i++) {
  str += ‘a‘;
}
document.getElementById(‘myDiv2‘).innerHTML = str;
console.timeEnd(2);

  结果第一次运行的时间居然是第二次的千倍!

1: 2846.700ms           2: 1.046ms

  第一段代码的问题在于,每次循环迭代,该元素都会被访问两次:一次读取innerHTML的值,另一次重写它,也就是说,每次循环都在过桥!结果充分表明,访问DOM的次数越多,代码的运行速度越慢。因此,能减少DOM访问的次数则尽量减少,尽量留在ECMAscript这端处理。

2、HTML集合 & 遍历DOM

操作DOM另一个耗能点就是遍历DOM,一般我们会收集一个HTML集合,比如用getElementsByTagName(),或者用document.links等,我想大家对此都不陌生。收集的结果是一个类似数组的集合,它处于一种“实时状态”实时存在,这意味着当底层文档对象更新时,它也会自动更新。怎么讲?很简单举个栗子:

<body><ul id="fruit"> <li> apple </li> <li> orange </li> <li> banana </li> </ul></body>
<script. type="text/javascript">
var lis = document.getElementsByTagName(‘li‘);
var peach = document.createElement(‘li‘);
peach.innerHTML = ‘peach‘;
document.getElementById(‘fruit‘).appendChild(peach);
console.log(lis.length); // 4
</script>

  而这正是低效之源!很简单,跟数组的优化操作一样,缓存个length变量就ok了(读取一个集合的length比读取一个普通数组的lengh要慢很多,因为每次都要查询)。

var lis0 = document.getElementsByTagName(‘li‘);
var str0 = ‘‘;
for(var i = 0; i < lis0.length; i++) {
    str0 += lis0[i].innerHTML;
}

var lis1 = document.getElementsByTagName(‘li‘);
var str1 = ‘‘;
for(var i = 0, len = lis1.length; i < len; i++) {
    str1 += lis1[i].innerHTML;
}

  我们看看性能提升能有多少?1: 0.974ms        2: 0.664ms

  当集合的长度大的时候,性能提升还是很明显的。

3、最后介绍两个原生DOM方法,querySelector()和querySelectorAll()

  相信大家都不陌生,前者返回一个数组(注意,它们的返回值不像HTML集合一样会动态变化),后者返回匹配的第一个元素。好吧,其实并不是所有时候它的性能都优于前者的HTML集合遍历。

var lis1 = document.getElementsByTagName(‘li‘);
var lis2 = document.querySelectorAll(‘li‘);
// 1: 0.038ms
// 2: 3.957ms

  但是因为它是类似CSS的选择方法,所以在做组合选择的时候,效率会提升,又方便。比如做如下的组合查询:

var elements = document.querySelectorAll(‘#menu a‘);
var elements = document.querySelectorAll(‘div.warning,div.notice‘);
时间: 2024-12-26 21:40:44

高性能WEB开发:DOM编程的相关文章

高性能WEB开发:重排与重绘

DOM编程可能最耗时的地方,重排和重绘. 1.什么是重排和重绘 浏览器下载完页面中的所有组件--HTML标记.JavaScript.CSS.图片之后会解析生成两个内部数据结构--DOM树和渲染树. DOM树表示页面结构,渲染树表示DOM节点如何显示.DOM树中的每一个需要显示的节点在渲染树种至少存在一个对应的节点(隐藏的DOM元素disply值为none 在渲染树中没有对应的节点).渲染树中的节点被称为"帧"或"盒",符合CSS模型的定义,理解页面元素为一个具有填充

高性能WEB开发(11) - flush让页面分块,逐步呈现

在处理比较耗时的请求的时候,我们总希望先让用户先看到部分内容,让用户知道系统正在进行处理,而不是无响应.一般大家在处理这种情况,都使用ajax,先把html输出到客户端,然后再用ajax取加载比较耗时的资源.用ajax麻烦的地方是增加了请求数,而且需要写额外的js代码.和js调用的请求接口. 正对这种情况,还有一种处理方法,就是让response分块编码进行传输.response分块编码,可以先传输一部分不需要处理的html代码到客户端,等其他耗时代码执行完毕后再传输另外的html代码. 分块编

高性能WEB开发(6) - web性能测试工具推荐

WEB性能测试工具主要分为三种,一种是测试页面资源加载速度的,一种是测试页面加载完毕后页面呈现.JS操作速度的,还有一种是总体上对页面进行评价分析,下面分别对这些工具进行介绍,如果谁有更好的工具也请一起分享下. Firebug: Firebug 是firefox中最为经典的开发工具,可以监控请求头,响应头,显示资源加载瀑布图: HttpWatch : httpwatch 功能类似firebug,可以监控请求头,响应头,显示资源加载瀑布图.但是httpwatch还能显示GZIP压缩信息,DNS查询

高性能WEB开发 - 图片篇

一.缩小图片大小 当图片很多的时候,减少图片大小是提高下载速度最直接的方法. 1. 使用PNG8代替GIF(非动画图片),因为PNG8在效果一样的情况,图片大小比GIF要小. 2. 用fireworks处理PNG图片,在我们产品中很多PNG图片是美工直接用photoshop导出的, 后来让美工用fireworks处理PNG(大概的方式是选择保存为PNG8,删除背景色). 处理后100K的图片大小基本减少了3/4,但图片质量也会有少许降低,要看自己是否能接受. 3. 使用Smush.it(http

高性能Web开发系列

1. 高性能WEB开发基础 http://www.uml.org.cn/net/201404225.asp 2. 高性能WEB开发进阶(上) http://www.uml.org.cn/net/201404235.asp 3. 高性能WEB开发进阶(下) http://www.uml.org.cn/net/201404245.asp 4. 高性能WEB开发经验分享 http://www.uml.org.cn/net/201404255.asp 高性能Web开发系列

高性能Javascript(2) DOM编程

第三部分 DOM编程 文档对象模型(DOM)是一个独立于语言的,使用XML和HTML文档操作的应用程序接口(API).在浏览器中,主要与HTML文档打交道,在网页应用中检索XML文档也很常见.DOM APIs主要用于访问这些文档中的数据.尽管DOM是与语言无关的API,在浏览器中的接口却是以JavaScript实现的.客户端大多数脚本程序与文档打交道,DOM就成为JavaScript代码日常行为中重要的组成部分. 2.1 DOM Access and Modification  DOM访问和修改

高性能JavaScript(DOM编程)快速响应的用户界面

浏览器UI线程 用于执行JavaScript代码和更新界面的进程被称为 “浏览器UI线程” . UI线程的工作基于一个简单的队列系统,任务会被保存到队列中直到线程空闲,一旦空闲队列就被重新提取出来运行.这些任务要么是运行JavaScript代码,要么是执行UI更新,包括重绘和重排.浏览器每一次执行JavaScript代码或者响应用户事件,都可能会导致一个或多个任务加入队列. function handleClick(){ //创建div元素 var div = document.createEl

静态Web开发 DOM

四章 Dom 1节dom中的顶级对象 dom(文档对象模型)js最终是要操作html页面,让html变成DHtml,而操作Html页面就要用到DOMDOM可以吧Html页面模拟成一个对象,如果js只是执行一些计算.循环等操作,而不能操作Html也就失去了它存在的意义 window.onload=function(){ //1 window.fm.btn.onclick=function(){ //window.id 的方式获得元素(如果嵌套很多次,会非常麻烦) alert('大家好!'); }

高性能WEB开发 为什么要减少请求数,如何减少请求数!

http请求头的数据量 [声明] 转载  原文出处:http://www.blogjava.net/BearRui/. 谢谢我们先分析下请求头,看看每次请求都带了那些额外的数据.下面是监控的google的请求头 Host www.google.com.hk User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTBDFff GTB7.0 Accept