摘要:在字體的過程中,先用一種最接近目標(biāo)字體的安全字體來顯示,等字體文件加載完后進(jìn)行替換。第個(gè)方案是一種迫不得已的選擇,在用戶眼皮底下更換字體,是非常影響體驗(yàn)的,好處是字體屬于異步加載,不會(huì)阻塞文本顯示。
問題
最近在做一個(gè)項(xiàng)目時(shí),遇到了這樣一個(gè)問題:網(wǎng)頁大標(biāo)題要用設(shè)計(jì)師指定的中文字體,該字體文件比較大,瀏覽器加載字體文件的過程中是不會(huì)顯示使用該字體的文本的,于是出現(xiàn)了初次打開網(wǎng)頁時(shí)有一段時(shí)間“No title”的BUG。
解決方案針對(duì)該問題,筆者能想到以下幾種解決方案(歡迎補(bǔ)充):
把文字做成png圖片,或改為路徑后做成SVG圖片,考慮做成base64內(nèi)嵌到CSS文件。
使用字體工具,將字體包中沒用到的字符刪除來減小字體文件的體積(npm上也有這樣的優(yōu)秀JS庫)。
方案1的升級(jí)版,在所有用到這個(gè)字體的文本中,把首屏出現(xiàn)的文本做成圖片,后面的文本依然使用字體包,并在打開首頁時(shí)就加載字體包。
方案2的升級(jí)版,在向服務(wù)器請(qǐng)求字體的時(shí)候,由服務(wù)端分析document中所有用到的字符,動(dòng)態(tài)生成字體包后返回給瀏覽器端。
在loading字體的過程中,先用一種最接近目標(biāo)字體的安全字體來顯示,等字體文件加載完后進(jìn)行替換。
打死設(shè)計(jì)師,想用啥用啥。
方案對(duì)比與選擇由于后續(xù)的頁面內(nèi)容也有不少文本會(huì)用到該字體,且考慮今后網(wǎng)站維護(hù)成本,所以1、2兩個(gè)解決方案不適合本項(xiàng)目。
第3個(gè)方案最省事,做快速開發(fā)的話比較合適,但代碼復(fù)用性不高,程序也不夠健壯,例如低網(wǎng)速情況下,有可能會(huì)出現(xiàn)字體包未完全加載時(shí)用戶已經(jīng)滑到下一頁,而這一頁中有文本是使用了目標(biāo)字體包從而不顯示的情況。
第4個(gè)方案需要后端開發(fā)的配合,要考慮如何判斷所有用到的字符,并且在JS向document中寫入新的字符時(shí),要請(qǐng)求增量字體包,會(huì)較大程度地增加CDN服務(wù)端負(fù)擔(dān)(主要是怕跟后端開發(fā)撕逼)。
第5個(gè)方案是一種迫不得已的選擇,在用戶眼皮底下更換字體,是非常影響體驗(yàn)的,好處是字體屬于異步加載,不會(huì)阻塞文本顯示。
最后一個(gè)方案成本比較高,需要搭上開發(fā)人員的下半輩子,好處是可以從根本上解決這個(gè)BUG,永訣后患。被逼急的程序員可以嘗試下。
結(jié)合項(xiàng)目特點(diǎn),最終選擇方案5。
實(shí)現(xiàn)過程整個(gè)過程邏輯非常簡單:首先標(biāo)題所用的class在CSS中被定義了一個(gè)最接近目標(biāo)字體的安全字體,然后等待字體文件加載,加載完成后將標(biāo)題的class換成自定義字體的class。
首先設(shè)好兩個(gè)CSS屬性,一個(gè)是用最接近目標(biāo)字體的安全字體,用于默認(rèn)字體,第二個(gè)是自定義字體:
/* 定義字體 */ @font-face{ font-family: Lanting_light; src: url("../res/font/goDieDesigner.woff"); } /* 安全字體,用于默認(rèn) */ .lanting_l{ font-family: Arial, Helvetica, sans-serif; } /* 自定義字體 */ .lanting_light{ font-family: "Lanting_light",Arial, Helvetica, sans-serif; }
元素設(shè)置成默認(rèn)字體:
我是一段可愛的文字,啾咪~
寫一個(gè)函數(shù),用于替換元素的class,在字體文件加載完成后執(zhí)行它:
function onLoadedFont() { ele = document.getElementsByClassName("Lanting_l"); for (let i = 0; i < ele.length; i++){ ele[i].classList.add("Lanting_light"); ele[i].classList.remove("Lanting_l"); } }
接下來是整個(gè)問題的核心:如何判斷字體文件已被加載?
一個(gè)html元素,可以用監(jiān)聽load事件來判斷加載,但字體不是html元素,無法監(jiān)聽。
再來看一下需求,字體文件是從用戶打開頁面時(shí)就要開始加載了,所以只要讓字體一開始就加載,然后監(jiān)聽window.load事件就好了:
window.addEventListener("load",onLoadedFont);
PS:這里不太嚴(yán)謹(jǐn),可能會(huì)有其他大體積資源加載拖慢load事件,所以大文件最好用lazyload。MDN提供了一個(gè)屬性可以判斷字體加載,但是目前兼容性還有一些問題,這里就先不用了,感興趣的可以看一下這里。小弟才疏學(xué)淺,如有大神知道其他監(jiān)聽字體文件加載的方法,還請(qǐng)留言告知,謝謝~
然后就是要做些什么讓字體文件一開始就去加載了,要知道不同瀏覽器什么時(shí)候會(huì)去加載一個(gè)字體,可以參考這篇文章。
在HTML中創(chuàng)建一個(gè)文本標(biāo)簽,讓它去用這個(gè)需要被加載的字體,并且讓這個(gè)文本不要出現(xiàn)在視窗中:
字體
最后擦個(gè)屁股,load完成后把上述已經(jīng)被榨干剩余價(jià)值的節(jié)點(diǎn)刪掉:
window.addEventListener("load",function(){ let dev = document.getElementsByClassName("Lanting_light"); for (let i = 0; i < dev.length; i++){ dev[i].parentElement.removeChild(dev[i]); } //必須先刪除舊節(jié)點(diǎn)后再修改需要改的節(jié)點(diǎn),否則文本節(jié)點(diǎn)會(huì)被刪掉 onLoadedFont(); });
到這里,整個(gè)功能就完成了。
總結(jié)總結(jié)一下,這個(gè)方案可以讓字體文件沒有加載完的時(shí)候,先用一個(gè)接近的安全字體讓文本先顯示出來,待字體加載完后再換字體,核心的點(diǎn)是監(jiān)聽字體文件的加載,因?yàn)镸DN上提供的document.font是一個(gè)實(shí)驗(yàn)性功能,兼容性不是很好,所以這里用了投機(jī)取巧的辦法去監(jiān)聽window.load,可能會(huì)被其他大文件阻塞,也會(huì)拖慢監(jiān)聽window.load的其他函數(shù),所以在項(xiàng)目中還是要取舍,沒有完美的方案,只有最合適的方案。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/106210.html
摘要:火狐推遲對(duì)字體的支持,重點(diǎn)放在格式上。網(wǎng)絡(luò)字體的效率字體文件的體積可能非常的大尤其是對(duì)于漢字,而且需要額外的連接,這些都會(huì)降低網(wǎng)站頁面的加載速度。 最近興致上來,就想更換了那Blog標(biāo)題字體(漢字的);網(wǎng)上搜索了一番,發(fā)現(xiàn)蘇新詩柳繁體這款甚合我心;然后就著手搞將了起來,分分鐘也算是替換了;但,這僅僅是此次折騰的開始;這就細(xì)細(xì)道來作為學(xué)習(xí)筆記記載。 原文首發(fā)鏈接http://www.je...
摘要:火狐推遲對(duì)字體的支持,重點(diǎn)放在格式上。網(wǎng)絡(luò)字體的效率字體文件的體積可能非常的大尤其是對(duì)于漢字,而且需要額外的連接,這些都會(huì)降低網(wǎng)站頁面的加載速度。 最近興致上來,就想更換了那Blog標(biāo)題字體(漢字的);網(wǎng)上搜索了一番,發(fā)現(xiàn)蘇新詩柳繁體這款甚合我心;然后就著手搞將了起來,分分鐘也算是替換了;但,這僅僅是此次折騰的開始;這就細(xì)細(xì)道來作為學(xué)習(xí)筆記記載。 原文首發(fā)鏈接http://www.je...
摘要:簡言之,我們認(rèn)為好的用戶體驗(yàn)從快速的內(nèi)容傳輸開始,也就意味著性能美觀。每一步我們都在探討如何在獲得好的用戶體驗(yàn)和保證設(shè)計(jì)美感的同時(shí),最小化對(duì)性能的影響。字型子集設(shè)定到目前為止,子集設(shè)定是改善網(wǎng)頁字體性能最快的方式。 作者 Declan 原文鏈接 最近更新了我們的網(wǎng)站,它是經(jīng)過了設(shè)計(jì)上的全面驗(yàn)收的。但實(shí)際上,作為軟件開發(fā)者,我們會(huì)注重很多技術(shù)相關(guān)的零碎的東西。我們的目標(biāo)是控制性能,注重性...
摘要:簡言之,我們認(rèn)為好的用戶體驗(yàn)從快速的內(nèi)容傳輸開始,也就意味著性能美觀。每一步我們都在探討如何在獲得好的用戶體驗(yàn)和保證設(shè)計(jì)美感的同時(shí),最小化對(duì)性能的影響。字型子集設(shè)定到目前為止,子集設(shè)定是改善網(wǎng)頁字體性能最快的方式。 作者 Declan 原文鏈接 最近更新了我們的網(wǎng)站,它是經(jīng)過了設(shè)計(jì)上的全面驗(yàn)收的。但實(shí)際上,作為軟件開發(fā)者,我們會(huì)注重很多技術(shù)相關(guān)的零碎的東西。我們的目標(biāo)是控制性能,注重性...
閱讀 2484·2023-04-25 19:24
閱讀 1700·2021-11-11 16:54
閱讀 2833·2021-11-08 13:19
閱讀 3547·2021-10-25 09:45
閱讀 2552·2021-09-13 10:24
閱讀 3276·2021-09-07 10:15
閱讀 4014·2021-09-07 10:14
閱讀 2950·2019-08-30 15:56