• 1.避免全局查找:
 <script type="text/javascript">
function updateUI(){
var imgs=document.getElementsByTagName("img");
for(var i=0,len=imgs.length;i<len;i++){
imgs[i].title=document.title+"image"+i;
}
var msg=document.getElementById("msg");
msg.innerHTML="updated!"
}
updateUI();
</script>

可能优化脚本性能最重要的就是:注意全局查找。使用全局变量和函数的开销比局部变量更大,因为涉及作用域链上的查找。以上例子包含了三个对全局document对象的引用。当图片特别多时,会造成对此作用域链上的查找。在这里,可以创建一个指向document对象的局部变量。来改进性能。如下:

 1 <script type="text/javascript">
2 function updateUI(){
3 var doc=document;
4 var imgs=doc.getElementsByTagName("img");
5 for(var i=0,len=imgs.length;i<len;i++){
6 imgs[i].title=doc.title+"image"+i;
7 }
8 var msg=doc.getElementById("msg");
9 msg.innerHTML="updated!"
10 }
11 updateUI();
12 </script>

在这里,首先将document对象保存在本地的doc变量中,后边的引用均为该本地变量,现在函数只有一次全局查找,肯定更快。

  • 2.避免with语句

和函数相同,with会创建自己的作用域。从而增加其中执行代码的作用域链长度。由于额外作用域的查找,在with语句中执行的代码肯定比外面执行的代码要慢。如下:

     function updateBody(){
with(document.body){
alert(tagName);
innerHTML="hello world!";
}
}
updateBody();

改进:虽然使用with语句可以创建document.body的作用域,在内部直接调用它的方法和属性即可。但可以使用局部变量来达到相同的效果。

     function updateBody(){
var body=document.body;
alert(body.tagName);
body.innerHTML="hello world!";
}
updateBody();

以上均为:需要不断查询作用域链,从而造成开销。可通过创建局部变量的方法。

  • 选择正确方法
  1. 对象属性查找:使用变量和数组要比访问对象上的属性更高效。对象上的属性查找花费时间比较长,因需要在原型链中对该属性进行一次搜索。所以:一旦多次用到对象属性,应该将其存储在局部变量中。
  2. 优化循环:   (1).减值迭代  (2)简化终止条件  (3)简化循环体   (4)使用后测试循环

(1):大多数循环使用从0开始、增加到某个特定值的迭代器。在很多情况下,从最大值开始,在循环中不断减值的迭代器更高效。

(2):由于每次循环都会计算终止条件,所以必须保证终止条件的简单,避免属性查找和其他操作。

(3):确保循环体的优化。

(4):使用后测试优化---最常使用for循环和while循环 都属于前测试循环。而do-while这种后测试循环,避免终止条件的计算,运算更快。

  • 最小化语句数
  1. 多个变量声明:变量声明只用一个var语句,之后用逗号隔开。比单个变量分别声明要快很多。
  2. 插入迭代值 :当使用迭代值时(在不同位置进行增加和减少的值),尽可能合并语句。如:
        var name=values[i];
    i++; 更正为:
    var name=values[i++];
  3. 使用数组和对象字面量:

  • 优化DOM交互
  1. 最小化现场更新:一旦访问的DOM部分是已经显示的页面的一部分,那么就要进行现场更新。即需要对页面对用户的显示进行更新。例如:

        var list=document.getElementById("list");
    for(var i=0;i<10;i++){
    var item=document.createElement("li");
    list.appendChild(item);
    item.appendChild(document.createTextNode("item"+i));
    }

因为每次添加项目时都要有两个现场更新,添加<li>元素和添加文本节点。

解决方法:第一种,将列表从页面移除,最后进行更新,最后将列表插入原位置。不理想:每次页面更新会有闪烁。

第二种,使用文档片段来构建DOM结构,接着将其添加到list元素。片段本身不会被添加,片段中的子节点会被添加到目标。

  •      var list=document.getElementById("list"),
    fragment=document.createDocumentFragment(),
    item,
    i;
    for(i=0;i<10;i++){
    item=document.createElement("li");
    fragment.appendChild(item);
    item.appendChild(document.createTextNode("item"+i));
    }
    list.appendChild(fragment);

2.使用innerHTML。创建一个字符串然后一次性调用innerHTML要比调用innerHTML多次快的多。

3.使用事件代理。页面上的事件处理程序的数量和页面响应用户交互的速度之间有个负相关,为了减少这种惩罚,最好事件代理:利用事件冒泡,任何可以冒泡的事件都不仅仅可以可以在事件目标上进行处理,目标的任何组件节点也能处理。

4.注意HTMLCollection。任何时候访问HTMLCollection,不管属性还是方法,都是在文档上进行查询,开销比较昂贵。。要尽量最小化访问。优化的重点部分是循环。如:

     var image=document.getElementsByTagName("img"),
i,
len;
for(var i=0,len=image.length;i<len;i++){
//处理
}

优化的关键:长度length存入变量len,而不是每次都去访问HTMLCollection的length属性。在循环中使用HTMLCollection时,下一步应该是获取要使用项目的引用,避免在循环体内多次调用HTMLCollection。

     var image=document.getElementsByTagName("img"),
i,
len;
for(var i=0,len=image.length;i<len;i++){
img=image[i];
}

这样,在循环中就没有理由再去访问image的HTMLCollection。

