久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    JS的阻塞特性

     敬而遠 2012-05-20

    JS具有阻塞特性,當瀏覽器在執行js代碼時,不能同時做其它事情,即<script>每次出現都會讓頁面等待腳本的解析和執行(不論JS是內嵌的還是外鏈的),JS代碼執行完成后,才繼續渲染頁面。

    由于,JS的這種阻塞特性,每次遇到<script>,頁面都必須停下來等待腳本下載并執行,這會停止頁面繪制,帶來不好的用戶體驗。所以,有必要減少JS阻塞特性造成的困擾。

    1 優化腳本位置

    HTML4規范中,<script>可以放在<head>或<body>中。你可能習慣性的在<head>中放置多個外鏈JS、CSS,以求優先加載它們。瀏覽器在繼續到<body>之前,不會渲染頁面,所以,把JS放在<head>中,會導致延遲。為了提高用戶體驗,新一代瀏覽器都支持并行下載JS,但是JS下載仍然會阻塞其它資源的下載(eg.圖片)。盡管腳本的下載過程并不會相互影響,但頁面仍然必須等待所有JS下載并執行完成才能繼續。顯見,所有<script>應該盡可能放到<body>的底部,以減少對頁面下載的影響。

    注意:CSS文件本身是并行下載,不會阻塞頁面的其他進程。但是,如果把一段內嵌腳本放在引用外鏈CSS的<link>之后會導致頁面阻塞去等待CSS的下載。這樣做是為了確保內嵌腳本在執行時能夠獲得正確的樣式信息。所以,最好不要把內嵌腳本放在CSS的<link>之后。

    2 減少外鏈腳本數量以改善性能

     原因很簡單,額外的HTTP請求會帶來額外的開銷,所以減少頁面中外鏈腳本的數量,有助于改善性能。

    3 使用無阻塞下載JS方法

    無阻塞腳本的秘訣在于,在頁面加載完成后才加載JS,即在window對象的load事件觸發后在下載腳本。

    3.1 使用<script>的defer屬性(僅IE和Firefox3.5以上);

    defer屬性指明本元素所含的腳本不會修改DOM,因此代碼能安全的延遲執行。defer屬性的<script>,對應的JS文件將在頁面解析到<script>時開始下載,但并不會執行,直到DOM加載完成,即onload事件觸發前被調用。當一個帶有defer屬性的JS文件下載時,他不會阻塞瀏覽器的其它進程,因此這類文件可以與頁面中的其他資源并行下載。

    復制代碼
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www./1999/xhtml">
    <head>
    <title>DeferredScripts</title>
    </head>
    <body>

    <script type="text/javascript" defer>
    alert("defer");
    </script>

    <script type="text/javascript">
    alert("script");
    </script>

    <script type="text/javascript">
    window.onload = function() {
    alert("load");
    };
    </script>

    </body>
    </html>
    復制代碼

     

    對于支持defer的瀏覽器彈出順序是:script>defer>load;而不支持該屬性的瀏覽器的彈出順序為:defer>script>load。

    3.2 使用動態創建的<script>元素來下載并執行代碼

    實例代碼如下:

    復制代碼
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www./1999/xhtml">
    <head>
    <title>DynamicScriptElements</title>
    </head>
    <body>

    <script type="text/javascript">
    function loadScript(url, callback) {
    var script = document.createElement("Script");
    script.type = "text/javascript";

    //IE 驗證腳本是否下載完成
    if (script.readyState) {
    script.onreadystatechange = function() {
    //readyState屬性有5種取值
    //uninitialized:初始狀態
    //loading:開始下載
    //interactive:數據完成下載但尚不可用
    //complete:數據已經準備就緒
    //實際使用時,readyState的值并不像我們預想的那樣有規律,實踐發現使用readyState
    //最靠譜的方式是同時檢查以下2個狀態,只要其中1個觸發,就認為腳本下載完成。
    if (script.readyState == "loaded" || script.readyState == "complete") {
    //移除事件處理器,確保事件不會處理2次
    script.onreadystatechange = null;
    callback();
    }
    };
    }

    //其他瀏覽器
    else {
    script.onload = function() {
    callback();
    };
    }

    script.src = url;
    //把新建的<Script>添加到<head>里比添加到<body>里更保險。
    document.getElementsByTagName("head")[0].appendChild(script);
    }

    //動態加載多個JS文件
    //優先加載Common.js,等待Common.js加載完畢后加載Costom.js
    //不同瀏覽器的執行順序不同
    //Firefox、Opera能夠保證按照你腳本的加載順序來執行
    //其他瀏覽器會按照從服務端返回的順序執行代碼,因此使用嵌套的方法保證調用順序
    loadScript("Common.js", function() {
    loadScript("Costom.js", function() {
    alert("all load");
    });
    });
    </script>

    </body>
    </html>
    復制代碼

    文件在該元素被添加到頁面時開始下載。這種技術的重點在于:無論在何時啟動下載,文件的下載與執行不會阻塞頁面的其他進程。使用動態腳本節點下載文件時,根據瀏覽器不同,多數瀏覽器,返回的代碼會立即執行(Firefox、Opera,會等待此前所有動態節點執行完畢)。當腳本”自執行“時,這種機制運行正常,但是當代碼內只包含供其它腳本調用的接口時,就必須確保腳本下載完成并準備就緒,在上例中列舉了不同瀏覽器的驗證方法。

    注意:如果多個文件的順序很重要,更好的做法是把它們按正確順序合并為一個文件。此外,說把新建的<Script>添加到<head>里比添加到<body>里更保險是因為要盡量避免頁面報錯(在低版本的IE中使用不當會發生"操作已中止"錯誤

    3.3 使用XHR對象下載JS代碼并注入頁面中

    實例代碼如下:

    復制代碼
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www./1999/xhtml">
    <head>
    <title>XhrScriptInjection</title>
    </head>
    <body>

    <script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.open("get", "JScript.js", true);
    xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
    //2XX表示有效響應,304表示從緩存讀取
    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); //一旦新創建的<script>被添加到頁面,代碼就立刻執行然后準備就緒。
    }
    }
    };
    xhr.send(null);
    </script>

    </body>
    </html>
    復制代碼

    這種方法的優點是,你可以下載JS代碼但不立即執行。由于代碼是在<script>標簽之外返回的,因此它下載后不會自動執行,這使得你可以把腳本的執行推遲到你準備好的時候。另一個優點是,同樣的代碼在所有主流瀏覽器中都能正常工作。

    這種方法的主要局限性是JS文件必須與所有請求的頁面處于相同的域。
    綜上所述,向頁面中添加大量JS的推薦做法只需兩步:先添加動態加載的所需代碼,然后加載初始化頁面所需的剩下代碼。

    復制代碼
        <script type="text/javascript" src="Common.js"></script>

    <script type="text/javascript">
    loadScript("Costom.js", function() {
    //Do Something
    });
    </script>
    復制代碼

    優化前:

    優化后:

     

    "操作已中止"錯誤
    復制代碼
    <html>
    <head>
    <title>Operation Aborted Example</title>
    </head>
    <body>
    <p>The following code should cause an Operation Aborted error in IE versions prior to 8.</p>
    <div>
    <script type="text/javascript">
    document.body.appendChild(document.createElement("div"));
    </script>
    </div>
    </body>
    </html>
    復制代碼

    上述代碼在低版本IE中會報"操作已中止"錯誤。出現此問題的原因是子容器 HTML 元素包含試圖修改父容器元素的子容器的腳本。腳本試圖使用 innerHTML 方法或 appendChild 方法修改父容器元素。例如對于如果 DIV 元素是一個 BODY 元素中的子容器,并且在 DIV 元素中的一個 SCRIPT 塊試圖修改 DIV 元素的父容器的 BODY 元素可能會出現此問題。

    最簡單的解決方法:將腳本移到body元素的范圍。

    復制代碼
    <html>
    <head>
    <title>Operation Aborted Example</title>
    </head>
    <body>
    <p>The following code should cause an Operation Aborted error in IE versions prior to 8.</p>
    <div>
    </div>
    <script type="text/javascript">
    document.body.appendChild(document.createElement("div"));
    </script>
    </body>
    </html>
    復制代碼

    其它解決方法可以參考:

    http://www./blog/2008/03/17/the-dreaded-operation-aborted-error

    http://support.microsoft.com/kb/927917/zh-cn

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 蜜芽久久人人超碰爱香蕉 | 丰满人妻一区二区三区视频53 | 91中文字幕一区二区| 在线观看成人永久免费网站| 午夜夫妻试看120国产| 国产精品大片中文字幕| 午夜A理论片在线播放| 亚洲小说乱欧美另类| 97精品亚成在人线免视频| 3D动漫精品啪啪一区二区免费| 天天做天天爱夜夜爽导航| 少妇肉麻粗话对白视频| A毛片终身免费观看网站| 日韩亚洲AV人人夜夜澡人人爽| 人妻中文字幕精品一页| 狠狠色丁香婷婷综合潮喷| 人妻中文字幕不卡精品| 欧美亚洲日韩国产人成在线播放| 日韩人妻精品中文字幕| 久久超碰97人人做人人爱 | 69天堂人成无码免费视频| 欧美巨鞭大战丰满少妇| 日本一区不卡高清更新二区| 色屁屁WWW影院免费观看入口| 亚洲高清国产拍精品5G| 国产精品成人久久电影| 免费播放一区二区三区| 欧美高清狂热视频60一70| 中出人妻中文字幕无码| 99RE6在线视频精品免费下载| 国产精品中文字幕av| 狠狠色噜噜狠狠狠7777奇米| 日韩欧美不卡一卡二卡3卡四卡2021免费| 精品亚洲国产成人av| 日韩AV无码免费播放| 国产中年熟女大集合| 国产精品人妻中文字幕| 亚洲AV无码一区二区乱子伦| 西西人体44WWW高清大胆| 四虎成人精品永久网站| 亚洲精品国产中文字幕|