• 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. server安装

    ArcGIS Server Enterprise10 安装过程 1.ArcGIS Server Enterprise10 安装之前先检查下系统有没有安装IIS.右击电脑--管理--服务和应用程序--I ...

  2. waffit防火墙检测

    Waffit是一款Web应用防火墙检测工具,检测防火墙保护的站点是在渗透测试中非常重要的一步.如果没有对WAF进行配置,有时候可能存在漏洞.在渗透测试和风险评估中分析WAF也是非常重要的.通过编码攻击 ...

  3. Java闰年的计算,Calendar的用法

    Java闰年的计算,Calendar的用法 代码如下: package com.aaa.zuoye; import java.text.ParseException; import java.util ...

  4. Bootstrap 代码

    [Bootstrap 代码] Bootstrap 允许您以两种方式显示代码: 第一种是 <code> 标签.如果您想要内联显示代码,那么您应该使用 <code> 标签. 第二种 ...

  5. camstar --调用自定义的CDO报帐号没有执行权限的错误

    解决: 访问站点--〉modeling-->role-->Default Modeling-->筛选(如:modeling or Inquiry) 在右边找到自己定义的CDO(ser ...

  6. SQLMAP自动注入(四):枚举

    --privileges 查询权限 -U 指定用户 -CU指定当前用户 --schema 查询所有的数据 --batch 批处理,自动选择默认选项 --exclude-sysdbs 排除系统库的查询 ...

  7. Java 读取Excel 文件内容

    在一个项目中,有一个需求,是把excel文件的内容转换为xml格式展示.在学习如何操作的过程中,首先是如何获取excel文件,其中操作的代码如下: 1.首先是导入需要的 jar, 下载地址:https ...

  8. PHPActiveRecord 学习三

    #事务处理 注意事务 数据库要用InnoDB引擎 $c1 = User::connection(); try { //开启事务 $c1->transaction(); //sql语句 $sql ...

  9. cf-Round551-Div2-D. Serval and Rooted Tree(DP)

    题目链接:https://codeforces.com/contest/1153/problem/D 题意:有一棵树,给定结点数n,在每个结点上的操作(max:表示该结点的number为其孩子结点中的 ...

  10. laravel excel导出调节列宽度,对某列中数据颜色处理

    //$cellData 表格标题栏各名称数组 //$result 表格内容数组//$items getForDataTable得到的表格数据 $result = array_merge($cellDa ...