您的位置:首页 > Web前端 > JavaScript

不知道JavaScript代码怎么优化?25条优化建议~

2019-01-10 11:35 281 查看

JS代码优化那点事
我们知道在web项目里,JavaScript作用越来越大,占用量越来越大,web应用性能问题JavaScript性能不足占了很大一部分原因,尤其是JavaScript脚本还会影响到浏览器的渲染,所以优化Javascript代码显得尤为重要。
参考链接:https://mp.weixin.qq.com/s?__biz=MzU5MTAwMjA0NA==&mid=2247486643&idx=1&sn=12a8cbca2d2d5ffff01e2f20bcffe269&chksm=fe34ec60c9436576b086577c4f7dd180cb5d28dfe28398b6bc401e70495c11fcef667dbd079b&mpshare=1&scene=23&srcid=0108xKKVDZ4P7PplNYWkYbwL#rd

1. JS的 <script> 标签位置最好位于body底部,因为浏览器无法知道js中是否会向HTML中添加或移除元素,所以会停下页面渲染的处理等待脚本下载执行。

<html>
<head>
<title>Source Example</title> <!--低效率的JS脚本位置 -->
<script type="text/javascript" src="script1.js"></script>
<script type="text/javascript" src="script2.js"></script>
<script type="text/javascript" src="script3.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css"></head>
<body>
<p>Hello world!</p>
</body>
</html>

脚本和样式文件的下载过程如下,可以看到第一个JS脚本阻塞了其他文件的下载,从 IE 8、Firefox 3.5、Safari 4 和 Chrome 2 开始都允许并行下载 JavaScript 文件,但是不可否认的是,JS还是会阻塞图片文件样式文件等资源的下载。

因此最好将JS脚本位置放到body底部如下:

<head>
<title>Source Example</title>
<link rel="stylesheet" type="text/css" href="styles.css"></head>
<body>
<p>Hello world!</p>
<!-- Example of efficient script positioning -->
<script type="text/javascript" src="script1.js"></script>
</body>
</html>

2. 不要使用with()语句
with语句会增加作用域链的长度。JavaScript每次会先扫描with语句产生的变量,其次是局部变量,最后是全局变量。

with (a.b.c.d) { //不推荐
property1 = 1;
property2 = 2;
}
//可以替换为:  var obj = a.b.c.d;
obj.property1 = 1;
obj.property2 = 2;

3. 当频繁访问一个对象属性或者是数组元素时,将其用变量表示。
JavaScript访问速度 变量和数值性能差异不大 > 访问对象属性和数组元素
4. 避免全局查找
查找局部变量速度大于查找全局变量,当函数内用到全局对象时,建议用局部变量来存储该全局变量

function test() {   //不推荐
console.log(window.location.href);
}
//建议更改为
function test() {
var location = window.location;
console.log(location.href);
}

5. 数字变字符串用 “”+
“”+的效率 > String() >.toString() >new String()
6. 考虑用clone来代替createElement
当需要在HTML中创建节点时,若是页面中存在样板节点可以用cloneNode()方法可以减少设置元素属性的次数,createElement()需要设置多次元素属性会降低效率。

*7. 小心使用闭包 *
在循环中最好不要滥用闭包
8. 循环的优化
对于for(var i=0;i<length;i++)这种循环语句可以考虑将控制条件和控制变量合并在一起。可以考虑用do while()代替
var x=10; do{…} while(x–)
9. 不要在循环中直接使用node.length属性作为控制条件

var images = document.getElementsByTagName('img');
//不建议i < images.length
for (var i = 0;  i < images.length; i++) { }
//可修改为
for (var i = 0, len = images.length;  i < images.length; i++) { }

10. 避免与null进行比较
1> 如果值应为一个引用类型,使用instanceof操作符检查其构造函数
2> 如果值应为一个基本类型,作用typeof检查其类型
3> 如果是希望对象包含某个特定的方法名,则使用typeof操作符确保指定名字的方法存在于对象上

11. 避免循环引用

function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {  //…… }
}
init();

init在执行的时候,有个当前上下文context,context引用了el,el引用了function,function引用了context。形成了循环引用
解决方法1------制空DOM对象,将el置空,context中不包含对dom对象的引用,从而打断循环应用。

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

12. 字符串连接少用+=

s+=a;
s+=b;
s+=c;
改为   s+=a + b + c;

或者使用下述利用数组存储再利用join方法

var buf = [];
for (var i = 0; i < 100; i++) {
buf.push(i.toString());
}
var all = buf.join("");

13. 少用多个var声明变量
14. 使用直接量表示对象和数组或者正则

var aTest = new Array(); //替换为  var aTest = [];
var aTest = new Object; //替换为  var aTest = {};
var reg = new RegExp(); //替换为  var reg = /../;

15. 语句合并插入迭代器

var name=values[i];
i++;
改为一句
var name=values[i++]。

16. 少用eval()函数,不要使用Function构造器
17. 不要给setTimeout和setInterval传递字符串参数

var num = 0;
setTimeout('num++', 10); //这样的写法NO!!
//可以替换为:
var num = 0;
function addNum() {
num++;
}
setTimeout(addNum, 10);

18. if条件的否定语句可以缩短

if (oTest != '#ff0000') {  }
if (oTest != null) {   }
if (oTest != false) {}
//推荐!!!
if (!oTest) {   }

19. switch语句相对if较快
20. 位运算符进行数字运算比布尔运算和算术运算快

21. 巧用||和&&布尔运算

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

22. return语句需要注意的地方,返回的表达式要和return在一行

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

23. if语句在判断是否相等最好用全等符===或者不等符!==

24. 部署优化
1、用JSLint运行JavaScript验证器来确保没有语法错误或者是代码没有潜在的问

2、部署之前推荐使用压缩工具将JS文件压缩

3、文件编码统一用UTF-8

4、JavaScript 程序应该尽量放在 .js 的文件中,需要调用的时候在 HTML 中以

25. 使用XHR对象加载JavaScript脚本

var xhr = new XMLHttpRequest();
xhr.open("get", "script1.js", true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
var script = document.createElement ("script");
script.type = "text/javascript";
script.text = xhr.responseText;
document.body.appendChild(script);
}
}
};
xhr.send(null);

方法的优点是,可以下载不立即执行的 JavaScript 代码。由于代码返回在<script>标签之外(换句话说不受<script>标签约束),它下载后不会自动执行,这使得JS可以推迟执行,直到一切都准备好了。此方法最主要的限制是:JavaScript 文件必须与页面放置在同一个域内,不能从 CDN 下载(CDN 指”内容投递网络(Content Delivery Network)”,所以大型网页通常不采用 XHR 脚本注入技术。

[注: 后续如有其他优化会持续更新~]

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: