精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
JS的阻塞特性

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.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/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.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/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.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/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.nczonline.net/blog/2008/03/17/the-dreaded-operation-aborted-error

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

本站僅提供存儲服務,所有內容均由用戶發布,如發現有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
探真無阻塞加載javascript腳本技術,我們會發現很多意想不到的秘密
JavaScript EE,第 3 部分: 結合使用 Java Scripting API 和 JSP
JavaScript的性能優化:加載和執行
高性能Javascript
非阻塞式JavaScript腳本介紹
一篇文章帶你搞定JavaScript 性能調優
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服

主站蜘蛛池模板: 什邡市| 铁力市| 柳江县| 大兴区| 古丈县| 长治市| 增城市| 错那县| 桦川县| 辽宁省| 万全县| 永善县| 民权县| 沁阳市| 延吉市| 丰镇市| 蓝山县| 泰来县| 巴彦淖尔市| 崇仁县| 曲阳县| 通河县| 莱州市| 皋兰县| 南木林县| 阜新| 新密市| 会泽县| 武功县| 贡嘎县| 峨眉山市| 启东市| 府谷县| 金堂县| 鄱阳县| 游戏| 罗定市| 湖口县| 鄂尔多斯市| 娄烦县| 钟祥市|