我正在閱讀異步加載CSS樣式表的方法。一種常見的方法如下:
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">
它工作正常。但是今天我看到一個大型網(wǎng)站使用以下方式加載CSS(他們說是異步加載):
<link rel="preload stylesheet" href="style.css" as="style">
<noscript><link rel="stylesheet" href="style.css"></noscript>
請注意,該鏈接既有預(yù)加載又有樣式表,并且有as = & quot風格& quot最后。我很好奇是不是這樣運作的,還是會是一個阻塞請求?
注意事項:
我已經(jīng)知道異步加載CSS的常用方法,這個問題不是關(guān)于如何做,我只是問關(guān)于上面的方法,因為我沒有看到它在任何地方被記錄。
我看到常見的方法是將預(yù)加載和樣式表分成兩個鏈接,所以我認為在同一個鏈接中使用它們是行不通的,這個問題是為了要求確認。
簡答:是阻塞請求。
長回答: 我為這種情況制作了一個演示,下面是我觀察到的情況。
先決條件 創(chuàng)建一個需要很長時間加載的CSS文件。
在下面的示例中,它將是/style.css,加載需要5秒鐘。內(nèi)容如下:
* {
color: red;
}
因此,當CSS成功加載時,頁面中的所有文本都將顯示為紅色。
注意事項:
所有的測試都是在本地執(zhí)行的,所以加載HTML只需要0秒鐘。
所有的測試都是在Chrome v113,Windows 10 64位上進行的。
測試: 正常情況下:
<html>
<head>
<!-- normal way -->
<link
rel="stylesheet"
href="/style.css" />
</head>
<body>
<h1>normal way</h1>
</body>
</html>
媒體打印+上傳:
<html>
<head>
<!-- media print then onload -->
<link
rel="stylesheet"
href="/style.css"
media="print"
onload="this.onload = null;this.media='all'" />
</head>
<body>
<h1>media print then onload</h1>
</body>
</html>
預(yù)加載+加載:
<html>
<head>
<!-- preload then onload -->
<link
href="/style.css"
rel="preload"
as="style"
onload="this.onload = null;this.rel='stylesheet'" />
</head>
<body>
<h1>preload then onload</h1>
</body>
</html>
在同一鏈接上預(yù)加載+樣式表:
<html>
<head>
<!-- preload + stylesheet -->
<link
rel="preload stylesheet"
href="/style.css"
as="style" />
</head>
<body>
<h1>preload + stylesheet</h1>
</body>
</html>
結(jié)果 測試1:頁面加載需要5秒鐘,加載時樣式正確。
測試2:頁面立即加載,需要5秒鐘來獲得正確的樣式。 標簽欄中的加載圖標出現(xiàn)5秒鐘。
測試3:頁面立即加載,需要5秒鐘來獲得正確的樣式。 沒有加載圖標。
測試4:頁面加載需要5秒鐘,加載時樣式正確。 (行為與測試1相同)。
在同一個rel屬性中添加多個關(guān)鍵字將為每個關(guān)鍵字創(chuàng)建一個(內(nèi)部)鏈接。 這意味著當您這樣做時& ltlink rel = & quot預(yù)加載樣式表& quotas = & quot風格& quothref = & quot...您將擁有一個非阻塞預(yù)加載鏈接和一個潛在阻塞樣式表鏈接。 所以這不能讓樣式表以非阻塞的方式加載,因為樣式表會阻塞和禁用預(yù)加載帶來的任何好處。
似乎可以得到一個非渲染阻塞& ltlink rel = & quot樣式表& quot& gt通過在& ltbody & gt,雖然我不確定如何& quot防彈& quot這是。
/* We're in <head> here */
:root { --red-500: green; }
span { color: var(--red-500); }
<span>If the rendering is not blocked I should be green then red</span>
<link rel="stylesheet" >