亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時(shí)間:2021年07月14日 16:06:41   作者:Alaso  
JS具有阻塞特性,當(dāng)瀏覽器在執(zhí)行js代碼時(shí),不能同時(shí)做其它事情,下面這篇文章主要給大家介紹了關(guān)于js與css阻塞問(wèn)題的相關(guān)資料,需要的朋友可以參考下

DOMContentLoaded和load

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

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

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

js 阻塞了什么

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

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

因此,js會(huì)阻塞DOM樹的構(gòu)建。

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

<!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,可見js阻塞了DOM樹的構(gòu)建。但是,頁(yè)面上卻幾乎在一瞬間顯示了hello world,說(shuō)明js不會(huì)阻塞位于它之前的dom元素的渲染。

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

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

css 阻塞了什么

當(dāng)我們解析 HTML 時(shí)遇到 link 標(biāo)簽或者 style 標(biāo)簽時(shí),就會(huì)計(jì)算樣式,構(gòu)建CSSOM。

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

<!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文件,打開Slow 3G模擬比較慢的網(wǎng)速,可以看到,DOMContentLoaded事件觸發(fā)只用了30ms,頁(yè)面此時(shí)依然是空白,而幾乎是loaded事件2.92s發(fā)生時(shí),頁(yè)面才出現(xiàn)內(nèi)容。

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

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

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

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

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

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

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

運(yùn)行下面這個(gè)例子,就會(huì)發(fā)現(xiàn)等css加載完成后,才會(huì)在控制臺(tái)打印“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)化

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

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

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

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

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

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

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

總結(jié)

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

相關(guān)文章

  • 詳解layui?laydate選擇時(shí)間的回調(diào)方法

    詳解layui?laydate選擇時(shí)間的回調(diào)方法

    這篇文章主要介紹了layui?laydate選擇時(shí)間的回調(diào)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • JS判斷元素是否在數(shù)組內(nèi)的實(shí)現(xiàn)代碼

    JS判斷元素是否在數(shù)組內(nèi)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了JS判斷元素是否在數(shù)組內(nèi)的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2016-03-03
  • JavaScript中實(shí)現(xiàn)new的兩種方式引發(fā)的探究

    JavaScript中實(shí)現(xiàn)new的兩種方式引發(fā)的探究

    眾所周知JS中new的作用是通過(guò)構(gòu)造函數(shù)來(lái)創(chuàng)建一個(gè)實(shí)例對(duì)象,這篇文章主要給大家介紹了關(guān)于JavaScript中實(shí)現(xiàn)new的兩種方式引發(fā)的相關(guān)資料,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 微信小程序webView嵌入H5的方法實(shí)例

    微信小程序webView嵌入H5的方法實(shí)例

    web-view是小程序提供的一個(gè)可以直連h5頁(yè)面的組件,只要傳遞一個(gè)h5頁(yè)面的地址,就可以在小程序里直接打開預(yù)覽該h5頁(yè)面,這篇文章主要給大家介紹了微信小程序webView嵌入H5的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • JavaScript中cookie工具函數(shù)封裝的示例代碼

    JavaScript中cookie工具函數(shù)封裝的示例代碼

    這篇文章給大家主要介紹了JavaScript中cookie工具函數(shù)的封裝,文中給出了詳細(xì)的實(shí)現(xiàn)步驟和示例代碼,相信會(huì)對(duì)大家的理解很有幫助,有需要的朋友們下面來(lái)一起看看吧。
    2016-10-10
  • layer.msg()去掉默認(rèn)時(shí)間,實(shí)現(xiàn)手動(dòng)關(guān)閉的方法

    layer.msg()去掉默認(rèn)時(shí)間,實(shí)現(xiàn)手動(dòng)關(guān)閉的方法

    今天小編就為大家分享一篇layer.msg()去掉默認(rèn)時(shí)間,實(shí)現(xiàn)手動(dòng)關(guān)閉的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-09-09
  • 微信小程序開發(fā)之實(shí)現(xiàn)心情記事本

    微信小程序開發(fā)之實(shí)現(xiàn)心情記事本

    這篇文章主要為大家詳細(xì)介紹了如何通過(guò)微信小程序開發(fā)一個(gè)簡(jiǎn)單的心情記事本,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以和小編一起學(xué)習(xí)一下
    2023-01-01
  • js中json處理總結(jié)之JSON.parse

    js中json處理總結(jié)之JSON.parse

    parse是解析json數(shù)據(jù)多種方法中的其中一種。這篇文章主要介紹了js中json處理總結(jié)之JSON.parse,需要的朋友可以參考下
    2016-10-10
  • 詳解cocoscreater預(yù)制體prefab

    詳解cocoscreater預(yù)制體prefab

    這篇文章主要介紹了詳解cocoscreater預(yù)制體prefab的作用和使用方法,對(duì)此感興趣的同學(xué),可以回去試一試
    2021-04-04
  • JS數(shù)組方法join()用法實(shí)例分析

    JS數(shù)組方法join()用法實(shí)例分析

    這篇文章主要介紹了JS數(shù)組方法join()用法,結(jié)合實(shí)例形式分析了JS數(shù)組join()方法具體功能、定義、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2020-01-01

最新評(píng)論