注意:在编写JavaScript时,要清楚何时返回HTMLCollection对象。这样就可以最小化的访问。以下情况下均返回HTMLCollection对象:

  1. 调用getElementsByTagName()
  2. 获得元素的childNodes属性。
  3. 获取元素的attributes属性。
  4. 访问特殊集合,如document.forms、document.images等。
 

性能(js)的更多相关文章

  1. 转:HTML5标准与性能之四:asm.js

    HTML5标准与性能之四:asm.js Cong Liu (Intel) 于 星期五, 24/05/2013 - 01:13 提交 之前的几篇文章分别介绍了WebWorkers.Typed Array ...

  2. JavaScript代码规范和性能整理

    性能 Js在性能方面有多要注意的地方: 避免全局查找 Js性能优化最重要的就是注意全局查找,因为作用域的查找是先找局部作用域在没有找到之后在去上一级作用域查找直到全局作用域,所以全局作用域查找的性能消 ...

  3. ionic react-native和native开发移动app那个好

    ionic react-native和native开发移动app那个好 ? 移动端开发如何选型?这里介绍一下我眼中的ionic,react-native,native 三种移动端开发选型对比.欢迎大家 ...

  4. 专题:点滴Javascript

    JS#38: Javascript中递归造成的堆栈溢出及解决方案 JS#37: 使用console.time测试Javascript性能 JS#36: Javascript中判断两个日期相等 JS#3 ...

  5. ionic react-native和native开发移动app到底那个好

    ionic react-native和native开发移动app那个好 ? 移动端开发如何选型?这里介绍一下我眼中的ionic,react-native,native 三种移动端开发选型对比.欢迎大家 ...

  6. 五年 Web 开发者 star 的 github 整理说明

    欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:樊东东 前端从业几年,积累了不少github开源库. 有时候想查阅以前star的库,但不好找,github大多库都是英文说明,对中文 ...

  7. ChakraCore/JSRT使用问题汇总

    QQ交流群:523723780(ChakraCore) ChakraCore是什么? 一个微软开源的,用于Windows IE/Edge内核的高效JS脚本引擎. 前不久微软开源了ChakraCore, ...

  8. web优化 js性能高级篇

    今天我们继续上一个阶段关于web的性能优化,如何对js高级进行优化 (1)闭包 何为闭包; 一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.  我认 ...

  9. 【前端性能】必须要掌握的原生JS实现JQuery

    很多时候,我们经常听见有人说jquery有多快多快.在这个各种类库满天飞的时候,不得不说的是,能有原生JS快吗? 是的,明显原生JS要更快,因为诸如JQuery这样的库必须要兼容各种浏览器和低版本和许 ...

  10. Ionic中使用Chart.js进行图表展示以及在iOS/Android中的性能差异

    Angular Chart 简介 在之前的文章中介绍了使用 Ionic 开发跨平台(iOS & Android)应用中遇到的一些问题的解决方案. 在更新0.1.3版本的过程中遇到了需要使用图表 ...

随机推荐

  1. java.lang.StringIndexOutOfBoundsException: String index out of range: 0

    hibernet 报错 java.lang.StringIndexOutOfBoundsException: String index out of range: 0 处理方法  数据表字段为char ...

  2. Excel 如何快速切换到最后一行

    1.快速切换到最后一行,是ctrl+↓箭头(来源:百度) 2. http://www.office68.com/excel/22936.html     一.定位到第一个单元格        方法1: ...

  3. fiddler常用操作之断点

    fiddler常用操作断点 标签(空格分隔): fiddler断点 一.断点: 1.为什么要打断点呢? 比如一个购买的金额输入框,输入框前端做了限制100-1000,那么我们测试的时候,需要测试小于1 ...

  4. 10大H5前端框架(转)

    10大H5前端框架 作为一名做为在前端死缠烂打6年并且懒到不行的攻城士,这几年我还是阅过很多同门从知名到很知名的各种前端框架,本来想拿15-20个框架来分享一下,但在跟几个前辈讨教写文章的技巧时果断被 ...

  5. 【Nodejs】Node.js(Express)の環境構築

    [Express]の環境 参考URL:http://expressjs.com/en/starter/generator.html ①Node.jsの準備 (参考URL:https://www.cnb ...

  6. KNN算法应用

    import numpy as np# 运算符模块,这里主要用来排序 import operator import matplotlib.pylab as plt def create_dataset ...

  7. Array 遍历数组

    public static void main(String args){ int a[][] = new int[3][4]; for(int i=0;i<a.length;i++){ for ...

  8. oracle数据库查询出多条数据,合并,之后列转行

    select B.enterprise_code, B.enterprise_name, sum(B.h0_overnum) AS over00, sum(B.h1_overnum) AS over0 ...

  9. Jmeter cookie不兼容问题

    历史脚本,今天准备执行测试,报出这种错误 解决方案:HTTP Cookie Manager里的 Cookie Policy 由rfc2109设置为兼容模式(Compatibility) 参考:http ...

  10. stm32 开发中startup.s文件中常见的命令功能

    由于C的普及以及编译器的发展,越来越多的软件工程师在编程时很少有机会接触到汇编语言.在ARM的开发中,我们不可避免的会遇到启动文件的编写,在KEIL环境中一般采用了startup.s的文件作为启动代码 ...