JS性能优化规范

1.作用域优化

随着作用域中的作用域数量的增加,访问当前作用域以外的变量的时间也在增加。所以访问全局变量总是比访问局部变量要慢,因为需要遍历作用域链。只要能减少花费在作用域链上的时间,就能增加脚本的整体性能。
所以尽量避免多次的全局查找(因为要逐层向上的作用域进行查找)

这个函数的时间复杂度是 (循环次数 * 查找到 document.title属性) 的次数,查找到 title 最坏的情况是遍历 document 的所有属性,最后才查找到 title 属性,而且每一次查找document都要进行多层的,逐层向上的作用域查找

优化前

function test() {
    var imgs = document.getElementByTagName("img");
    for(var i = 0, len = imgs.length; i < len; i++) {
        imgs[i].title = document.title + " image " + i;
    }
}

优化后

function test() {
    var title = document.title;
    var imgs = doc.getElementByTagName("img");
    for(var i = 0, len = imgs.length; i < len; i++) {
        imgs[i].title = title + " image " + i;
    }
}

2.属性查找优化

JS中访问变量或者数组都是 O(1) 操作,比访问对象上的属性更有效率,访问对象的属性的是一个 O(n) 的操作,最坏的情况是查找对象所有的属性后,才查找到。对象的任何属性查找要比访问变量花费更长的时间,因为必须在原型链中对拥有该名称的属性进行一次搜索,即属性查找越多,执行时间越长。所以针对需要多次用到的对象属性,应将其存储在局部变量,或者使用对象解构的方式存储起来。

这个函数在优化前的时间复杂度是 O(100 * n) ,因为一共 100 次循环,每次循环的时候都要去查找An属性,每次查找An属性都要遍历n次

优化前

let data = {
    A1: 1,
    A2: 2,
    A3: 3
    ...
    An: 100
}

function test(data) {
    for(let i = 0; i < 100; ++i) {
        console.log(data.An);
    }
}

test(data);

优化后

let data = {
    A1: 1,
    A2: 2,
    A3: 3
    ...
    An: 100
}

function test({A1, A2, A3...An}) {
    function test(data) {
    for(let i = 0; i < 100; ++i) {
        console.log(An);
    }
}

test(data);

优化后的时间复杂度就只为 O(100) 了,不需要每次循环中都去查找 An 属性的值,而是使用局部变量进行了存储。


3.循环优化

循环是编程中最常见的结构,优化循环是性能优化过程中很重要的一部分。一个循环的基本优化步骤如下:

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

简化终止条件——由于每次循环过程都会计算终止条件,故必须保证它尽可能快,即避免属性查找或其它 O(n) 的操作。

简化循环体——循环体是执行最多的,故要确保其被最大限度地优化。确保没有某些可以被很容易移出循环的密集计算。

4.其他优化

(1) switch语句较快——若有一系列复杂的if-else语句,可以转换成单个switch语句则可以得到更快的代码,还可以通过将case语句按照最可能的到最不可能的顺序进行组织,来进一步优化。

(2) 位运算较快——当进行数学运算时,位运算操作要比任何布尔运算或算数运算快。选择性地用位运算替换算数运算可以极大提升复杂计算的性能,诸如取模,逻辑与和逻辑或也可以考虑用位运算来替换。

(3) 字符串拼接,在 JS 中使用 “+” 号来拼接字符串效率是比较低的,因为每次运行都会开辟新的内存并生成新的字符串变量,然后将拼接结果赋值给新变量。与之相比更为高效的做法是使用 join 方法,因此当需要拼接的字符串较多的时候可以考虑用此方法。更提倡使用es6中的字符串模板,更加的快速高效。当然如果只是几个或者几十个字符串的拼接,那么使用哪种方法在性能上的区别都不大。

(4) 使用直接量,在某些浏览器上对象创建比直接量要耗时很多

var aTest = new Array(); //替换为
var aTest = [];
var aTest = new Object; //替换为
var aTest = {};
var reg = new RegExp(); //替换为
var reg = /../;
//如果要创建具有一些特性的一般对象,也可以使用字面量,如下:
var oFruit = new O;
oFruit.color = "red";
oFruit.name = "apple";
//前面的代码可用对象字面量来改写成这样:
var oFruit = { color: "red", name: "apple" };

(5) 最小化语句数

JS代码中的语句数量也会影响所执行的操作的速度,完成多个操作的单个语句要比完成单个操作的多个语句块快。故要找出可以组合在一起的语句,以减来整体的执行时间。这里列举几种模式

优化前

var i = 1;
var j = "hello";
var arr = [1,2,3];
var now = new Date();

优化后

var i = 1,
j = "hello",
arr = [1,2,3],
now = new Date();

优化前

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

优化后

var name = values[i++];

优化前

var a = new Array();
a[0] = 1;
a[1] = "hello";
a[2] = 45;

var o = new Obejct();
o.name = "bill";
o.age = 13;

优化后

var a = [1, "hello", 45];
var o = {
    name : "bill",
    age : 13
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值