從新認識script標籤

  • defer和asnyc(只對外部文件有效)html

    • defer 在頁面完成解析時執行代碼,這個屬性代表腳本在執行時不會影響頁面的構造,在元素中設置這個屬性至關於告訴瀏覽器當即下載但延遲執行segmentfault

    • async 相對於頁面其餘部分異步執行腳本,通常的script標籤都是會阻塞頁面執行的,沒有加上async屬性的標籤會阻塞後面的標籤的解析。通常用在不須要操做dom元素的腳本上,例如一些統計代碼(跟頁面執行邏輯無關的,不涉及dom操做的),能夠避免因長時間加載而呈現白屏現象瀏覽器

  • script中有或沒有它們的區別app

    • script中沒有defer和async,會馬上加載並執行dom

    • script中有async沒有defer時,會與渲染後續文檔元素並行加載,加載完自動執行異步

    • script中有defer沒有async時,後續文檔元素渲染會與腳本文件加載並行,可是執行全部元素解析完成以後,在DOMContentLoaded以前執行async

QQ圖片20160929092409.png

https://segmentfault.com/q/10... 這個回答很棒性能

  • 可是紅寶書中有這樣一句話:HTML5規範要求腳本執行應該按照腳本出現的前後順序執行,但在現實生活中,延遲腳本並不必定按照順序執行,也不必定會在DOMContentLoaded事件中觸發前執行,所以最好只包含一個延遲腳本。所以上圖第三點說法有欠缺測試

Paste_Image.png

未解決問題:全部瀏覽器都兼容,那麼爲何沒有看到別人在用呢?url

查了一下,網易有在用,瀏覽器兼容仍是有點小問題,and業務需求

  • script是能夠並行下載的,這裏應該是指放在head中的script標籤,不會阻塞其餘script標籤,可是仍然會阻塞其餘資源下載,例如圖片。儘管腳本的下載過程當中不會相互影響,但頁面仍然要等到全部js代碼下載並完成執行才能繼續。-- 《高性能的js》

並行下載測試

Paste_Image.png

  • 建議放在body的底部

  • 每一個script標籤初始化都會阻塞頁面渲染,在解析html頁面過程當中每遇到一個script標籤都會因執行腳本而致使必定的延時

  • 儘管單個較大的js文件只請求一次http,可是這樣會致使鎖死瀏覽器一段時間,解決方案除了上面所說的defer以外還能夠動態建立標籤加入head中,能夠經過onload事件來監聽腳本加載是否完畢,ie下經過readystatechange事件

function loadScript(url, callback) {

    var script = document.createElement('script');

    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.getElementsByTagName('head')[0].appendChild(script);

}
相關文章
相關標籤/搜索