JavaScript提升性能的常用技巧总结【经典】


Posted in Javascript onJune 20, 2016

本文讲述了JavaScript提升性能的常用技巧。分享给大家供大家参考,具体如下:

1.注意作用域

随着作用域链中的作用域数量的增加,访问当前作用域以外的变量的时间也在增加.访问全局变量总是要比访问局部变量慢,因为要遍历作用域链
1). 避免全局查找   将在一个函数中会多次用到的全局对象存储为局部变量总是没错的.

2). 避免 with 语句  with会创建自己的作用域,因此会增加其中执行代码的作用域链的长度.

2.选择正确的方法

性能问题的一部分是和用于解决问题的算法或者方法有关的.

1). 避免不必要的属性查找

在计算机科学中,算法的复杂度是使用O符号来表示的.最简单,最快捷的算法是常数值,即O(1).之后,算法变得越来越复杂并花更长时间执行.常用的JavaScript算法类型有:

常数 : 不管有多少值,执行的时间都是恒定的.一般表示简单值和存储在变量的值.

对数 : 总的执行时间和值的数量相关,但是要完成算法并不一定要获取每个值. 例如:二分查找

线性 : 总执行时间和值的数量直接相关. 例如 :遍历某个数组中的所有元素

平方 : 总执行时间和值的数量有关,每个值至少要获取n次.例如:插入排序

立方:  总执行时间和值的数量有关,每个值至少要获取n的平方次

使用变量和数组要比访问对象上的属性更有效率.对象上的任何属性的查找都要比访问变量或者数组花更长时间,因为必须在原型链中对拥有该名称的属性进行一次搜索.

一般来讲,只要能减少算法的复杂度,就要尽可能减少.尽可能多地使用局部变量将属性查找替换为值查找.进一步讲,如果即可以用数字化的数组位置进行访问,也可以使用命名属性(诸如NodeList对象),那么使用数组位置.

2). 优化循环

a. 减值迭代   在很多情况下,从最大值开始,在循环中不断减值的迭代器更加高效.
b. 简化终止条件   由于每次循环过程都会计算终止条件,所以必须保证它尽可能快.
c. 简化循环体   循环体是执行最多的,所以要确保其被最大限度地优化.确保没有某些可以被很容易移出循环的密集计算.
d. 使用后测试循环   最常用的for循环和while循环都是前测试循环.而如do-while这种后测试循环,可以避免最初终止条件的计算,因此更快. 

3). 展开循环   当循环的次数是确定的,消除循环并使用多次函数调用往往更快.如著名的Duff装置

4). 避免双重解释

当JavaScript 代码想解析 JavaScript 的时候就会存在双重解释的惩罚.如下例:

eval("alert('Hello world!')");
//某些代码求值

修正:

alert('Hello world');
var sayHi = new Function("alert('Hello world!')");

修正:

var sayHi = function(){
  alert("Hellow world!');
};
setTimeout("alert('Hellow world!')",500);

修正:

setTimeout(function)({
   alert('Hellow world!');
},500);

5). 其他方法

原生方法较快--只要有可能,使用原生方法而不是自己用JavaScript重写一个.原生方法是用诸如C/C++之类的编译型语言写出来的,所以要比JavaScript的快很多很多.JavaScript中最容易被忘记的就是可以在Math对象中找到的复杂的数学运算;这些方法要比任何用JavaScript写的同样方法,如正弦,余弦快的多.

Switch 语句较快--如果有一系复杂的if-else语句,可以转换成单个switch语句则可以得到更快的代码.还可以通过将case语句按最可能的到最不可能在顺序进行组织,来进一步优化switch语句.

位运算符较快--当进行数学运算的时候,位运算操作要比任何布尔运算或者算数运算快.选择性的用位运算换算数运算可以极大提升复杂计算的性能.诸如取模,逻辑与和逻辑或都可以考虑用位运算来替换.

3 . 最小化语句数

1). 多个变量声明

如:

//4个语句---很浪费
var count = 5;
var color = "blue";
var values = [1,2,3];
var now = new Date();

优化:

var count = 5,
color = "blue", 
values = [1,2,3],
noiw = new Date();

在大多数情况下这种优化都非常容易做,并且要比单个变量分别声明快很多.

2). 插入迭代值

如:

var name = values[i];
i++;

优化:

var name = values[i++];

3). 使用数组和对象字面量

如:

var values = new Array(); --->  var values = [];
var obj = new Object(); ---> var obj = {};

4. 优化DOM交互

1). 最小化现场更新

一旦你需要访问DOM部分是已经显示的页面的一部分,那么你就是在进行一个现场更新.之所以叫现场更新,是因为需要立即(现场)对页面对用户的显示进行更新.不管是插入单个字符,还是移除整个片段,都有一个性能惩罚,因为浏览器要重新计算无数尺寸以进行更新.

例:

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

这样添加10个项目,这个操作总共要完成20个现场更新.  下面用创建文档碎片的方法改进:

var list = document.getElementById("myList");
var fragment = document.createDocumentFragment();
for(var i = 0; i < 10;i++){
   fragment.appendChild(item);
   item.appendChild(document.createTextNode("Item "+i));
}
list.appendChlid(fragment);

在这个例子中只有一次现场更新,它发生在所有项目都创建好之后.文档碎片用作一个临时的占位符,放置新创建的项目.然后使用appendChild()将所有项目添加到列表用.记住,当给appendChild()传入文档碎片时,只有碎片中的子节点被添加到目标,碎片本身不会被添加的.

一旦需要更新DOM,请考虑使用文档碎片来构建DOM结构,然后将其添加到现存的文档中.

