JavaScript性能优化几点小窍门

1. 避免阻塞渲染:

页面渲染会因JavaScript执行而暂停,尤其是内联脚本和document.write()的使用。

<script>document.write("Today is " + new Date().toDateString());</script>

2. 慎用with语句:它增加作用域链搜索,影响性能。

和函数类似 ,with语句会创建自己的作用域,因此会增加其中执行的代码的作用域链的长度,由于额外的作用域链的查找,在with语句中执行的代码肯定会比外面执行的代码要慢,在能不使用with语句的时候尽量不要使用with语句。

// 使用with语句前
with(someObject) {
    console.log(property);
}

// 使用with语句后
console.log(someObject.property);

3. 优化数据访问:局部变量访问速度优于对象属性和数组元素,多次访问应使用局部变量缓存。

const array = someObject.array;
for (let i = 0; i < array.length; i++) {
    console.log(array[i]);
}

4. 减少全局变量访问:局部变量访问速度比全局变量快。

function search() {
    const location = window.location;
    alert(location.href);
}

5. 合理放置脚本标签:置于HTML底部以减少对页面渲染的阻塞。

优化 JavaScript 的首要规则:将脚本放在底部。

<body>
    <!-- 页面内容 -->
    <script src="script.js"></script>
</body>

6. 慎用闭包:它们可能导致作用域链中的性能问题,特别是在循环中。

闭包基本上被认为是JavaScript中的new,当我们定义一个即时函数的时候,我们就使用了闭包,比如:

document.getElementById('foo').onclick = function(ev) { };

7. 优化循环:避免在循环中重复声明和检查变量。

for (let i = 0; i < 10; i++) {
    // 循环体
}

8. 使用XHR加载脚本:可异步下载并执行脚本,避免阻塞。

var xhr = new XMLHttpRequest();
xhr.open("GET", "script.js", true);
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
        eval(xhr.responseText);
    }
};
xhr.send(null);

9. 减少NodeList访问:缓存NodeList结果并减少访问次数。

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

 var images = document.getElementsByTagName('img');
        for (var i = 0, len = images.length; i < len; i++) {}

编写JavaScript的时候一定要知道何时返回NodeList对象,这样可以最小化对它们的访问:
1、进行了对getElementsByTagName()的调用
2、获取了元素的childNodes属性
3、获取了元素的attributes属性
4、访问了特殊的集合,如document.forms、document.images等等
要了解了当使用NodeList对象时,合理使用会极大的提升代码执行速度

10. 避免与null比较:使用typeof或instanceof进行类型检查。

由于JavaScript是弱类型的,所以它不会做任何的自动类型检查,
所以如果看到与null进行比较的代码,尝试使用以下技术替换:

1、如果值应为一个引用类型,使用instanceof操作符检查其构造函数

2、如果值应为一个基本类型,作用typeof检查其类型

3、如果是希望对象包含某个特定的方法名,
则使用typeof操作符确保指定名字的方法存在于对象上

11. 尊重对象所有权:不要修改不属于你的对象。

因为JavaScript可以在任何时候修改任意对象,这样就可以以不可预计的方式覆写默认的行为,
所以如果你不负责维护某个对象,它的对象或者它的方法,那么你就不要对它进行修改,具体一点就是说:
1、不要为实例或原型添加属性
2、不要为实例或者原型添加方法
3、不要重定义已经存在的方法
4、不要重复定义其它团队成员已经实现的方法,永远不要修改不是由你所有的对象,
你可以通过以下方式为对象创建新的功能:
	1、创建包含所需功能的新对象,并用它与相关对象进行交互
	2、创建自定义类型,继承需要进行修改的类型,然后可以为自定义类型添加额外功能

12. 避免循环引用:可能导致内存泄漏。

下面2种方法可以解决循环引用:
1、置空dom对象

function init() {
    var el = document.getElementById('MyElement');
    el.onclick = function () {
    //……
    }
}
init();
//可以替换为:
function init() {
    var el = document.getElementById('MyElement');
    el.onclick = function () {
    //……
    }
    el = null;
}
init();

2、构造新的context

function init() {
    var el = document.getElementById('MyElement');
    el.onclick = function () {
    //……
    }
}
init();
//可以替换为:
function elClickHandler() {
//……
}
function init() {
    var el = document.getElementById('MyElement');
    el.onclick = elClickHandler;
}
init();

13. 字符串连接优化:使用模板字符串或数组join方法。

如果要连接多个字符串,应该少使用+=,如

s+=a;

s+=b;

s+=c;

应该写成s+=a + b + c;
而如果是收集字符串,比如多次对同一个字符串进行+=操作的话,
最好使用一个缓存,使用JavaScript数组来收集,最后使用join方法连接起来。

14. 类型转换:直接使用适当的类型,避免不必要的转换。

var myVar = "3.14159",
str = "" + myVar, //转成string类型
i_int = ~ ~myVar,  //转成int类型  
f_float = 1 * myVar,  //转成浮点型  
b_bool = !!myVar,  /*  转成布尔类型,任何长度不为0的字符串和除0以外的任何数字都为真*/
array = [myVar];  //  转成数组

如果定义了toString()方法来进行类型转换的话,推荐显式调用toString(),因为内部的操作在尝试所有可能性之后,会尝试对象的toString()方法尝试能否转化为String,所以直接调用这个方法效率会更高。

15. 使用字面量创建对象和数组。

