LCP 元素竟然是 Title 區(qū)域
一般情況下頁面 LCP 元素是首屏最大的圖片,即使托管在了 CDN、并且 preload 圖片下載仍需要一定時間,但最近分析團隊負責的某個頁面時候竟然發(fā)現 20% 左右的頁面訪問 LCP 竟然是一個沒有任何圖片的文本區(qū)域,僅次于頁面首屏最大圖片
在 webpagetest 測試看 Filmstrip View,確實可以看到文案區(qū)域空白時候,下面 DOM 已經被渲染
是什么阻止了頁面文案的渲染?
web font 渲染時機
既然是文本渲染問題很自然聯想到字體問題,為了保證品牌一致性和跨平臺一致性,網站使用了 web font。web font 有多種格式,在以往是個復雜的選擇問題,自從 WOFF2 格式出現后就不用糾結了,WOFF2 使用了 Brotli,因此其壓縮效果比 WOFF 高出 30%,從而可以減少下載數據量,從而提升性能,同時 WOFF2 瀏覽器支持也特別好
可以使用 @font-face
在頁面引入 web font
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 100;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxFIzIXKMnyrYk.woff2) format('woff2');
}
可能在大部分人想象中使用 @font-face 后文本的渲染過程是這樣的
下載 web font
在下載期間先用備選字體渲染
web font 字體下載完成后使用該字體替換
但實際這只是 @font-face 渲染方式的一種,而且不是默認的,@font-face 由 font-display
屬性決定 web font 在下載時間和可用時間是如何展示的
auto:瀏覽器使用默認的字體加載策略,不同瀏覽器處理方式不同,但一般是有一個非常短暫的阻塞期,如果字體在這段時間內加載完成則使用該字體,否則它將使用備用字體,并且在字體文件加載完成后切換到定義的字體
block:在字體請求的階段內文本不可見,只有在字體文件加載完成后文本才會顯示。如果在這個階段(大約為3秒)字體文件沒有加載完成,將使用備用字體渲染,并且在加載完成后切換到請求的字體
swap:在字體文件加載過程中瀏覽器會立即使用備用字體渲染,一旦字體文件加載完成,瀏覽器會將文本切換到請求的字體。這能有效避免文本在加載字體文件時不可見,但可能會導致文本樣式突然改變
fallback:結合了block和swap兩種情況。在字體加載的前100ms(或者更長,取決于瀏覽器)內,瀏覽器會阻塞文本的渲染。之后如果字體尚未加載,將使用備用字體。但與swap不同的是,在備用字體顯示的一段時間后,如果請求的字體仍未加載完成,瀏覽器就不會再執(zhí)行字體切換,以避免文本樣式的突變
optional:與fallback類似,但它給予瀏覽器更大的自由度來決定是否下載字體文件。如果字體文件在一定時間內沒有加載完成,瀏覽器可能選擇不再加載它。這個值對于用戶體驗和性能都有可能帶來提升,因為它減輕了網絡負擔,但可能會有字體不一致的風險
在字體下載比較慢的情況下
web font 下載提速
但在大部分網站無論是字體閃爍、還是不使用規(guī)定的 web font 渲染都是問題,因此我們的主要思路需要集中在如何提升 web font 下載速度
提前加載 web font
令人意外的是瀏覽器解析到 @font-face 聲明時候并不會下載對應的字體,只有解析到使用了該 font-face 中定義字體的頁面元素時,才會下載對應的字體
這也就意味著把 @font-face 聲明寫在頁面頂部是沒有作用的,可以使用 preconnect 或者 preload 提前讓瀏覽器提前建連和下載字體文件,尤其是在頁面應用了流式渲染時候有奇效
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" href="https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxFIzIXKMnyrYk.woff2" as="font" type="font/woff2" crossorigin>
字體子集化縮減 web font 體積
字體子集化是一種減小字體文件大小的技術,它通過移除字體文件中不需要的字符來實現。由于許多字體文件包含了成千上萬的字符,這些字符包括各種語言的字母、符號、標點、數字、空格、換行符以及裝飾性和特殊字符。然而一個特定的網站或應用可能不需要這么多字符
在 @font-face 內部可以使用 unicode-range
定義字體應用到的 Unicode 字符范圍。這樣可以將字體文件拆分成多個,當字符在定義的范圍內時,瀏覽器才會下載并使用對應的字體文件
例如網站主要使用英文,但偶爾包含一些拉丁擴展字符,可以用 unicode-range 來指定只加載這些字符的字體:
@font-face {
font-family: 'MyFont';
src: url('myfont.woff2') format('woff2');
unicode-range: U+00-FF; /* 基本拉丁字母及擴展 */
}
通過將字體文件限制為僅包含網站或應用所需的字符,可以減少文件的大小,得益于上面提到的字體當被使用到才會下載的機制,從而減少下載時間和帶寬使用,提高網站的加載速度和性能
Google Roboto 字體的定義 fonts.googleapis.com/css2?family…
/* cyrillic-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKKTU1Kvnz.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKKTU1Kvnz.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKKTU1Kvnz.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
...
優(yōu)化效果
為了保障用戶體驗,選擇了對字體文件 preload
<link rel="preload" href="xxxx.woff2" as="font" type="font/woff2" crossorigin>
這樣文本部分終于第一時間加載
作者:謙行
鏈接:https://juejin.cn/post/7371712684797280256
來源:稀土掘金
著作權歸作者所有。商業(yè)轉載請聯系作者獲得授權,非商業(yè)轉載請注明出處。
該文章在 2024/5/29 14:36:53 編輯過