前端JS优化技巧你值得拥有
JavaScript 你是否一直在使用,忙于开发而没有关注于代码优化,下面将介绍一些技巧,这些技巧可以帮助你写出干净优质的 JavaScript 代码,使 JavaScript代码运行更快,性能更优。
下面具体来看看有哪些技巧?
1. 延迟(异步)加载
js的延迟加载有助于提高页面的加载速度,所以尽量延迟加载。
- 给 setTimeout()和 setInterval()传递函数参数而不是字符串参数
1)使用setTimeout延迟方法
目的:延迟加载js代码,给网页加载留出时间
<script type="text/javascript"> function login(){ $.post("/login",{name:name,pwd:password},function(){ alert("hahha"); }) } $(function (){ //延迟2秒 setTimeout("login()",2000); }) </script>
2. 多条件时优先选择 Map
如果要判断多个条件时,使用Map
代替 switch/if-else,筛选会快得多
。
switch (color) { case 'blue': return 'A' case 'red': return 'A' case 'black': return 'B' }
或
if (color === 'blue' || color === 'red') return 'A' else return 'B'
上面可以使用 Map
来代替
const m = new Map([ ['blue','A'], ['red', 'A'], ['black', 'B'] ]); return m.get(color);
3. 使用临时变量保存属性
对于每个属性,JavaScript引擎都将遍历整个对象链,直到找到匹配项。 如果使用不当,将会占用大量资源,影响应用程序的性能。
使用临时变量来保存属性,能够减少性能损耗。
不推荐:
const page = pageResponse.data.page.name + pageResponse.data.page.num
推荐:
const page1 = pageResponse.data.page const page = page1.name + page1.num
4. 避免内存泄漏
JavaScript 中垃圾回收是自动执行的,但某些情况下也会出现内存泄漏。
常见会带来内存泄露的原因:
1)意外的全局变量
全局变量声明周期很长,知道页面关闭,依然存在,全局变量的内存一直不会被回收,当全局变量使用不当,没有及时回收(置为null)或拼写错误将某个变量挂载到全局变量时,就出现内存泄漏。
function foo() { this.name = "xiaowang"; } // Foo 调用自己,this 指向了全局对象(window) // 而不是 undefined foo();
这样无意中一个意外的全局变量就被创建了,为了阻止这种错误发生,在你的Javascript文件最前面添加 'use strict;'
这开启了解析JavaScript的阻止意外全局的更严格的模式。
2)循环引用
要解决循环引用的问题,最好是在不使用它们的时候手动将它们设为null。
function func() { let obj1 = {}; let obj2 = {}; obj1.a = obj2; // obj1 引用 obj2 obj2.a = obj1; // obj2 引用 obj1 //此时 设为null,可以防止循环引用,引用计数为0 obj1 = null; obj2 = null; }
3)闭包
闭包是 JavaScript 开发的一个关键方面:匿名函数可以访问父级作用域的变量。
最重要的事情是,闭包的作用域一旦创建,它们有同样的父级作用域,作用域是共享的。
闭包会造成对象引用的生命周期脱离当前函数的上下文,如果闭包如果使用不当,可以导致环形引用,类似于死锁,只能避免,无法发生之后解决,即使有垃圾回收也还是会内存泄露。
4)被遗忘的计时器
我们经常在使用到 setInterval/setTimeout
,之后忘记清理。
var someResource = getData(); setInterval(function() { var node = document.getElementById('Node'); if(node) { // 处理 node 和 someResource node.innerHTML = JSON.stringify(someResource)); } }, 1000);
if
内引用了 someResource
变量,如果没有清除 setInterval/setTimeout
的话someResource
也得不到释放;同时,someResource
如果存储了大量的数据,也是无法被回收的。所以用完记得去 clearInterval/clearTimeout
。
5)脱离DOM引用
每个页面上的 DOM 都是占用内存的,下面例子 虽然在页面上移除了A,但是内存指向换为了 refA
,内存占用还是存在的。添加:refA = null
,手动释放这个内存。
var refA = document.getElementById('A'); document.body.removeChild(refA); // #A不能回收,因为存在变量refA对它的引用。将其对#A引用释放,但还是无法回收 //添加null refA = null;
5. if多条件判断
把多个值放在一个数组中,然后调用数组的 includes 方法
// 冗余 if (x === 'a' || x === 'b' || x === 'c' || x ==='d') {} // 简洁 if (['a', 'b', 'c', 'd'].includes(x)) {}
6. 不要使用 with() 语句
with()语句将会在作用域链的开始添加额外的变量,当任何变量需要被访问的时候,JavaScript引擎都需要先扫描with()语句产生的变量,然后才是局部变量,最后是全局变量。
7. 使用直接量
创建新对象和数组时使用对象直接量和数组直接量。它们比非直接量形式创建和初始化更快。
//创建数组 var a = []; //创建对象 var b = {};
8. 对象属性的顺序
始终以相同的顺序实例化对象属性,以便可以共享隐藏类和随后优化的代码。
9. for、while、do-while
for、while、do-while 循环的性能特性相似,快慢没有必要比较。除非你要迭代遍历一个属性未知的对象,否则不要使用 for-in 循环。
10. 简化switch
将条件保存在键值对象中,并根据条件来调用它们。
// 冗余 switch (a) { case 1: b(); break; case 2: b1(); break; } // 简洁 var a = { 1: b1, 2: b2 }; a[hh] && a[hh]();
内容如果有错,欢迎纠正 ~~~