• 高性能Javascript笔记


    .) 下载并执行javacript会阻塞页面渲染,因此比较推荐js脚本放在页面底部,在</body>标签上边...
    .) 尽量减少script标签。如果外链多个script文件,能合并就合并(利用合并的工具),同样适用内嵌的。
    .) 动态脚本加载,无阻塞的比较好的解决方案:创建script DOM
    比如:

    var script = document.createElement("script");
    script.type = "text/javascript";
    //Firefox, Opera, Chrome, Safari 3+ 
    //js文件src下载完的触发事件
    script.onload = function(){
      alert(1);
    };
    script.src = "jquery.js";
    document.getElementsByTagName("head")[0].appendChild(script);

    .) 另一种无阻塞载入,利用xhr对象获取脚本注入,这种方法不能跨域获取(--ajax

     var xhr = new XMLHttpRequest();
        xhr.open("get", "file1.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;// 相当于内联聊本的<script>标签
                    document.body.appendChild(script);
                }
            }
        };
        xhr.send(null);

    事件委托:

    dom如下所示,

    span上都要有点击事件的反馈。如果在每个span上绑定click事件的话,当li很多时候,这样比较浪费性能。
    事件绑定占用了处理时间,浏览器需要跟踪每个事件处理器,占用了更多内存。
    此时可以使用事件委托。利用冒泡机制,在其父节点,比如只需要在ul上监听一个点击事件。然后判断节点哪个是哪个就ok了。

    <div>
        <ul id="ul">
            <li>
                <span id="a">aaaaa</span>
            </li>
            <li>
                <span id="b">bbbb</span>
            </li>
            <li>
                <span id="c">ccccc</span>
            </li>
            <li>
                <span id="d">ddddd</span>
            </li>
        </ul>
    </div>
    
    <script type="text/javascript">
        $('#ul').click(function(e){
                var target = e.target;
               // 只有点击的是span标签才触发事件
                if(target.nodeName.toLowerCase() != 'span'){
                    return false;
                }
                var id = target.id; // 判断目标对象是哪个span
                switch(id){
                    case 'a': alert(1);break;
                    case 'b': alert(2);break;
                    case 'c': alert(3);break;
                    case 'd': alert(4);break;
                }
    
            });
    </script>        

    字符串连接;

    str += "one" + "two";
    
    str += "one";
    str += "two";
    
    str = str + "one" + "two";

    第一行代码比较浪费,内存需要分配一个临时字符串来连接 "onetwo",然后再连str。

    剩下两种方式,则不需要内存额外分配变量。

    作用域链和原型链得知,一个全局变量在局域使用,最好是赋值给局域变量。链上远的变量查找更耗时,更消耗性能。

    在操作dom集合(类数组而不是数组)的时候,涉及到length,尽量把这个集合的length赋值给一个变量,然后在循环里使用这个变量。遍历集合没有遍历数组快。

    大多数时候没必要使用eval()和Function(),每次调用eval()时都要创建一个新的解释器/编译器示例。
    尽量避免使用他们。至于setTimeout()和setInterval(),建议传入函数而不是字符串作为第一个参数。比如:

    setTimeout(function(){
        sum = a+b;
    }, 100);

    使用Object/Array时,建议使用直接量,这样更快。
    比如:

    var obj = new Object();
    obj.name = 'a';
    obj.age = 12;
    
    // 更推荐这种方式:
    var obj = {
    name: 'a',
    age: 12
    };
    
    // ============
    // 数组比如:
    var arr = new Array();
    arr[0] = 'a';
    arr[1] = 'b';
    
    // 更推荐这种:
    var arr = ['a', 'b'];

    不要重复工作:
    比如根据一个判断(比如这里的 a 和 b 大小比较)处理一个逻辑:

    var a=1;
    var b=2;
    function test(){
        if(b>a){
           xxx;// 几行代码
        } else {
           yyy;//
        }
    }

    比如这个 test() 函数在页面上可能会频繁遭到调用,那么每次都要去判断 a 和 b 的大小(如果是更复杂的逻辑判断,那么频繁调用一定会浪费性能)。那么不如在代码中重新覆盖这个 test() 函数:

    function test(){
        if(b>a){
           test = function(){// 重新给test赋值
               xxx;
            };
        } else {
            test = function(){
               yyy;
            };
        }
        test();// 当然结尾不要忘记执行
    }          

    这样的话,下一次再去调用这个test()的话,直接就是了。


    数字运算的话,可以多考虑下,是否可以按位运算。比如奇数偶数这个...和1按位与操作。

    尽量使用原生js,比较原生的都是js引擎低级编程语言编译好的,要更快。


    Ajax:

    常用的向服务器请求数据的方法:
    1. XMLHttpRequest(XHR) 最常用的技术
    2. 动态脚本注入
    3. Multipart XHR

    1). xhr(ajax常用技术,IE低版本要使用 ActiveXObject )是最常用的,它允许异步发送和接收数据。浏览器支持好,get、post方式均可,可以读取http响应头信息和响应文本。缺点不能跨域。
    代码:

    var url = '/data.php?a=1&b=2';
    var req = new XMLHttpRequest();
    
    req.onreadystatechange = function(){
        if(req.readyState === 4){// 4表示整个响应接收完毕;3表示接收到部分信息,还没完
            var responseHeaders = req.getAllResponseHeaders();// 获取响应头信息
            var data = req.responseText;// 获取响应文本
            // 逻辑处理
            // ...
        }
    }
    
    req.open('GET', url, true);// true表示异步
    req.setRequestHeader('', '');// 可以设置请求头信息
    req.send(null);// 发送请求

    2). 动态脚本注入
    这个方法利用动态创建 script 元素来请求数据。它克服了xhr最大限制:可以跨域请求。这当然算是个Hack。

    xhr的缺点:不可以设置请求头信息;也只能使用get方式;需要等这个脚本下载完,才能访问它们;返回的数据需要封装在函数里。
    因为响应信息是脚本标签的源码(script),因此他必须是可执行的javascript代码,所以数据格式需要封装在函数里,或者说调用一个函数。
    代码:

    var scriptEle = document.createElement('script');
    scriptEle.src = 'http://xxx/test.js';// 可以请求与当前脚本所在不同域的文件。
    document.getElementsByTagName('head')[0].appendChild(scriptEle); // 在head头部插入脚本
    function callfun(data){
        // 接收到服务端过来的 data
        alert(data.a);
    }
    
    
    // test.js 文件内容
    callfun({a:1,b:'qq'});// 数据被包含在回调函数里。

     

    向服务器传输数据:
    一种xhr的技术,还有一种信标的方法。
    所谓信标,就是创建一个Image对象,利用属性src向服务器传输数据。然而这种方法,效率虽高,但是存在局限性,一般只是像服务器传输数据,而不关心返回结果(当然服务端的确可以返回一个图片,然后前端根据图片的比如宽度来判断逻辑,这个宽度也可以算是服务端的返回状态。不过一般使用这种方法,不考虑服务端返回结果...),而且src表示也只能以get方式传输,并且参数长度也有所限制。
    代码:

    (new Image()).src = 'http://www.test.com/xxx.php?a=1&b=x';// 传输了a、b两个参数值过去

    -

  • 相关阅读:
    MSSQL慢查询查询与统计
    SQLServer统计采集数据库相关信息
    python3 安装pymssql失败 pip3 install pymssql
    CentOS7源码安装Python3
    python3 安装pyodbc失败 pip3 install pyodbc
    Django配置Mysql数据库 (Pycharm)
    DBArtist之Oracle入门第4步: Oracle创建数据库
    DBArtist之Oracle入门第3步: 安装配置PL/SQL Developer
    linux三剑客
    python + SMTP 发送邮件
  • 原文地址:https://www.cnblogs.com/firstForEver/p/5363975.html
Copyright © 2020-2023  润新知