zoukankan      html  css  js  c++  java
  • LABjs使用与分析

    目前业界商用的JS文件加载器有LABjs,Require.js,Sea.js。后两者同时又是模块加载器,很多网站/软件并不是按照AMD/CMD规范来开发的,只有LAB.js在大部分网站/软件上可以即插即用,下面分析一下LAB.js。

    LAB.js即loading and blocking,并行的加载脚本文件,同时同步的等待执行。

    实例:

    $LAB.setGlobalDefaults({Debug:true}) //打开调试
    
     $LAB
         //第一个执行链
        .script('http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js')
        .script('http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js')
    
        //第二个执行链
        .wait(function(){
             // console.log(window.$)
             // console.log(window._)
        })
    
        //第三个执行链
        .script('http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/js/bootstrap.min.js')
        .script('http://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.pack.js')
    
        //第四个执行链
        .wait(function(){
             // console.log(plugin1Function)
             // console.log(plugin2Function)
        })
    
        //第五个执行链
        .script('./module1.js')
        .script('./module2.js')
    
        //第六个执行链
        .wait(function(){
            // console.log(module1Function)
            // console.log(module2Function)
        })

    调试信息跟踪分析:

    //这三个执行是并行加载完以后,执行的3个wait操作
    驱动执行的函数advance_exec_cursor, chain length:2  exec_cursor:0 LAB.js:46
    驱动执行的函数advance_exec_cursor, chain length:4  exec_cursor:0 LAB.js:46
    驱动执行的函数advance_exec_cursor, chain length:6  exec_cursor:0 LAB.js:46
    //因为request_script函数中setTimeout(f,0),所以加载会滞后于wait操作
    start script load (ordered async): http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js LAB.js:46
    start script load (ordered async): http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js LAB.js:46
    start script load (ordered async): http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/js/bootstrap.min.js LAB.js:46
    start script load (ordered async): http://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.pack.js LAB.js:46
    start script load (ordered async): file:///D:/Users/sj_yu/Desktop/work/20140408/LABjs/./module1.js LAB.js:46
    start script load (ordered async): file:///D:/Users/sj_yu/Desktop/work/20140408/LABjs/./module2.js LAB.js:46
    script execution finished: http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js LAB.js:46
    script execution finished: http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js LAB.js:46
    //按顺序执行完第一组执行链,也就是jquery和lodash,执行完JS后,调用advance_exec_cursor来探测执行游标是否需要移动
    驱动执行的函数advance_exec_cursor, chain length:6  exec_cursor:0 LAB.js:46
    //执行第二组执行链
    $LAB.wait() executing: function (){
             // console.log(window.$)
             // console.log(window._)
        } LAB.js:46
    //执行第三组执行链
    script execution finished: http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/js/bootstrap.min.js LAB.js:46
    script execution finished: http://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.pack.js LAB.js:46
    //执行完第三组后,触发advance_exec_cursor
    驱动执行的函数advance_exec_cursor, chain length:6  exec_cursor:2 LAB.js:46
    //第四组执行链
    $LAB.wait() executing: function (){
             // console.log(plugin1Function)
             // console.log(plugin2Function)
        } LAB.js:46
    //第五组执行链
    script execution finished: file:///D:/Users/sj_yu/Desktop/work/20140408/LABjs/./module1.js LAB.js:46
    script execution finished: file:///D:/Users/sj_yu/Desktop/work/20140408/LABjs/./module2.js LAB.js:46
    驱动执行的函数advance_exec_cursor, chain length:6  exec_cursor:4 LAB.js:46
    //执行第六组执行链
    $LAB.wait() executing: function (){
            // console.log(module1Function)
            // console.log(module2Function)
        } 

    LAB.js关键代码分析:

    //核心代码
    (function(global){
    
        function create_sandbox() {
    
            //加载脚本,用到的方式有document.createElement('script'),xhr
            function do_script() {
                //脚本加载
                if(需要预加载) {
                    if(是否默认支持预加载) {
                        if(是否支持preload属性) {
                            script.preload = true;
                        } else {
                            script.onreadystatechage = function() {
                                if (script.readyState == "loaded") onload();
                            }
                        }
                        script.src = src;
                    } else if(是否用XHR方式) {
                        new XMLHttpRequest();
                    } else {
                        script.type = "text/cache-script";
                        create_script_load_listener();
                        script.src = src;
                    }
                } else if(可以异步加载) {
                    script.async = false; //强制同步执行
                    create_script_load_listener();
                    script.src = src;
                } else {
                    create_script_load_listener();
                    script.src = src;
                }
            }
    
            //创建执行链
            function create_chain() {
    
                var chain = [];//执行链
    
                //执行完JS调用该函数
                function chain_script_executed() {
                    advance_exec_cursor();
                }
    
                //主动执行每个执行链
                function advance_exec_cursor() {
                    while(执行游标 < chain.length) {
                        if(执行链是wait中的函数) {
                            执行wait函数
                        } else if(该执行链还没执行完) {
    
                        } 
    
                        游标++;
                    }
    
                    if (游标 == chain.length) {
                        执行停止
                    }
                }
    
                //执行链api
                var chainedAPI = {
                    script: function() {
                        do_script();
    
                        return chainedAPI;//支持链式调用
                    },
    
                    wait: function() {
                        if(arguments.length > 0) {
                            chain.push(arguments)
                        }
    
                        advance_exec_cursor();
    
                        return chainedAPI;//支持链式调用
                    }
                }
    
                return {
                    script:chainedAPI.script, 
                    wait:chainedAPI.wait
                };
            } //end of create_chain
    
            //整个$LAB的接口
            var instanceAPI = {
                script:function(){
                    return create_chain().script.apply(null,arguments);
                },
                wait:function(){
                    return create_chain().wait.apply(null,arguments);
                }
            };
    
            return instanceAPI;
        } // end of create_sandbox
    
        //create_sandbox()返回 instanceAPI,包含script,wait等接口
        global.$LAB = create_sandbox();  
    })(this);

    总结:

    优点:LABjs的接口设计非常轻,api很清晰,现有项目可以快速上手,大幅改进页面性能。相对于多个JS文件压缩到一个JS文件,又有不阻塞图片,css加载和模块化的优势。

    缺点:目前没有靠谱的grunt插件,打包困难。

    与Require.js和Sea.js的比较请参考:

    http://www.zhihu.com/question/20342350

    DailyJS对LABjs的解析:

    http://dailyjs.com/2011/08/15/code-review/

  • 相关阅读:
    vim 显示行号 临时&永久
    ubuntu redis config IP password
    Vulnerability Scanning Tools
    Tomcat清理无用应用防止漏洞
    XSS平台-学习
    Amazon aws s3 加速
    XSS的DOS攻击之 server limit dos
    Linux Nginx naxsi
    Acunetix Web Vulnerability Scanner abbr. AWVS
    nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied)
  • 原文地址:https://www.cnblogs.com/aotoYu/p/3653003.html
Copyright © 2011-2022 走看看