zoukankan      html  css  js  c++  java
  • javascript的性能优化tips

    谈到javascript的性能优化,有好多点,比如把script放到离body闭合标签附近,合并多个script标签等等,还有一些代码的性能,for的性能不如while的性能好,用while模拟for循环等等等。

    1.从加载开始

    在浏览器中,js文件的执行和下载会阻塞css和dom的渲染,这是浏览器的单线程所致,后来chrome,ff等浏览器启用了
    js文件的并行下载,然而js文件的运行还是会被阻塞,有的浏览器支持defer关键字。

    <script type="text/javascript" defer>
        alert("defer");
    </script>
    <script type="text/javascript">
        alert("ok")
    </script>
    <script type="text/javascript">
        window.onload=function(){
            alert("onload");
        }
    </script>

    不支持defer的浏览器会输出defer,ok,onload,支持的会弹出ok,defer和onload,defer是在dom渲染之前的。
    还可以把js文件的script标签用js动态加载。这样文件的下载执行就不会影响其他页面的处理过程。

    另外,你可以监听script标签load事件,而ie触发一个readystatechange事件,而且有一个readyState,
    它有5个状态,最主要的就是loaded和complete事件,然而ie的这两个事件表现又不一致,有时候又loaded事件没有complete,有时候反之。
    那我们在用的时候就可以同时判断:

    var script=document.createElement("script");
    script.type="text/javascript";
    script.onreadystatechange=function(){
        if (script.readyState=="loaded"||script.readyState=="complete") {
            script.onreadystatechange=null;//为了防止事件处理两次
            alert("script ok");
        };
    }
    script.src="file.js";
    document.body.append(script);

    2.数据存储的优化

    如果外部数据在函数作用域内多次使用,最好用一个局部变量来表示,因为局部变量在函数作用域内的性能消耗是最少的,
    函数作用域链中优先查找局部变量,全局变量的性能消耗相对较多。

    var a=doucument.getElementById("aa");
    document.body.onclick=function(){
        var temp=a;
        // temp to do something...            
    }

    3.dom操作的优化

    javascript中存在的dom集合,如document.getElementsByTagName(''),document.links,document.images,document.forms,
    document.forms[0].elements,他们都是类数组,有一个length属性,而在遍历的时候会重新查找计算,而把它们放到一个真正的数组里是一个优化方案。
    或者可以把length用一个变量表示一下;

    var col=document.getElementsByTagName('div');
    var len=col.length;
    for (var i = 0; i < len; i++) {
        //todo;
    };

    在选择dom的结构中,firstChild,nextSibling,previousSibling都是包含文本节点和注释节点,比如在我以前写的选择dom里面,就写了好几个nextSibling。在选取子元素的时候nextSibling比childNodes性能更节省,在ie下节省的性能更多,而jquery的children里面也是用的nextSibling选取的。
    下面这个结构,img1的nextSibling是文本节点,如果自己过滤的话会产生性能消耗,现代浏览器提供了nextElementSibling,previousElementSibling等等,他们可以自动过滤文本节点和注释节点,从而提升性能,
    ie6,7,8只支持children。

    <img src="" id="img1">
    <!-- zhushi -->
    <img src="" id="img2">

    在dom的选择中,querySelectorAll的特性比getElementById的性能好,比如这个结构里:

    var b=document.querySelectorAll('img#img1,img#img2');

    querySelectorAll比较方便,而循环迭代getElementById的性能就不怎么样了。浏览器支持就用吧。

    4.for循环的优化

    for循环的优化,在迭代1000次以上,用达夫设备比较快,基本思想就是用while代替for。而forEach比for循环还慢;
    if else和switch相比,在条件多的时候用 switch条件少用if else 这也符合性能的考虑。
    递归的优化,可以将递归转化为迭代。为了防止递归做一些重复的计算,可以建立缓存如下,视实际情况选用。称为制表技术。这里给一个制表技术的例子:

    function merta(n){
        if (!merta.cache) {
            merta.cache={
                0:0,
                1:1
            }
        };
        if (!merta.cache.hasOwnProperty(n)) {
            merta.cache[n]=n*merta(n-1);
        };
        return merta.cache[n];
    }

    求数字的阶乘,每次递归的结果都被缓冲,从而达到节省性能。

    5.字符串的优化

    str+="one"+"two";

    在运行的时候会产生一个临时变量="onetwo",然后让这个临时变量+=str,而str=str+'one'+'two',就会阻止临时变量的产生,从而做到优化。在大多数浏览器会加快10%-40%

    在ie中,这些优化并不适用,ie的字符串处理机制不用,在ie8中连接字符串只会记下各个字符串的引用,在连接的时候把各个字符串拷贝到真正的字符串中,并取代它的引用。
    而ie8以前的实现更糟,这种方法反而会使效率更慢。ie8以前给每一个字符串的拷贝分配空间,在大量字符串连接的时候性能消耗成倍增长,只能用数组的连接方法来达到优化

    while(len--){
        newstr[newstr.length]=str;
    }
    newStr=newstr.join('');
  • 相关阅读:
    简单的验证码;在一个数组中随即打印出4个不重复的字母
    数据类型
    java语法基础
    mac 开机运行脚本
    【mac】 搭建java环境
    mac 复制文件到NTFS格式的移动硬盘
    JAVA学习日报 8.19
    JAVA学习日报 8.20
    (VI)事务:Spring 事务管理
    (VI)事务:Spring 事务细节
  • 原文地址:https://www.cnblogs.com/dh-dh/p/5142356.html
Copyright © 2011-2022 走看看