dom操作中的js优化
频繁地对于DOM进行操作的很是损耗性能,但在富网页应用中我们编写脚本无可避免地要跟DOM打交道,到底怎么才能优化这个性能瓶颈呢,大致从以下三种情况去考虑:
访问和修改DOM元素
修改DOM样式,会造成页面的重绘和重新排版
通过DOM事件处理程序来响应用户
访问和修改DOM元素
在浏览器中,DOM的实现和Javascript的实现通常是保持相互独立的。下面了解一下主流浏览器的渲染引擎和JS引擎:
浏览器 | 渲染引擎(内核) | JS引擎 |
---|---|---|
IE | mshtml.dll(Trident) | JScript |
Chrome | WebCore(WebKit) | V8 |
FireFox | Gecko | Spider-Monkey/TraceMonkey |
Safari | WebCore(WebKit) | JavaScriptCore/SquirrelFish |
访问DOM元素的代价就是交一次“桥费”,修改DOM元素则会导致浏览器重新计算页面的几何变化。如果是循环修改DOM元素,其代价可想而知。如下代码:
function innerHTMLLoop1(){
for(var count=0;count<10000;count++){
document.getElementById("test").innerHTML +="增加内容";
}
}
在这段代码中,每循环一次都要对DOM元素访问两次:一次是读取innerHTML属性的内容,另一次是把新的内容写入它。所以一个优化的办法就是使用一个局部变量存储更新后的内容,在循环结束时再一次性写入:
function innerHTMLLoop2(){
var content ="";
for(var count=0;count<10000;count++){
content +="增加内容";
}
document.getElementById("test").innerHTML += content ;
}
更新页面的两种方法性能比较:innerHTML和DOM方法(如document.creatElment)。性能差别不大,innerHTML好一些,使用简单嘛。另外还有一个更新页面的方法是节点克隆--element.cloneNode()。
HTML集合的操作
HTML集合是用于存放DOM节点引用的类数组对象。可通过下列的方法或属性得到这样的集合:
document.getElementsByName()
document.getElementsByTagName()
document.getElementsByClassName()
document.images 返回对文档中所有 Image 对象引用
document.links 返回对文档中所有 Area 和 Link 对象引用
document.forms 返回对文档中所有 Form 对象引用
document.forms[0].elements 返回对文档中第一个表单的所有元素
HTML集合会实时查询文档信息,也就是说当你要用到这个集合时,它会自动查询文档的最新信息。请看如下代码:
var allDivs = document.getElementsByTagName("div");
for(var i=0;i<allDivs.length;i++){
document.body.appendChild(document.createElement("div"));
} 例如像上面的那段代码其实是个死循环,因为每一次访问div集合的length属性,它都会重新计算文档中的div元素数目。这就是html集合低效率的来源。要改进代码就用一个局部变量保存div集合的length属性:
for(var i=0, len=allDivs.length; i<len; i++){...}
var len = 集合.length;
//HTML集合转换成数组
function toArray(coll){
for(var a=[], i=0, len=coll.legnth; i<len; i++){
a[i] = coll[i];
}
return a;
}
//使用
var coll = document.getElementsByTagName("div");
var divs = toArray(coll);
有人可能会问,这样多用了一个数组副本到底值不值得?这个倒是要看情况吧。不过另外一种选择,使用局部变量:
function loopColletion(){
var coll = document.getElmentsByTagName("div");
var len = coll.length;
var el = null;
for(var i = 0; i<len; i++){
el = coll[i];
//然后访问局部变量el
}
}
许多浏览器提供了API函数返回元素节点,这些API都是原生的,所以可用的话就尽量用。下图列举了一些DOM的属性:
上图列举的所有属性能被FF,safari,chrome,opera所支持,ie6-8只支持children。
遍历children比childNodes更快,因为集合项少了。HTML源码中的空格实际上是文本节点,但他们不包含在children中。
另外还有两个比较好的选择器API:document.querySelectorAll()和document.querySelector()。前者接收一个CSS选择器字符串参数并返回一个NodeList类数组对象而不是返回HTML集合,后者只返回符合查询条件的第一个节点。很遗憾IE6、7不支持这两个API。
dom操作中的js优化的更多相关文章
- js优化原则
首先,与其他语言不同,JS的效率很大程度是取决于JS engine的效率.除了引擎实现的优劣外,引擎自己也会为一些特殊的代码模式采取一些优化的策略.例如FF.Opera和Safari的JS引擎,都对字 ...
- 从字符串拼接看JS优化原则
来自知乎的问题:JavaScript 怎样高效拼接字符串? 请把以下用于连接字符串的JavaScript代码修改为更高效的方式: var htmlString ='< div class=”co ...
- 前端js优化方案(连续更新)
最近在读<高性能javascript>,在这里记录一下读后的一些感受,顺便加上自己的一些理解,如果有兴趣的话可以关注的我的博客http://www.bloggeng.com/,我会不定期发 ...
- js优化 前端小白适用
注意啦,前端初学者适合看的js优化,当你看我的优化认为太low,那么恭喜,你已经脱离初学者了. 首先这边我觉得分享的还是以js为主,前端性能优化,我认为最重要的还是js,因为js是一门解释型的语言,相 ...
- 前端js优化方案(一)
最近在读<高性能javascript>,在这里记录一下读后的一些感受,顺便加上自己的一些理解,如果有兴趣的话可以关注的我的博客http://www.bloggeng.com/,我会不定期发 ...
- DOM操作的性能优化
DOM操作的真正问题在于 每次操作都会出发布局的改变.DOM树的修改和渲染. React解决了大面积的DOM操作的性能问题,实现了一个虚拟DOM,即virtual DOM,这个我们一条条讲. 所以关于 ...
- JavaScript性能优化篇js优化
JavaScript性能优化篇js优化 随着Ajax越来越普遍,Ajax引用的规模越来越大,Javascript代码的性能越来越显得重要,我想这就是一个很典型的例子,上面那段代码因为会被频繁使用, ...
- require.js优化器
项目发布前,require.js优化器可以合并require.js各个模块. 官网: http://requirejs.org/docs/optimization.html 安装 npm instal ...
- 关于js优化和css优化
css优化: 1.css代码的压缩. 2.css文件的合并. 3.不滥用float,因为float在渲染时计算量比较大,所以尽量减少使用float. 4.避免在html标签中写style属性. js优 ...
随机推荐
- 压力测试工具:tsung
http://tsung.erlang-projects.org/user_manual/introduction.html#what-is-tsung
- java正则表达式语法详解及其使用代码实例
原文地址 译者序(下载代码) 正则表达式善于处理文本,对匹配.搜索和替换等操作都有意想不到的作用.正因如此,正则表达式现在是作为程序员七种基本技能之一*,因此学习和使用它在工作中都能达到很高的效率. ...
- jquery单选框 复选框表格高亮 选中
单选框: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/T ...
- android如何实现开机自动启动Service或app
第一步:首先创建一个广播接收者,重构其抽象方法 onReceive(Context context, Intent intent),在其中启动你想要启动的Service或app. import and ...
- Thread message loop for a thread with a hidden window? Make AllocateHwnd safe
Thread message loop for a thread with a hidden window? I have a Delphi 6 application that has a thre ...
- 常用CSS3效果:用text-shadow做CSS3 文字描边
思路: 利用CSS3的text-shadow属性,对文字的四个边均用阴影. 最终效果: 单纯的为了实现效果.未作任何美化. 实现代码: HTML: <div>文字描边效果</div& ...
- 解决从内部存储设备安装apk提示Permission Denied
做应用商店,下载apk,考虑一种情况,如果没有sd卡的情况下就将apk下载到 Internal Cache目录下. 下载都正常,但是在安装的时候提示Permission Denied /data/da ...
- Task could not find "AxImp.exe" using the SdkToolsPath "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\"
本机v7.0A目录里没有AxImp.exe,无奈只能去官网下了个V7.1的. 安装完V7.1后,去“开始-所有程序-Microsoft Windows SDK v7.1”里找到Windows SDK ...
- 【M17】考虑使用缓式评估
1.缓式评估其实就是拖延战术,直到逼不得已的时候才去计算.缓式评估的使用场景有: 2.引用计数,考虑String,String是一个内含char指针(char指针以'\0'结束)的资源管理类,正常情况 ...
- 64位ubuntu下装32位软件
本帖最后由 wuy069 于 2013-10-25 12:28 编辑 很多软件只有32位的,有的依赖32位库还挺严重的:从ubuntu 13.10已经废弃了ia32-libs,但可以使用多架构,安装软 ...