JS以及CSS對頁面的阻塞

1、JS阻塞javascript

   全部的瀏覽器在下載JS文件的時候,會阻塞頁面上的其餘活動,包括其餘資源的下載以及頁面內容的呈現等等,只有當JS下載、解析、執行完,纔會進行後面的 操做。在現代的瀏覽器中CSS資源和圖片image資源是並行下載的,在IE6中默認的並行的加載數目是2個,在IE6之後以及其餘的瀏覽器中的默認的並行加載數目是6個。css

在瀏覽器從服務器接收到HTML文檔後,並把HTML在內存中轉換爲DOM樹,在轉換節點的過程當中若是引入了CSS文件以及添加了images,則會在文檔加載的同時並行的加載CSS文件以及圖片。可是JS不同,由於瀏覽器須要1個穩定的DOM樹結構,而JS中頗有可能有代碼直接改變了DOM樹結構,好比使用document.write 或 appendChild,甚至是直接使用的location.href進行跳轉,瀏覽器爲了防止出現JS修改DOM樹,須要從新構建DOM樹的狀況,因此就會阻塞其餘的下載和呈現.在沒有使用異步加載(async)或者是延遲加載(defer)的狀況下,只有在一個JS文件加載解析完後才能加載後面的JS文件。利用延遲腳本和異步腳本能夠實現腳本的並行加載。如下討論都是在沒有這兩個屬性的狀況下。html

  (1)內嵌腳本的阻塞java

     直接寫在HTML文檔中的js代碼就是內嵌JS,內嵌腳本無需加載,能夠直接執行,因此當頁面有內嵌的腳本時,能夠直接執行,致使會阻塞全部資源的加載和頁面的呈現。bootstrap

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>內嵌JS會阻塞頁面上的全部內容的呈現</title>
</head>
<body>
<div>
<ul>
    <li>blogjavaspan style="color: #800000;"</li>
    <li>CSDNspan style="color: #800000;"</li>
    <li>博客園span style="color: #800000;"</li>
    <li>ABCspan style="color: #800000;"</li>
    <li>AAAspan style="color: #800000;"</li>
</ul>
<span style="color: #800000;"></span>
</div>
<script type="text/javascript">
// 循環5秒鐘
var n = Number(new Date());
var n2 = Number(new Date());
while((n2 - n) < (6*1000)){
n2 = Number(new Date());
}
</script>

<ul>
    <li>MSNspan style="color: #800000;"</li>
    <li>GOOGLEspan style="color: #800000;"</li>
    <li>YAHOOspan style="color: #800000;"</li>
</ul>

</body>
</html>

上面的內嵌腳不只會阻塞第二個ul的展現,也會阻塞第一個ul的展現,頁面在5秒前是一片空白,當延遲結束後才展示全部的內容瀏覽器

(2)外聯腳本阻塞服務器

  外聯腳本不同,外聯腳本只有當頁面加載到該<script>以後纔會加載外聯腳本,因此外聯腳本只會阻塞其後面的內容的呈現以及資源的下載,在下面的代碼中,頁面會先展現一部份內容,後面一部份內容在5秒後展示app

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>外聯JS文件只會阻塞後面的資源的下載和呈現</title>
</head>
<body>
<ul>
    <li>blogjavaspan style="color: #800000;"</li>
    <li>CSDNspan style="color: #800000;"</li>
    <li>博客園span style="color: #800000;"</li>
    <li>ABCspan style="color: #800000;"</li>
    <li>AAAspan style="color: #800000;"</li>
</ul>
<script src="定時.js"></script><!--定時中的代碼和上面的延遲函數的內容同樣的-->
<ul>
    <li>MSNspan style="color: #800000;"</li>
    <li>GOOGLEspan style="color: #800000;"</li>
    <li>YAHOOspan style="color: #800000;"</li>
</ul>
</body>
</html>

2、嵌入JS致使CSS阻塞加載的問題異步

async

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
</head>
<body>
<img src="http://www.blogjava.net/images/logo.gif" />
<img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
</body>
</html>

fireBug中的時間棧:

谷歌中的事件棧:

在上圖中CSS和圖片是並行下載的,經過時間線能夠看出,後面的圖片並無等到CSS文件徹底加載完後在加載。

(2)內嵌腳本致使CSS阻塞頁面

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
    <script type="text/javascript">
        function a(){};
    </script>
</head>
<body>
<img src="http://www.blogjava.net/images/logo.gif" />
<img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
</body>
</html>

fireBug中的時間棧:

 谷歌中的時間棧:

經過上圖在狐火中因爲內嵌腳本的做用使得圖片要等到css徹底加載完後在加載,即CSS阻塞了圖片的加載。其實質是由於瀏覽器會維持HTML中CSS和JS的順序,即在JS前面出現的CSS文件須要加載、解析完後纔會執行後面的內嵌JS,而內嵌JS又會阻塞後面的內容

(2)外聯腳本

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
    <script type="text/javascript" src="fun.js"></script><!--這裏fun中的內容就是a方法-->
</head>
<body>
<img src="http://www.blogjava.net/images/logo.gif" />
<img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
</body>
</html>

外聯腳本會阻塞後面資源的加載,可是在谷歌瀏覽器中不論是內聯仍是外聯的腳本均不會阻塞

3、爲了避免阻塞頁面腳本的放置位置

(1)儘可能合併腳本減小<script>的出現

(2)儘可能使用外聯腳本並將腳本放置在<body>底部

(3)使用延遲腳本和異步腳本

(4)內嵌腳本放置在window.onload中執行

相關文章
相關標籤/搜索