美文网首页
高性能JavaScript chapter 1 : 加载和执行

高性能JavaScript chapter 1 : 加载和执行

作者: 张朝阳_cecurs | 来源:发表于2017-04-03 20:13 被阅读0次

    如何用最高效的方式把javascript代码加载到页面中呢?
    1、脚本位置
    每个文件必须等到前一个文件下载并执行完成才会开始下载。在这些文件逐个下载过程中,用户看到的是一片空白。称为脚本阻塞。因此推荐将所有的标签尽可能放到标签的底部,以尽量减少对整个页面下载的影响。

    <html>
    <head>
        <title>script example</title>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
        <p>Hello world!</p>
        <!-- 推荐的脚本存放位置 -->
        <script type="text/javascript" src="file1.js"></script>
        <script type="text/javascript" src="file2.js"></script>
        <script type="text/javascript" src="file1.js"></script>
    </body>
    </html>
    

    2、组织脚本
    (1)浏览器在解析HTML页面的过程中,每遇到一个<script>标签,都会因执行脚本而导致一定的延时,所以减少页面所包含的<script>标签数量有助于改善页面性能。
    (2)HTTP请求会带来额外的性能开销,因此下载单个100KB的文件将比下载4个25KB的文件更快。即,减少页面中外链脚本文件的数量将会改善性能。
    综述:用文件打包工具把多个文件合并成1个,这样只需要引用一个<script>标签,就可以减少性能消耗。

    <html>
    <head>
        <title>script example</title>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
        <p>Hello world!</p>
        <!-- 推荐的脚本存放位置 -->
        <script type="text/javascript" src="file1.js"></script>
    </body>
    </html>
    

    3、无阻塞的脚本
    秘诀:在页面加载完成后才加载JavaScript代码。
    (1)延迟的脚本
    带有defer属性的JavaScript文件将在页面解析到<script>标签时开始下载,但并不会执行,下载时,不会阻塞浏览器的其他进程,可以与页面中其他资源并行下载。它下载完成后,在onload事件被触发前执行。
    该属性只有IE4+ 和 firefox3.5+ 的浏览器支持。

    <head>
        <title>script defer example</title>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
        <script defer>
            alert("defer");
        </script>
        <script>
            alert("script");
        </script>
        <script>
            window.onload = function(){
                alert("load");
            }
        </script>
    </body>
    </html>
    

    <small>该 示例 在支持defer属性的浏览器上,弹出的顺序是:script , defer , load.</small>
    (2)动态脚本文件
    该脚本文件被添加到页面时开始下载,无论在何时启动下载,文件的下载和执行过程不会阻塞页面其他进程。

    <html>
    <head>
        <title>动态 script example</title>
    </head>
    <body>
        <script>
            function loadScript( url , callback ){
                var script = document.createElement("script");
                script.type = "text/javascript";
                if( script.readyState ){ // IE
                    script.onreadystatechange = function(){
                        if( script.readyState == "loaded" || script.readyState == "complete" ){
                            script.onreadystatechange = null;
                            callback();
                        }
                    }
                } else { // 其他浏览器
                    script.onload = function(){
                        callback();
                    }
                }
                script.src = url ;
                document.getElementByTagName("head")[0].appendChild(script);
            }
            loadScript("file1.js" , function(){
                alert("file is loaded !");
            })
        </script>
    </body>
    </html>
    

    <small>该 示例 用到<script>的readyState属性,该属性有5种取值:
    uninitialized 初始状态
    loading 开始下载
    loaded 下载完成
    interactive 数据完成下载但尚不可使用
    complete 所有数据已准备就绪</small>
    (3)XMLHttpRequest(xhr对象) 脚本注入
    优点1:你可以把脚本的执行推迟到你准备好的时候。
    优点2:在所有主流浏览器都能正常使用。
    缺点:JavaScript文件必须与所请求的页面属于相同的域。

    <html>
    <head>
        <title>xhr script example</title>
    </head>
    <body>
        <script>
            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;
                        document.body.appendChild(script);
                    }
                }
            }
            xhr.send(null);
        </script>
    </body>
    </html>
    

    <small>这段代码发送一个get请求获取file1.js文件。事件处理函数onReadyStateChange 检查readyState 是否为4 ,同时校验HTTP状态码是否有效(2XX 表示有效响应,304意味着是从缓存读取)。如果收到了有效响应,就会创建一个<script>元素,设置该元素的text属性为从服务器接收到的responseText。</small>
    (4)作者推荐的无阻碍模式

    • 第一种:YUI3的方式
      YUI3 API:https://github.com/yui/yui3
      设计理念:由页面中的少量代码来加载丰富的功能组件。
    <html>
    <head>
        <title>YUI3 example</title>
    </head>
    <body>
        <script src="http://yui.yahooapis.com/3.18.1/build/yui/yui-min.js"></script>
        <script>
        // Create a YUI sandbox on your page.
        YUI().use('node', 'event', function (Y) {
            // The Node and Event modules are loaded and ready to use.
            // Your code goes here!
        });
        </script>
    </body>
    </html>
    
    <html>
    <head>
        <title>LazyLoad example</title>
    </head>
    <body>
        <script type="text/javascript" src="lazyload.js"></script>
        <script>
            LazyLoad.js("the-rest.js",function(){
                
                Application.init();
            });
        </script>
    </body>
    </html>
    
    <html>
    <head>
        <title>LABjs example</title>
    </head>
    <body>
        <script type="text/javascript" src="LAB.js"></script>
        <script>
            $LAB.script("first-file.js").wait()
                .script("the-rest.js")
                .wait(function(){
                    Application.init();
                });
        </script>
    </body>
    </html>
    

    <small>在前面的例子中,不能保证first-file.js的代码在the-rest.js的代码前执行。
    为了确保这一点,你必须在第一个script()方法后调用wait(),比如,
    如下示例可以保证first-file.js的代码在the-rest.js的代码前执行。</small>

    <html>
    <head>
        <title>LABjs example</title>
    </head>
    <body>
        <script type="text/javascript" src="LAB.js"></script>
        <script>
            $LAB.script("first-file.js").wait()
                .script("the-rest.js")
                .wait(function(){
                    Application.init();
                });
        </script>
    </body>
    </html>
    

    相关文章

      网友评论

          本文标题:高性能JavaScript chapter 1 : 加载和执行

          本文链接:https://www.haomeiwen.com/subject/fypoottx.html