我應該使用JavaScript加載我的Web字體嗎? (翻譯文)

原文 : https://www.filamentgroup.com/lab/js-web-fonts.html

當它們首次引入時,Web字體主要是一個CSS功能,對於許多Web開發人員來說,他們總是使用CSS加載它們(僅此而已)。但是在過去的十年中,許多瀏覽器中的默認Web字體加載行為使得僅使用CSS的方法成為我們頁面文本呈現的賭博,而深思熟慮的開發人員轉而採用更安全的JavaScript方法。最近,瀏覽器對新的和更安全的CSS策略的支持讓一些開發人員感到疑惑:是否需要加載Web字體的JavaScript方法?它們有用嗎?讓我們深入研究。

負責任的Web字體加載的時代

Internet Explorer是唯一支持Web字體的瀏覽器,並且以漸進式增強友好的方式實現了這一點,事後看來,它似乎非常具有前瞻性。在Internet Explorer中加載Web字體時,後備文本在加載期間可見:健壯且可讀。

2008年,Safari添加了Web字體支持。不幸的是,Safari選擇在加載字體文件時將所有Web字體文本設置為不可見文本。值得注意的是,這些不可見的文本不包括這些請求的合理超時 — 將Web字體請求轉換為頁面上文本的單點故障。如果您對字體文件的請求停止 — 您的文本可以無限期地隱藏,除了重新開始並重新加載整個頁面之外,幾乎不向用戶提供任何追索權。因此,需要JavaScript方法來解決此問題並負責任地加載Web字體。

Firefox是第一個在2011年為其字體加載引入隱身超時的Web瀏覽器 — 如果Web字體在三秒內未加載,則渲染回退字體。 Chrome在2014年緊隨其後,Safari是2016年採用超時的最後一個主要瀏覽器。值得注意的是,這標誌著加載Web字體的CSS專用方法不再是網頁單點故障的一年。但是,在加載字體時,開發人員對文本可見性的控制仍然有限。

2018年採用字體顯示標誌著字體加載行為的新紀元。我們的CSS-only savior,font-display是一個簡單的CSS描述符,允許開發人員收回對web字體加載的文本隱形行為的控制。

@font-face {
font-family: Noto Serif;
src: url(notoserif.woff2) format('woff2'),
url(notoserif.woff) format('woff');
font-display: swap;
}

隨著瀏覽器支持的不斷發展,在字體加載時,字體顯示可以緩解JavaScript作為可見文本的要求!這為字體加載提供了一個非常簡單的基礎,對於許多站點而言“足夠好”。

確實,使用字體顯示描述符可以使您達到可接受的Web字體加載級別 — 但我們可以做得更好!讓我們看看我們可以做出的一些其他改進:

  1. 集體重繪
    當您為單個字體加載多個字體文件時,每個請求都可能會產生單獨的重繪和重排。通過將其分組為單個重繪來減少頁面上的移動量。您可以在“問題與字體顯示和重排”中閱讀更多相關信息。

您的JavaScript可能如下所示:

if ("fonts" in document) {
var font = new FontFace(
"Noto Serif",
"url(notoserif.woff2) format('woff2'), url(notoserif.woff) format('woff')"
);

var fontBold = new FontFace(
"Noto Serif",
"url(notoserif-bold.woff2) format('woff2'), url(notoserif-bold.woff) format('woff')",
{ weight: "700" }
);

Promise.all([
font.load(),
fontBold.load()
]).then(function(loadedFonts) {

// Render them at the same time
loadedFonts.forEach(function(font) {
document.fonts.add(font);
});
});
}

當用戶啟用了數據保護模式時,您可以使用“保存數據”首選項選擇退出字體。閱讀更多關於使用Google網絡基礎知識上的保存數據交付快速和輕量級應用程序的更多信息。

function loadFonts() {
/* NOTE: Reuse the Group Repaints code snippet above, here */
}

if( navigator.connection && navigator.connection.saveData ) {
} else {
loadFonts();
}

或者,當用戶啟用Reduce Motion輔助功能選項時,您可以使用首選減少動作首選項(瀏覽器支持)來選擇退出Web字體加載。

要在Mac OS上啟用此功能,請轉至系統偏好設置>輔助功能>減少動作。在iOS上,它是 Settings > General > Accessibility > Reduce Motion.。

說網絡字體重排是動作可能是一個延伸 — 但它將改善頁面穩定性。閱讀更多關於CSS-Tricks的簡化運動媒體查詢簡介。

function loadFonts() {
/* NOTE: Reuse the Group Repaints code snippet above, here */
}

if( "matchMedia" in window && window.matchMedia("(prefers-reduced-motion: reduce)").matches ) {
// do nothing
} else {
loadFonts();
}

為了獲得額外的功勞,我可以想像使用Paint Timing API只有在第一次繪製條目被記錄後Web字體完成加載時才選擇退出渲染。閱讀更多可愛的帖子:由JoséM.Pérez編寫的PerformanceObserver和Paint Timing API。但實際上這可能有點多,即使對我來說也是如此。

您還可以使用網絡信息API(瀏覽器支持)在慢速連接上選擇退出字體。有關詳細信息,請參閱MDN Web文檔上的Network Information API文檔。

function loadFonts() {
/* NOTE: Reuse the Group Repaints code snippet above, here */
}

if( navigator.connection && (navigator.connection.effectiveType === "slow-2g" || navigator.connection.effectiveType === "2g") ) {
// do nothing
} else {
loadFonts();
}

請注意,您可能想要訂閱Network Information API中公開的“更改”事件。小心!在用戶可能已經深入閱讀之後,您不希望您的Web字體加載觸發超級延遲!網絡字體重排後來發生,它感覺越具有破壞性。

不幸的是,在編寫本文時,沒有已知的第三方Web字體主機支持僅CSS的字體顯示描述符。我建議現在使用這些服務時堅持使用JavaScript方法。

正如您所看到的,JavaScript提供的高級Web字體加載控件仍然提供了足夠的價值來保持它。您可以調整頁面的性能配置文件以適應用戶的網絡條件,用戶首選項,改進自託管字體和第三方託管提供商的一般加載行為。

Written by

撰寫任何事情,O型水瓶混魔羯,咖啡愛好者,Full stack/blockchain developer,Founder of Blockchain&Dapps meetup and DeFi-Decentralized-Finance-SG meetup,Udemy teacher。

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store