JavaScript是几乎每个Web应用程序和基于Web的软件的重要组成部分。 JavaScript的客户端脚本功能可以使应用程序更具动态性和交互性, 但同时也增加了代码效率低下的可能性。因此, 编写不当的JavaScript可能难以确保所有用户的一致和健康的体验。
以下指南将启发你有关JavaScript性能问题的原因, 并提供一些优化JavaScript代码的最佳实践。
对document.getElementById()使用快速DOM遍历。
考虑到jQuery的可用性, 基于标记名, 类和CSS3的组合来生成高度特定的选择器要容易得多。你需要注意, 这种方法涉及多次迭代, 而jQuery循环遍历每个DOM元素并尝试找到匹配项。你可以通过按ID选择特定元素来提高DOM遍历速度。
例子:
// jQuery will need to iterate until it finds the right element
let button = jQuery( 'body div.dialog > div.close-button:nth-child(4)' )[0];
上面的代码利用了JQuery来操纵DOM, 这不是最好的选择, 因为不是这样做, 我们可以利用文档对象提供给我们的getElementById方法。
// A far more optimized way is to use document.getElementById.
let button = document.getElementById( 'dialog-close-button' );
延迟加载JavaScript
如果用户甚至在JavaScript接收之前就可以看到一些内容, 那么在加载样式表和JavaScript文件的位置上, 如果用户可以看到一些内容, 则可能会影响页面的感知速度, 这是一种更好的体验, 当浏览器遇到脚本标签时, 它会停止其工作如果我们将脚本放在页面顶部, 则完全可以下载并运行脚本, 这意味着它首先下载我们的JavaScript文件, 然后再下来解析我们的HTML正文, 这意味着在我们的脚本下载过程中, 用户没有任何内容现在来看我们是否将脚本放到页面底部, 而不是按时间放置, 我们的脚本开始加载, 页面上至少有一些内容使页面加载似乎更快。
一种替代方法是在script标签中使用defer。 defer属性指定脚本应在页面解析完成后执行, 但仅适用于外部脚本。
例子:
// placing script at the end:
<html>
<head>
<title>My Page</title>
</head>
<body>
<div id= "user-greeting" >Welcome back, user</div>
<script type= "text/javascript" src= "my-script.js" ></script>
</body>
</html>
// using defer:
<script type= "text/javascript" src= "path/to/script2.js" defer></script>
使用" switch"而不是冗长的" if-then-else"语句。
当你的代码库变大时, switch语句通常比一组嵌套的ifs更有效。这是因为在编译过程中可以更轻松地优化" switch"语句。
摆脱不必要的循环和在循环内进行的调用。
数组push()pop()和shift()指令由于其语言构造与其低级汇编语言对应项密切相关而具有最小的处理开销。
例子:
// push() method
let Animals = [ "Tiger" , "Giraffe" , "Horse" , "Deer" ];
Animals.push( "Zebra" );
console.log(Animals);
// pop() method
let Animals = [ "Tiger" , "Giraffe" , "Horse" , "Deer" ];
Animals.pop();
console.log(Animals);
// shift() method
let Animals = [ "Tiger" , "Giraffe" , "Horse" , "Deer" ];
Animals.shift();
console.log(Animals);
尽量减少代码
将应用程序的组件捆绑到* .js文件中, 并通过JavaScript缩小工具传递它们, 可使你的代码更整洁。有大量免费的代码缩减工具。
使用本地范围(" this")
这对于使用回调编写异步代码特别有用, 但是, 由于你不必依赖作用域链中更进一步的全局变量或闭包变量, 因此它也可以提高性能。你可以通过使用内置在每个函数中的特殊call()和apply()方法重新布线, 从而最大程度地利用范围变量(this)。请参阅以下示例:
例子:
let Organization = Object.create({
init: function (name) {
this .name = name;
}, do : function (callback) {
callback.apply( this );
}
});
let lsbin = new Organization( 'lsbin' );
lsbin. do ( function () {
alert( this .name); // 'lsbin' gets alerted because we rewired 'this'.
});