var aTest = new Array(); //替换为
var aTest = [];

var aTest = new Object; //替换为
var aTest = {};

var reg = new RegExp(); //替换为
var reg = /../;

//如果要创建具有一些特性的一般对象,也可以使用字面量,如下:
var oFruit = new Object;
oFruit.color = "red";
oFruit.name = "apple";

//前面的代码可用对象字面量来改写成这样:
var oFruit = { color: "red", name: "apple" };

16. 避免双重解释:如使用eval或Function构造器。

如果要提高代码性能,尽可能避免出现需要按照JavaScript解释的字符串,也就是
1、尽量少使用eval函数
使用eval相当于在运行时再次调用解释引擎对内容进行运行,需要消耗大量时间,而且使用Eval带来的安全性问题也是不容忽视的。
2、不要使用Function构造器
不要给setTimeout或者setInterval传递字符串参数。

var num = 0;
 setTimeout('num++', 10);
 
//可以替换为:
var num = 0;
function addNum() {
    num++;
}
setTimeout(addNum, 10);

17. 简化否定检测:使用逻辑非操作符。

if(oTest != '#ff0000'){
    //do something
}
if(oTest != null){
//do something
}
if(oTest != false){
  //do something
}
//虽然这些都正确,但用逻辑非操作符来操作也有同样的效果:
if(!oTest){
//do something
}

18. 释放对象引用:帮助垃圾回收。

在rich应用中,随着实例化对象数量的增加,内存消耗会越来越大。所以应当及时释放对对象的引用,让GC能够回收这些内存控件。

对象:obj = null

对象属性:delete obj.myproperty

数组item:使用数组的splice方法释放数组中不用的item

19. 性能注意事项:使用原生方法,优化switch语句,利用位运算符,巧用布尔运算符。

1、尽量使用原生方法

2、switch语句相对if较快

通过将case语句按照最可能到最不可能的顺序进行组织

3、位运算较快

当进行数字运算时,位运算操作要比任何布尔运算或者算数运算快

4、巧用||和&&布尔运算符

function eventHandler(e) {
    if (!e) e = window.event;
}
//可以替换为:
function eventHandler(e) {
    e = e || window.event;
}
-------------------------------------------------------------
if(myobj){
    doSomething(myobj);
}
//可以替换为:
myobj && doSomething(myobj);

20. 代码风格:使用清晰的代码风格,避免不必要的类型声明和赋值。

1、每条语句末尾须加分号

在if语句中,即使条件表达式只有一条语句也要用{}把它括起来,以免后续如果添加了语句之后造成逻辑错误

2、使用+号时需谨慎

JavaScript 和其他编程语言不同的是,在 JavaScript 中,’+'除了表示数字值相加,字符串相连接以外,还可以作一元运算符用,把字符串转换为数字。因而如果使用不当,则可能与自增符’++’混淆而引起计算错误

var valueA = 20;
var valueB = "10";
alert(valueA + valueB);     //ouput: 2010 
alert(valueA + (+valueB));  //output: 30 
alert(valueA + +valueB);    //output:30 
alert(valueA ++ valueB);     //Compile error

3、使用return语句需要注意

一条有返回值的return语句不要用()括号来括住返回值,如果返回表达式,则表达式应与return关键字在同一行,以避免压缩时,压缩工具自动加分号而造成返回与开发人员不一致的结果

function F1(){
    var valueA = 1;
    var valueB = 2;
    return valueA + valueB;
}
function F2() {
    var valueA = 1;
    var valueB = 2;
    return
    valueA + valueB;
}
alert(F1());  //输出: 3 
alert(F2());  //输出: undefined

==和===的区别
避免在if和while语句的条件部分进行赋值,如if (a = b),应该写成if (a == b),但是在比较是否相等的情况下,最好使用全等运行符,也就是使用===和!==操作符会相对于==和!=会好点。==和!=操作符会进行类型强制转换。

ar valueA = "1";
var valueB = 1;
if(valueA == valueB) {
    alert("Equal");
}
else{
    alert("Not equal");
}
//输出: "Equal"
if(valueA === valueB){
    alert("Equal");
}
else{
    alert("Not equal");
}
//输出: "Not equal"

不要使用生偏语法
函数返回统一类型
总是检查数据类型
何时用单引号,何时用双引号
建议在HTML中使用双引号,在JavaScript中使用单引号,但为了兼容各个浏览器,也为了解析时不会出错,定义JSON对象时,最好使用双引号。

21. 部署:使用JSLint验证,压缩JS文件,统一UTF-8编码,将JavaScript代码放在外部文件中,并在HTML底部引用。

1、用JSLint运行JavaScript验证器来确保没有语法错误或者是代码没有潜在的问题。
2、部署之前推荐使用压缩工具将JS文件压缩。
3、文件编码统一用UTF-8。
4、JavaScript 程序应该尽量放在 .js 的文件中,需要调用的时候在 HTML 中以 <script src=”filename.js”> 的形式包含进来。JavaScript 代码若不是该 HTML 文件所专用的,则应尽量避免在 HTML 文件中直接编写 JavaScript 代码。因为这样会大大增加 HTML 文件的大小,无益于代码的压缩和缓存的使用。另外,<script src=”filename.js”> 标签应尽量放在文件的后面,最好是放在标签前。这样会降低因加载 JavaScript 代码而影响页面中其它组件的加载时间。

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**之火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值