這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 HTML頁面載入過程會發生什麼?因為瀏覽器網路拉取資源是多線程的,但是dom樹的操作都是在一個線程中的,所以網頁資源的解析、js載入、dom樹渲染都是一個線程執行,所以就會線程任務就會相互搶占,先來先執行。而當瀏覽器載入html文件時,會 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
HTML頁面載入過程會發生什麼?因為瀏覽器
網路拉取資源是多線程
的,但是dom樹的操作都是在一個線程
中的,所以網頁資源的解析、js載入、dom樹渲染都是一個線程執行,所以就會線程任務就會相互搶占,先來先執行。而當瀏覽器載入html文件時,會自上而下載入
。我們先看一下下麵的例子:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"> <style> #app { width: 100px; height: 100px; background-color: red; } </style> <script> alert('代碼的script'); </script> // alert('src的script'); <script src="./test.js"></script> </head> <body> <div id="app"></div> </body> </html>由於html文件的載入自上而下的,所以不管傳入的腳本script是代碼還是鏈接,都是先寫先載入,可能我們會問問什麼style沒有載入,不是沒有載入,而是已經解析並載入了,因為對css進行解析會
生成cssom規則樹
,然後需要結合DOM樹構建渲染樹
,而我們的dom元素是命名在body標簽中定義,由於當前解析的是head標簽,這階段還沒有渲染dom,所以一般在html中操作dom的時機都是在body中的。
在上面例子,我們有沒有發現在解析html文檔過程中,但執行script腳本之前是不是有一段時間在載入,其實是在載入link資源,也就是css資源,等css資源執行完畢後才會執行後面script,這就是CSS阻塞
,這裡阻塞了其後面的js語句的執行。
而style標簽引入的樣式是不會阻塞瀏覽器渲染也不會阻塞DOM解析
,但是可能會出現閃屏現象(使用transition
動畫時)。 上面只是在head標簽中引入樣式,如果是在body標簽中引入樣式,css是否也會阻塞?
-
在link引入前後定義DOM元素:css載入會阻塞後面DOM元素的渲染,以及前面元素的css樣式渲染。
<body> <button class="btn btn-primary">test1</button> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"> <div>test2</div> </body>
-
在link引入前後引入腳本:在link引入樣式前執行腳本,在link引入樣式後執行版本,我們會發現link會阻塞後面腳本的執行,需要等css資源載入完畢才會執行。
我們都知道在html中載入資源除了css,還有js資源載入,既然看了有CSS資源載入阻塞,是不是也有js阻塞?是的,script引入與使用分為兩種方式:head中引入
、body中引入
。
-
在head標簽中引入script:如果是head中引入腳本是不能直接操作DOM渲染,因為DOM還沒有載入與渲染。那麼有辦法可以解決嗎?其實是有的,使用
defer
(延遲執行,等DOM解析完成再執行JS腳本)和async
(非同步執行,保證DOM樹和JS腳本並行執行)。
<head> <script src="./a.js" defer></script> <script src="./a.js" async></script> </head>
- 在body標簽中引入script: 當引入的script腳本後下載並解析完成後,才去載入後面DOM元素,但是script腳本不會影響腳本執行前的DOM元素渲染。所以一般把所有腳本都會丟到
</body>
前。
<body> <script src="https://code.jquery.com/jquery-3.4.1.js"></script> <div>test</div> </body>
所以一般是把引入式(鏈接)放在head標簽內,內聯式一般是放在body內。