用脚本进行DOM操作的代价很昂贵,它是富Web应用中最常见的性能瓶颈。

浏览器中的DOM:天生就慢

  DOM(文档对象模型)是独立于语言的,但在浏览器中的接口是用JavaScript实现的。两个相互独立的功能只要通过接口彼此连接,就会产生消耗。

  访问DOM元素是有代价的,修改元素则更甚。

 function innerHTMLLoop(){
for(var count = 0; count < 15000; count++){
document.getElementById('here').innerHTML += 'a';//糟糕透顶,难道要重复15000次 访问+重写 吗?
}
}

  减少访问DOM的次数,把运算留在ECMAScript这一端处理

 function innerHTMLLoop(){
var content = '';
for(var count = 0; count < 15000; count++){
content += 'a';
}
document.getElementById('here').innerHTML += content;//一次 访问+重写,比起上面,简直好太多
}

昂贵的集合

  document.getElementsByTagName()

  document.getElementsByClassName()

  document.images

  document.links

  document.forms

  以上方法和属性的返回值为HTML集合对象,类似数组(不是数组,没有push slice等方法),提供了length属性,可以以数字索引访问其中的元素

  重点是,HTML集合对象以一种『假定实时态』实时存在,一直与文档保持着连接,当底层文档对象更新时,它也会更新。这就是低效之源。

  

 var alldivs = document.getElementsByTagName('div');
for(var i = 0; i < alldivs.length; i++){ //length一直在变,一个意外的死循环
document.body.appendChild(document.createElement('div'));
}
  • 将集合拷贝至数组,访问数组较快(但这也会因为额外的步骤多遍历一次集合,评估而定)
  • 缓存length属性
  • 多次访问同一个集合元素时使用局部变量缓存

只取得元素节点

只取得元素节点 不建议使用
children childNodes
childElementcount

childNodes.length

firstElementChild

firstChild

lastElementChild lastChild
nextElementSibling nextSibling
priviousElementSibling priviousSibling

选择器API

  querySelectorAll()

  使用CSS选择器作为参数,返回Nodelist类数组对象,不会返回HTML集合,因此避免了HTML集合引起的性能(和潜在逻辑)问题

 var elements1 = document.getElementById('menu').getElementsByTagName('a');//id为menu的下面的所有<a>
var elements2 = document.querySelectorAll('#menu a');//同上,对比之下,querySeletorAll较简洁 var errs = document.querySelectorAll('div.warning, div.notice');//类为warning和notice的<div>

高性能JavaScript P35-50

DOM编程的性能问题的更多相关文章

  1. 性能优化之数据存储&DOM编程

    多读书多看报 数据存储 ·在javascript中,数据存储的位置会对代码整体性能产生重大的影响. ·数据存储共有4种方式:字面量.变量.数组.对象成员.   ·要理解变量的访问速度,就要理解作用域. ...

  2. JavaScript性能优化 DOM编程

    最近在研读<高性能JavaScript>,在此做些简单记录.示例代码可在此处查看到. 一.DOM 1)DOM和JavaScript 文档对象模型(DOM)是一个独立于语言的,用于操作XML ...

  3. JS性能优化——DOM编程

    浏览器中的DOM  天生就慢 DOM是个与语言无关的API,它在浏览器中的接口却是用JavaScript实现的.客户端脚本编程大多数时候是在个底层文档打交道,DOM就成为现在JavaScript编码中 ...

  4. 读书笔记:JavaScript DOM 编程艺术(第二版)

    读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...

  5. 《高性能javascript》 领悟随笔之-------DOM编程篇(二)

    <高性能javascript> 领悟随笔之-------DOM编程篇二 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...

  6. 《高性能javascript》 领悟随笔之-------DOM编程篇

    <高性能javascript> 领悟随笔之-------DOM编程篇一 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...

  7. 高性能JavaScript笔记一(加载和执行、数据访问、DOM编程)

    写在前面 好的书,可能你第一遍并不能领会里面的精魂,当再次细细品评的时候,发现领悟的又是一层新的含义 (这段时间,工作上也不会像从前一样做起来毫不费力,开始有了新的挑战,现在的老大让我既佩服又嫉妒,但 ...

  8. 160826、浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘

    一.浏览器渲染页过程描述   1.浏览器解析html源码,然后创建一个DOM树. 在DOM树中,每一个HTML标签都有一个对应的节点(元素节点),并且每一个文本也都有一个对应的节点(文本节点). DO ...

  9. 浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘。

    一.浏览器渲染页过程描述 1.浏览器解析html源码,然后创建一个DOM树. 在DOM树中,每一个HTML标签都有一个对应的节点(元素节点),并且每一个文本也都有一个对应的节点(文本节点). DOM树 ...

随机推荐

  1. Android 底部弹出Dialog(横向满屏)

    项目中经常需要底部弹出框,这里我整理一下其中我用的比较顺手的一个方式(底部弹出一个横向满屏的dialog). 效果图如下所示(只显示关键部分): 步骤如下所示: 1.定义一个dialog的布局(lay ...

  2. Android 5.X新特性之为RecyclerView添加HeaderView和FooterView

    上一节我们讲到了 Android 5.X新特性之RecyclerView基本解析及无限复用 相信大家也应该熟悉了RecyclerView的基本使用,这一节我们来学习下,为RecyclerView添加H ...

  3. MVP解析

    一套可以直接复制使用的MVP框架 通过对MVP设计模式学习,对MVP也有了一个初步的认识,以登录Login模块为例,封装MVP如下: package com.example.administrator ...

  4. 【代码笔记】iOS-验证手机号,邮箱,车牌号是否合法

    一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. ...

  5. swift-元组

    元组: 将多个相同或者不同类型的值用一个小括号括起来就是一个元组.元组和结构体很像,实际上元组是复合类型.小括号内可以写任意类型,如果不定义类型,可以根据数据自动判断推算出类型 省略了类型 let p ...

  6. java 中时间的比较 用compareTo方法

    //compareTo 方法  是对象比较 大于 1   等于  返0  小于  返 -1 列 Date  dat1=new Date(); Date  dat2=new Date(); int va ...

  7. 从Sql Server表中随机获取一些记录最简单的方法

    * FROM test ORDER BY NewID() 注意,使用时,请将‘test’改为真实的表名.

  8. T-SQL 将动态SQL的结果集赋值到变量

    1. 使用输出变量 ) ) DECLARE @counts int SET @city = 'New York' SET @sqlCommand = 'SELECT @cnt=COUNT(*) FRO ...

  9. T-SQL 如何获取一个表的列名

    方法1: exec sp_columns [{table_name}],[{schema_name}] 方法2: SELECT * FROM syscolumns WHERE id=OBJECT_ID ...

  10. monkeyrunner之坐标或控件ID获取方法-续

    在之前的文章中,介绍过控件坐标和ID的获取方法,这里,我们再介绍一个新的工具-uiautomatorviewer. Uiautomatorviewer是Android sdk自带的工具,位置在sdk/ ...