欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用preload預(yù)加載頁面資源時(shí)注意事項(xiàng)

 更新時(shí)間:2020年02月03日 16:49:40   作者:螞蟻金服數(shù)據(jù)體驗(yàn)技術(shù)團(tuán)隊(duì)  
本文主要介紹 preload 的使用,以及與 prefetch 的區(qū)別。然后會(huì)聊聊瀏覽器的加載優(yōu)先級(jí),大家一定要認(rèn)真看完

preload 提供了一種聲明式的命令,讓瀏覽器提前加載指定資源(加載后并不執(zhí)行),在需要執(zhí)行的時(shí)候再執(zhí)行。提供的好處主要是

將加載和執(zhí)行分離開,可不阻塞渲染和 document 的 onload 事件

提前加載指定資源,不再出現(xiàn)依賴的 font 字體隔了一段時(shí)間才刷出

如何使用 preload

使用 link 標(biāo)簽創(chuàng)建

<!-- 使用 link 標(biāo)簽靜態(tài)標(biāo)記需要預(yù)加載的資源 -->
<link rel="preload" href="/path/to/style.css" rel="external nofollow" as="style">
<!-- 或使用腳本動(dòng)態(tài)創(chuàng)建一個(gè) link 標(biāo)簽后插入到 head 頭部 -->
<script>
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'style';
link.href = '/path/to/style.css';
document.head.appendChild(link);
</script>

使用 HTTP 響應(yīng)頭的 Link 字段創(chuàng)建

Link: <https://example.com/other/styles.css>; rel=preload; as=style

如我們常用到的 antd 會(huì)依賴一個(gè) CDN 上的 font.js 字體文件,我們可以設(shè)置為提前加載,以及有一些模塊雖然是按需異步加載,但在某些場(chǎng)景下知道其必定會(huì)加載的,則可以設(shè)置 preload 進(jìn)行預(yù)加載,如:

<link rel="preload" as="font"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<link rel="preload" as="script"  rel="external nofollow" >
<link rel="preload" as="script"  rel="external nofollow" >

如何判斷瀏覽器是否支持 preload

目前我們支持的瀏覽器主要為高版本 Chrome,所以可放心使用 preload 技術(shù)。 其他環(huán)境在 caniuse.com 上查到的支持情況如下:

在不支持 preload 的瀏覽器環(huán)境中,會(huì)忽略對(duì)應(yīng)的 link 標(biāo)簽,而若需要做特征檢測(cè)的話,則:

const isPreloadSupported = () => {
const link = document.createElement('link');
const relList = link.relList;
if (!relList || !relList.supports) {
return false;
}
return relList.supports('preload');
};

如何區(qū)分 preload 和 prefetch

preload 是告訴瀏覽器頁面必定需要的資源,瀏覽器一定會(huì)加載這些資源;

prefetch 是告訴瀏覽器頁面可能需要的資源,瀏覽器不一定會(huì)加載這些資源。

preload 是確認(rèn)會(huì)加載指定資源,如在我們的場(chǎng)景中,x-report.js 初始化后一定會(huì)加載 PcCommon.js 和 TabsPc.js, 則可以預(yù)先 preload 這些資源;

prefetch 是預(yù)測(cè)會(huì)加載指定資源,如在我們的場(chǎng)景中,我們?cè)陧撁婕虞d后會(huì)初始化首屏組件,當(dāng)用戶滾動(dòng)頁面時(shí),會(huì)拉取第二屏的組件,若能預(yù)測(cè)用戶行為,則可以 prefetch 下一屏的組件。

preload 將提升資源加載的優(yōu)先級(jí)

使用 preload 前,在遇到資源依賴時(shí)進(jìn)行加載:

使用 preload 后,不管資源是否使用都將提前加載:

可以看到,preload 的資源加載順序?qū)⒈惶崆埃?/p>

避免濫用 preload

使用 preload 后,Chrome 會(huì)有一個(gè)警告:

如上文所言,若不確定資源是必定會(huì)加載的,則不要錯(cuò)誤使用 preload,以免本末倒置,給頁面帶來更沉重的負(fù)擔(dān)。

當(dāng)然,可以在 PC 中使用 preload 來刷新資源的緩存,但在移動(dòng)端則需要特別慎重,因?yàn)榭赡軙?huì)浪費(fèi)用戶的帶寬。

避免混用 preload 和 prefetch

preload 和 prefetch 混用的話,并不會(huì)復(fù)用資源,而是會(huì)重復(fù)加載。

<link rel="preload"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" as="font">
<link rel="prefetch"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" as="font">

使用 preload 和 prefetch 的邏輯可能不是寫到一起,但一旦發(fā)生對(duì)用一資源 preload 或 prefetch 的話,會(huì)帶來雙倍的網(wǎng)絡(luò)請(qǐng)求,這點(diǎn)通過 Chrome 控制臺(tái)的網(wǎng)絡(luò)面板就能甄別:

