高性能JavaScript chapter 1 : 加載和執(zhí)行

如何用最高效的方式把javascript代碼加載到頁面中呢懂更?
1眨业、腳本位置
每個文件必須等到前一個文件下載并執(zhí)行完成才會開始下載。在這些文件逐個下載過程中沮协,用戶看到的是一片空白龄捡。稱為腳本阻塞。因此推薦將所有的標(biāo)簽盡可能放到標(biāo)簽的底部慷暂,以盡量減少對整個頁面下載的影響聘殖。

<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>標(biāo)簽奸腺,都會因執(zhí)行腳本而導(dǎo)致一定的延時餐禁,所以減少頁面所包含的<script>標(biāo)簽數(shù)量有助于改善頁面性能。
(2)HTTP請求會帶來額外的性能開銷突照,因此下載單個100KB的文件將比下載4個25KB的文件更快帮非。即,減少頁面中外鏈腳本文件的數(shù)量將會改善性能讹蘑。
綜述:用文件打包工具把多個文件合并成1個末盔,這樣只需要引用一個<script>標(biāo)簽,就可以減少性能消耗座慰。

<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>標(biāo)簽時開始下載版仔,但并不會執(zhí)行游盲,下載時,不會阻塞瀏覽器的其他進程蛮粮,可以與頁面中其他資源并行下載益缎。它下載完成后,在onload事件被觸發(fā)前執(zhí)行然想。
該屬性只有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)動態(tài)腳本文件
該腳本文件被添加到頁面時開始下載又沾,無論在何時啟動下載,文件的下載和執(zhí)行過程不會阻塞頁面其他進程熙卡。

<html>
<head>
    <title>動態(tài) 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 初始狀態(tài)
loading 開始下載
loaded 下載完成
interactive 數(shù)據(jù)完成下載但尚不可使用
complete 所有數(shù)據(jù)已準(zhǔn)備就緒</small>
(3)XMLHttpRequest(xhr對象) 腳本注入
優(yōu)點1:你可以把腳本的執(zhí)行推遲到你準(zhǔn)備好的時候驳癌。
優(yōu)點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>這段代碼發(fā)送一個get請求獲取file1.js文件颓鲜。事件處理函數(shù)onReadyStateChange 檢查readyState 是否為4 表窘,同時校驗HTTP狀態(tài)碼是否有效(2XX 表示有效響應(yīng),304意味著是從緩存讀忍鸨酢)乐严。如果收到了有效響應(yīng),就會創(chuàng)建一個<script>元素衣摩,設(shè)置該元素的text屬性為從服務(wù)器接收到的responseText昂验。</small>
(4)作者推薦的無阻礙模式

  • 第一種:YUI3的方式
    YUI3 API:https://github.com/yui/yui3
    設(shè)計理念:由頁面中的少量代碼來加載豐富的功能組件。
<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的代碼前執(zhí)行既琴。
為了確保這一點占婉,你必須在第一個script()方法后調(diào)用wait(),比如甫恩,
如下示例可以保證first-file.js的代碼在the-rest.js的代碼前執(zhí)行逆济。</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>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市磺箕,隨后出現(xiàn)的幾起案子奖慌,更是在濱河造成了極大的恐慌,老刑警劉巖滞磺,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件升薯,死亡現(xiàn)場離奇詭異,居然都是意外死亡击困,警方通過查閱死者的電腦和手機涎劈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阅茶,“玉大人蛛枚,你說我怎么就攤上這事×嘲В” “怎么了蹦浦?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撞蜂。 經(jīng)常有香客問我盲镶,道長,這世上最難降的妖魔是什么蝌诡? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任溉贿,我火速辦了婚禮,結(jié)果婚禮上浦旱,老公的妹妹穿的比我還像新娘宇色。我一直安慰自己,他們只是感情好颁湖,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布宣蠕。 她就那樣靜靜地躺著,像睡著了一般甥捺。 火紅的嫁衣襯著肌膚如雪抢蚀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天镰禾,我揣著相機與錄音思币,去河邊找鬼鹿响。 笑死,一個胖子當(dāng)著我的面吹牛谷饿,可吹牛的內(nèi)容都是我干的惶我。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼博投,長吁一口氣:“原來是場噩夢啊……” “哼绸贡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起毅哗,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤听怕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后虑绵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尿瞭,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年翅睛,在試婚紗的時候發(fā)現(xiàn)自己被綠了声搁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡捕发,死狀恐怖疏旨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扎酷,我是刑警寧澤檐涝,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站法挨,受9級特大地震影響谁榜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凡纳,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一惰爬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惫企,春花似錦、人聲如沸陵叽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽巩掺。三九已至偏序,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胖替,已是汗流浹背研儒。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工豫缨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人端朵。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓好芭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親冲呢。 傳聞我的和親對象是個殘疾皇子舍败,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容