国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

js與css的阻塞問(wèn)題詳析

發(fā)布時(shí)間:2021-08-17 12:16 來(lái)源: 閱讀:0 作者:Alaso 欄目: JavaScript 歡迎投稿:712375056

目錄

DOMContentLoaded和load

我們先了解兩個(gè)事件,有助于后面的分析。

load事件:load 應該僅用于檢測一個(gè)完全加載的頁(yè)面 當一個(gè)資源及其依賴(lài)資源已完成加載時(shí),將觸發(fā)load事件。也就是說(shuō),頁(yè)面的html、css、js、圖片等資源都已經(jīng)加載完之后才會(huì )觸發(fā) load 事件。

DOMContentLoaded事件:當初始的 HTML 文檔被完全加載和解析完成之后,DOMContentLoaded 事件被觸發(fā),而無(wú)需等待樣式表、圖像和子框架的完成加載。也就是說(shuō),DOM 樹(shù)已經(jīng)構建完畢就會(huì )觸發(fā) DOMContentLoaded 事件。

js 阻塞了什么

因為js在執行的過(guò)程中可能會(huì )操作DOM,發(fā)生回流和重繪,所以GUI渲染線(xiàn)程與JS引擎線(xiàn)程是互斥的。

在解析HTML過(guò)程中,如果遇到 script 標簽,渲染線(xiàn)程會(huì )暫停渲染過(guò)程,將控制權交給 JS 引擎。內聯(lián)的js代碼會(huì )直接執行,如果是js外部文件,則要下載該js文件,下載完成之后再執行。等 JS 引擎運行完畢,瀏覽器又會(huì )把控制權還給渲染線(xiàn)程,繼續 DOM 的解析。

因此,js會(huì )阻塞DOM樹(shù)的構建。

那么,是否會(huì )阻塞頁(yè)面的顯示呢?我們用下面的代碼來(lái)測試一下。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div>hello world</div>
  <script>
    debugger
  </script>
  <div>hello world2</div>
</body>
</html>

可以看到,這個(gè)頁(yè)面的DOMContentLoaded發(fā)生在2.23s,可見(jiàn)js阻塞了DOM樹(shù)的構建。但是,頁(yè)面上卻幾乎在一瞬間顯示了hello world,說(shuō)明js不會(huì )阻塞位于它之前的dom元素的渲染。

現代瀏覽器為了更好的用戶(hù)體驗,渲染引擎將嘗試盡快在屏幕上顯示的內容。它不會(huì )等到所有DOM解析完成后才布局渲染樹(shù)。而是當js阻塞發(fā)生時(shí),會(huì )將已經(jīng)構建好的DOM元素渲染到屏幕上,減少白屏的時(shí)間。

這也是為什么我們會(huì )將script標簽放到body標簽的底部,因為這樣就不會(huì )影響前面的頁(yè)面的渲染。

css 阻塞了什么

當我們解析 HTML 時(shí)遇到 link 標簽或者 style 標簽時(shí),就會(huì )計算樣式,構建CSSOM。

css不會(huì )阻塞dom樹(shù)的構建,但是會(huì )阻塞頁(yè)面的顯示。我們依然用一個(gè)例子來(lái)測試:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" type="text/css" >
</head>
<body>
  <div class="woo-spinner-filled">hello world</div>
  <div>hello world2</div>
</body>
</html>

使用一個(gè)外部css文件,打開(kāi)Slow 3G模擬比較慢的網(wǎng)速,可以看到,DOMContentLoaded事件觸發(fā)只用了30ms,頁(yè)面此時(shí)依然是空白,而幾乎是loaded事件2.92s發(fā)生時(shí),頁(yè)面才出現內容。

原因是,瀏覽器在構建 CSSOM 的過(guò)程中,不會(huì )渲染任何已處理的內容。即便 DOM 已經(jīng)解析完畢了,只要 CSSOM 不沒(méi)構建好,頁(yè)面也不會(huì )顯示內容。

只有當我們遇到 link 標簽或者 style 標簽時(shí),才會(huì )構建CSSOM,所以如果 link 標簽之前有dom元素,當加載css發(fā)生阻

<body>
  <div class="woo-spinner-filled">hello world</div>
  <link rel="stylesheet" type="text/css" >
  <div>hello world2</div>
</body>

這樣做會(huì )導致一個(gè)問(wèn)題,就是頁(yè)面閃爍,在css被加載之前,瀏覽器按照默認樣式渲染  <div class="woo-spinner-filled">hello world</div>,當css加載完成,會(huì )為該div計算新的樣式,重新渲染,出現閃爍的效果。

為了避免頁(yè)面閃爍,通常 link 標簽都放在head中。

css會(huì )不會(huì )阻塞后面js執行?答案是會(huì )!

JS 的作用在于修改,它幫助我們修改網(wǎng)頁(yè)的方方面面:內容、樣式以及它如何響應用戶(hù)交互。這“方方面面”的修改,本質(zhì)上都是對 DOM 和 CSSDOM 進(jìn)行修改。當在JS中訪(fǎng)問(wèn)了CSSDOM中某個(gè)元素的樣式,那么這時(shí)候就需要等待這個(gè)樣式被下載完成才能繼續往下執行JS腳本。

運行下面這個(gè)例子,就會(huì )發(fā)現等css加載完成后,才會(huì )在控制臺打印“this is a test”。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" type="text/css" >
</head>
<body>
  <div class="woo-spinner-filled">hello world</div>
  <div>hello world2</div>
  <script>
    console.log('this is a test')
  </script>
</body>
</html>

優(yōu)化

使用內聯(lián) JavaScript 和 CSS,這樣獲取到 HTML 文件之后就可以直接開(kāi)始渲染流程了。

并不是所有的場(chǎng)合都適合內聯(lián),那么還可以盡量減少文件大小,比如通過(guò) webpack 等構建工具刪除無(wú)用代碼、壓縮 css、JavaScript 文件的體積;并且啟用 cdn/' target='_blank'>CDN 加快文件的下載速度。

對于大的 CSS 文件,可以通過(guò)媒體查詢(xún)屬性,將其拆分為多個(gè)不同用途的 CSS 文件,這樣只有在特定的場(chǎng)景下才會(huì )加載特定的 CSS 文件。

如果 JavaScript 文件中沒(méi)有操作 DOM 相關(guān)代碼,就可以將該 JavaScript 腳本設置為異步加載,通過(guò) async 或 defer 來(lái)標記代碼。

<script src="index.js"></script>
//瀏覽器必須等待 index.js 加載和執行完畢才能去做其它事情。

<script async src="index.js"></script>
//index.js 的加載是異步的,加載時(shí)不會(huì )阻塞瀏覽器做任何其它的事情。
//當它加載結束,JS 腳本會(huì )立即執行。

<script defer src="index.js"></script>
//JS 的加載是異步的,執行是被推遲的。
//使用了 defer 標記的腳本文件,會(huì )等整個(gè)文檔解析完成,在 DOMContentLoaded 事件觸發(fā)之前執行

總結

到此這篇關(guān)于js與css的阻塞問(wèn)題的文章就介紹到這了,更多相關(guān)js與css阻塞內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

玩弄人妻少妇500系列视频| 色窝窝亚洲AV网在线观看 | 亚洲男同志GAY片| 亚洲精品无码不卡在线播放| 真实乱子伦露脸自拍| 6080YYY午夜理论AA片|