避免錯(cuò)用 preload 加載跨域資源

若 css 中有應(yīng)用于已渲染到 DOM 樹的元素的選擇器,且設(shè)置了 @font-face 規(guī)則時(shí),會(huì)觸發(fā)字體文件的加載。 而字體文件加載中時(shí),DOM 中的這些元素,是處于不可見的狀態(tài)。對(duì)已知必加載的 font 文件進(jìn)行預(yù)加載,除了有性能提升外,更有體驗(yàn)優(yōu)化的效果。

在我們的場(chǎng)景中,已知 antd.css 會(huì)依賴 font 文件,所以我們可以對(duì)這個(gè)字體文件進(jìn)行 preload:

<link rel="preload" as="font"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >

然而我發(fā)現(xiàn)這個(gè)文件加載了兩次:

原因是對(duì)跨域的文件進(jìn)行 preload 的時(shí)候,我們必須加上 crossorigin 屬性:

<link rel="preload" as="font" crossorigin  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >

再看一下網(wǎng)絡(luò)請(qǐng)求,就變成一條了。

W3 規(guī)范是這么解釋的:

Preload links for CORS enabled resources, such as fonts or images with a crossorigin attribute, must also include a crossorigin attribute, in order for the resource to be properly used.

那為何會(huì)有兩條請(qǐng)求,且優(yōu)先級(jí)不一致,又沒有命中緩存呢?這就得引出下一個(gè)話題來解釋了。

不同資源加載的優(yōu)先級(jí)規(guī)則

我們先來看一張圖:

這張表詳見:Chrome Resource Priorities and Scheduling

這張圖表示的是,在 Chrome 46 以后的版本中,不同的資源在瀏覽器渲染的不同階段進(jìn)行加載的優(yōu)先級(jí)。 在這里,我們只需要關(guān)注 DevTools Priority 體現(xiàn)的優(yōu)先級(jí),一共分成五個(gè)級(jí)別:

Highest 最高

Hight 高

Medium 中等

Low 低

Lowest 最低

html 主要資源,其優(yōu)先級(jí)是最高的

css 樣式資源,其優(yōu)先級(jí)也是最高的

CSS(match) 指的是對(duì)已有的 DOM 具備規(guī)則的有效的樣式文件。

script 腳本資源,優(yōu)先級(jí)不一

前三個(gè) js 文件是寫死在 html 中的靜態(tài)資源依賴,后三個(gè) js 文件是根據(jù)首屏按需異步加載的組件資源依賴,這正驗(yàn)證了這個(gè)規(guī)則。

font 字體資源,優(yōu)先級(jí)不一

樣式文件中有一個(gè) @font-face 依賴一個(gè) font 文件,樣式文件中依賴的字體文件加載的優(yōu)先級(jí)是 Highest; 在使用 preload 預(yù)加載這個(gè) font 文件時(shí),若不指定 crossorigin 屬性(即使同源),則會(huì)采用匿名模式的 CORS 去加載,優(yōu)先級(jí)是 High,看下圖對(duì)比: 第一條 High 優(yōu)先級(jí)也就是 preload 的請(qǐng)求:

第二條 Highest 也就是樣式引入的請(qǐng)求:

可以看到,在 preload 的請(qǐng)求中,缺少了一個(gè) origin 的請(qǐng)求頭字段,表示這個(gè)請(qǐng)求是匿名的請(qǐng)求。 讓這兩個(gè)請(qǐng)求能共用緩存的話,目前的解法是給 preload 加上 crossorigin 屬性,這樣請(qǐng)求頭會(huì)帶上 origin, 且與樣式引入的請(qǐng)求同源,從而做到命中緩存:

<link rel="preload" as="font" crossorigin  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >

這么請(qǐng)求就只剩一個(gè):

在網(wǎng)絡(luò)瀑布流圖中,也顯示成功預(yù)加載且后續(xù)命中緩存不再二次加載:

總結(jié)

preload 是個(gè)好東西,能告訴瀏覽器提前加載當(dāng)前頁面必須的資源,將加載與解析執(zhí)行分離開,做得好可以對(duì)首次渲染帶來不小的提升,但要避免濫用,區(qū)分其與 prefetch 的關(guān)系,且需要知道 preload 不同資源時(shí)的網(wǎng)絡(luò)優(yōu)先級(jí)差異。

preload 加載頁面必需的資源如 CDN 上的字體文件,與 prefetch 預(yù)測(cè)加載下一屏數(shù)據(jù),興許是個(gè)不錯(cuò)的組合。

更多關(guān)于preload預(yù)加載頁面的文章大家可以看看下面的相關(guān)鏈接

相關(guān)文章

最新評(píng)論