2). 使用innerHTML

有两种在页面上创建DOM节点的方法:使用诸如createElement(),appendChild()之类的DOM方法,以及使用innerHTML对于小的DOM更改而言,两种方法效率都差不多.而对于大的DOM更改,使用innerHTML要比使用标准DOM方法创建同样的DOM结构快很多.同样,一次使用innerHTML比多次使用innerHTML也要快相当多.

3). 使用事件代理(简,略)

4). 注意NodeList

最小化访问NodeList的次数可以极大的改进脚本的性能.

发生以下情况时会返回NodeList对象:

a. 进行了对getElementsByTagName()的调用
b. 获取了元素的childNodes属性
c. 获取了元素的attributes属性
d. 访问了特殊的集合,如document.forms  ,  document.images等等

要了解当使用NodeList对象时,合理使用会极大提升代码执行速度.

前面介绍的 函数节流  也是很重要的一方面。特别是多重循环,非常耗性能时,此方法很有用的。

PS:对于javascript进行压缩,减少代码体积也是提升javascript性能的有效途径。这里就为大家推荐2款非常实用的压缩工具:

JavaScript压缩/格式化/加密工具:
http://tools.3water.com/code/jscompress

jsmin在线js压缩工具:
http://tools.3water.com/code/jsmincompress

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
jQuery LigerUI 使用教程入门篇
Jan 18 Javascript
JavaScript获取多个数组的交集简单实例
Nov 11 Javascript
jquery取子节点及当前节点属性值的方法
Sep 09 Javascript
JavaScript onkeypress事件入门实例(按下或按住一个键盘按键)
Oct 17 Javascript
js鼠标滑过图片震动特效的方法
Feb 17 Javascript
浅析JavaScript中作用域和作用域链
Dec 06 Javascript
初识 Vue.js 中的 *.Vue文件
Nov 22 Javascript
Vue2 轮播图slide组件实例代码
May 31 Javascript
详解如何实现Element树形控件Tree在懒加载模式下的动态更新
Apr 25 Javascript
layui 实现自动选择radio单选框(checked)的方法
Sep 03 Javascript
详解vue-router 动态路由下子页面多页共活的解决方案
Dec 22 Javascript
vue实现可移动的悬浮按钮
Mar 04 Vue.js
使用jQuery给input标签设置默认值
Jun 20 #Javascript
js中获取时间new Date()的全面介绍
Jun 20 #Javascript
AngularJs Javascript MVC 框架
Jun 20 #Javascript
jQuery 限制输入字符串长度
Jun 20 #Javascript
JavaScript函数节流概念与用法实例详解
Jun 20 #Javascript
Angular的Bootstrap(引导)和Compiler(编译)机制
Jun 20 #Javascript
jquery通过name属性取值的简单实现方法
Jun 20 #Javascript
You might like
Terran历史背景
2020/03/14 星际争霸
用PHP读注册表
2006/10/09 PHP
关于PHP中的Class的几点个人看法
2006/10/09 PHP
随时给自己贴的图片加文字的php代码
2007/03/08 PHP
php 应用程序安全防范技术研究
2009/09/25 PHP
PHP 面向对象程序设计(oop)学习笔记 (五) - PHP 命名空间
2014/06/12 PHP
php获取网页中图片、DIV内容的简单方法
2014/06/19 PHP
PHP的Yii框架入门使用教程
2016/02/15 PHP
Yii2实现让关联字段支持搜索功能的方法
2016/08/10 PHP
php实现银联商务公众号+服务窗支付的示例代码
2019/10/12 PHP
PHP vsprintf()函数格式化字符串操作原理解析
2020/07/14 PHP
js 字符串转化成数字的代码
2011/06/29 Javascript
js生成缩略图后上传并利用canvas重绘
2014/05/15 Javascript
JS模拟实现Select效果代码
2015/09/24 Javascript
JS实现图片的不间断连续滚动的简单实例
2016/06/03 Javascript
javascript创建含数字字母的随机字符串方法总结
2016/08/01 Javascript
Vuejs在v-for中,利用index来对第一项添加class的方法
2018/03/03 Javascript
微信小程序实现折叠展开效果
2018/07/19 Javascript
微信小程序实现页面下拉刷新和上拉加载功能详解
2018/12/03 Javascript
小程序rich-text组件如何改变内部img图片样式的方法
2019/05/22 Javascript
easyUI使用分页过滤器对数据进行分页操作实例分析
2020/06/01 Javascript
Vue实现Header渐隐渐现效果的实例代码
2020/11/05 Javascript
Python使用matplotlib实现的图像读取、切割裁剪功能示例
2018/04/28 Python
Python用5行代码写一个自定义简单二维码
2018/10/21 Python
python实现朴素贝叶斯算法
2018/11/19 Python
python fuzzywuzzy模块模糊字符串匹配详细用法
2019/08/29 Python
Python 中pandas索引切片读取数据缺失数据处理问题
2019/10/09 Python
python3 re返回形式总结
2020/11/20 Python
阿玛尼美妆加拿大官方商城:Giorgio Armani Beauty加拿大
2017/10/24 全球购物
前台接待岗位职责
2013/12/03 职场文书
文明餐桌活动方案
2014/02/11 职场文书
舞蹈专业大学生职业规划范文
2014/03/12 职场文书
伦敦奥运会的口号
2014/06/21 职场文书
学生抄袭作业的检讨书
2014/10/02 职场文书
工作自我评价范文
2019/03/21 职场文书
2019个人工作态度自我评价
2019/04/24 职场文书