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

如何用最高效的方式把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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容