js优化汇总
js优化
延期脚本
带有defer属性的script标签。会等待DOM加载完成后再执行。无论是内联脚本还是外部脚本。
动态脚本
通过创建script标签,可以随时添加脚本,不会对页面加载有任何阻塞。
标识符解析性能
直接量和局部变量的访问速度比数组项和对象成员要快,具体快多少视浏览器而定。
闭包的副作用
因为闭包会保留作用域,所以经常访问范围之外的标识符会增加一些性能开销,为了减轻对运行速度的影响。最好将常用的域外变量存入局部变量中。
缓存对象成员的值
正因为原型链的存在,可以使js做到类似面向对象的继承机制,但是当原型链足够深时,一些嵌套很深的原型属性调用,会在原型链上搜索的很慢。所以适当的
减少DOM操作
因为浏览器中js引擎和页面的渲染引擎在技术上分离,所以js操作DOM不可避免的会有性能开销,当js频繁操作DOM时,这种性能开销将带来极为严重的页面响应过慢的问题。
克隆节点
使用document.cloneNode()方法比document.createElement()创建元素更快。
HTML集合
每次对HTMLCollection对象进行索引或者修改,都会执行页面的元素查询,执行效率将会很低。所以,当需要对HTML集合进行循环遍历的时候,通常比较好的做法是,用局部变量缓存length属性,以及视具体情况用数组来缓存HTML集合,因为数组的遍历没有对页面元素进行查询,效率会比HTML集合更高一些。
元素节点
DOM属性诸如childNodes,firstNode,和nextSibling不区分元素节点和其他类型节点,但通常只需要操作元素节点,所以需要对节点的返回类型加以过滤,带来不必要的性能开销。现代浏览器提供了只返回元素节点类型的DOM属性,如children,childElementCount等。
精细获取DOM
通过使用getElementById()和getElementByTagName()来精准抓取某些DOM元素时,不可避免地会有对集合元素或者父子节点的查询,如果使用querySelectorAll()方法,它支持css选择器的精准定位,所以执行速度更快。
循环
关于JS的循环,循环是一种常用的流程控制。JS提供了三种循环:for(;😉、while()、for(in)。在这三种循环中 for(in)的效率最差,因为它需要查询Hash键,因此应尽量少用for(in)循环,for(;😉、while()循环的性能基本持平。当然,推 荐使用for循环,如果循环变量递增或递减,不要单独对循环变量赋值,而应该使用嵌套的++或--运算符。
如果需要遍历数组,应该先缓存数组长度,将数组长度放入局部变量中,避免多次查询数组长度。
对字符串进行循环操作,例如替换、查找,就使用正则表达式。因为JS的循环速度比较慢,而正则表达式的操作是用C写成的API,性能比较好。
运算符和方法
尽量少使用eval,每次使用eval需要消耗大量时间,这时候使用JS所支持的闭包可以实现函数模板。
使用运算符时,尽量使用+=,-=、*=、=等运算符号,而不是直接进行赋值运算。
当需要将数字转换成字符时,采用如下方式:"" + 1。从性能上来看,将数字转换成字符时,有如下公式:("" +) > String() > .toString() > new String()。String()属于内部函数,所以速度很快。而.toString()要查询原型中的函数,所以速度逊色一些,new String()需要重新创建一个字符串对象,速度最慢。
当需要将浮点数转换成整型时,应该使用Math.floor()或者Math.round()。而不是使用parseInt(),该方法用于将字符串转换成数字。而且Math是内部对象,所以Math.floor()其实并没有多少查询方法和调用时间,速度是最快的。
尽量使用JSON格式来创建对象,而不是var obj=new Object()方法。因为前者是直接复制,而后者需要调用构造器,因而前者的性能更好。
当需要使用数组时,也尽量使用JSON格式的语法,即直接使用如下语法定义数组:[parrm,param,param…],而不是采用 new Array(parrm,param,param…)这种语法。因为使用JSON格式的语法是引擎直接解释的。而后者则需要调用Array的构造器。
修改css类而不是直接修改样式