动态

详情 返回 返回

可能是東半球最好的 Web Font 優化方式「中文網字計劃」 - 动态 详情

中文網字計劃是收錄眾多中文字體並通過 Web Font 的形式為 網站開發者 提供美麗字體的項目。

中文網字計劃致力於在互聯網中提供更加便捷實用的全字符集中文渲染方案。中文網字計劃通過精巧設計的字體分包方式,將龐大的字體文件切割為多個小型靜態分包部署於雲端,在全網領域內都可快捷、穩定地進行加載。為提高中文字體在網絡中的流通體驗而努力!

為什麼要使用獨特的中文字體

  • 提高藝術風格的表現力

前端領域是信息呈現最為豐富、風格最為靈活的一個技術領域。它不僅包括了各種以文本為主的新聞、博客、論壇網站,還涵蓋了各類生動靈活的數據可視化網站,以及風格別緻的網頁小遊戲。在許多注重表現細節網站中,中文字體的作用不容小覷。例如在像素遊戲使用像素字體來符合整個遊戲世界觀,數據可視化網站中運用特殊裝飾字體來呈現主題所表達的情感,在個人博客中也有運用飄逸輕盈的字體來展現個人的藝術追求的例子。可以説,選擇適合的字體是使得網頁呈現獨特風格的關鍵要素之一。

  • 提高產品的風格辨識度和國際統一度

中文字體能夠有效地呈現品牌形象,提高產品的辨識度,幫助產品更好地傳遞自己的理念和價值觀。中文字體在不同的設計元素中也有着其獨特的應用。

舉例來説,米哈遊開發的原神中採用 漢儀文黑字體,它在中、日、韓、英四種語言環境下表現出一致的藝術風格和文字表現力。即使在同一圖片中呈現也沒有違和感,這對於不同語言玩家在遊戲中的視覺效果和用户體驗來説具有非常強烈的提升。

在當前的互聯網環境中,英文字體的應用已經非常普遍。由於英文字符數量較少,因此加載整個字體包並不會對網頁造成影響。然而,中文字符與英文字符相比,其數量和輪廓複雜度都更高。因此中文字體體積較英文字體大非常多,而且加載中文字體往往會佔用大量的網絡帶寬。對於原生應用程序來説,可以通過內置字體包等方式解決這個問題,但這個弱點對於 Web 網頁加載則是致命的。

如何實現 Web 場景下的網絡字體加速

手動、自動切割字體文件

目前一種在網頁中使用中文字體的方法是分析網頁所包含的中文字符,將字體切割出來,單獨分包存儲在服務器中。這種切割方式可以極大地減小字體大小對帶寬的影響,適用於個人博客等類型的網站。然而,隨着一個項目越來越大,所需要進行的切割文本越來越多,採用這種非全量級的加載方式,可能會導致不同的文章涉及的文字不同,從而造成打包字符區間不同,影響服務器的緩存和資源利用率。常見的工具有:字蛛、fontmin、fonttools 等

缺點:需要手動執行、只適用於靜態場景、影響緩存效率

Google fonts 方案

在 Google Fonts 網站中,Google 採用最新的 CSS 特性 unicode-range 來實現按需加載 CJK (中日韓) 字體,併成功地實現了中文字體在網頁端的全量級按需加載。同時提供瞭如站酷系列、Noto 系列等字體的效果展示。從技術上看,所有加載文件為靜態文件,可以通過 CDN 一次發佈,隨處加載,且具有可靠的速度和穩定性。即使如博客論壇等專注長文本類型的網站,也可使用。但受限於版權問題,Google Fonts 中僅有開源字體,如果需要特殊字體需要進行自託管

https://fonts.googleapis.com/css2?family=Lexend+Exa:wght@900&family=Roboto:wght@100&display=swap

缺點:分包較大、國內訪問不佳或需要代理、需要自託管

中文網字計劃方案

中文網字計劃在 Google Fonts 的切割方案的基礎之上,對字體的使用順序進行了排序分類,優化了各類字符的分包區間,並可使用更加快速的全球 CDN 服務,實現了近乎完美的中文字符落地方案。同時,計劃中所開源的的開發工具流已經可以無縫融入前端開發,為中文字體在網絡中的使用提供理論和技術上的支持。

建立自己的字體服務

上方介紹了三種不同的字體優化方式,現結合「中文網字計劃」中的開源模塊對字體進行優化

暫時無法在飛書文檔外展示此內容

分析

這裏取「阿里巴巴普惠體 3.0」進行測試,首先可以使用字體分析工具對字體進行分析

在線分析工具:https://chinese-font.netlify.app/analyze/

離線分析工具:https://www.npmjs.com/package/font-analyze

可以看出,在 AlibabaPuHuiTi-3-55-Regular 文件的版權信息,同時中文文字覆蓋率信息很好,CJK 覆蓋率一般

切割

@konghayao/cn-font-split 是一個基於 Node.js 的字體分包器,能夠將來源字體文件分成多個包,並且提供附帶成果預覽和數據分析功能 。中文網字體計劃使用 @konghayao/cn-font-split 作為核心,構建了一系列字體的分包成品。如果您需要對私有字體進行簡單分包和靜態部署,選擇它再適合不過了。

在線切割工具

https://chinese-font.netlify.app/online-split/

在線工具可通過提交字體進行分包處理,藉助 WebAssembly、多線程等技術優化,使得其可以運行在任何標準的 Nodejs 或者是 Web 環境中執行,這意味着所有現代瀏覽器都可以進行分包。

這裏看到分包結果是以 woff2 進行輸出的,同時分包後文件大小比源字體還小很多。原因如下:

在現代字體中,WOFF2 是最新的,擁有最廣泛的瀏覽器支持,並提供最好的壓縮。由於使用 Brotli,WOFF2 的壓縮率比 WOFF 提高了 30%,從而減少了下載數據,從而提高了性能。

離線切割工具

https://www.npmjs.com/package/@konghayao/cn-font-split

安裝

npm install @konghayao/cn-font-split

執行腳本
import { fontSplit } from '@konghayao/cn-font-split';
// import { fontSplit } from "@konghayao/cn-font-split/dist/browser/index.js";
// import { fontSplit } from "https://cdn.jsdelivr.net/npm/@konghayao/cn-font-split@4.3.6/dist/browser/index.js";
fontSplit({
    FontPath: './fonts/SourceHanSerifCN-Bold.ttf', // 部分 otf 文件會報錯,最好使用 ttf 版本的字體
    destFold: './build',
    targetType: 'woff2', // ttf woff2;注意 eot 文件在瀏覽器中的支持度非常低,所以不進行支持
    chunkSize: 70 * 1024, // 如果需要的話,自己定製吧
    testHTML: true, // 輸出一份 html 報告文件
    reporter: true, // 輸出 json 格式報告
    // previewImage: {}, // 只要填入 這個參數,就會進行圖片預覽文件生成,文件為 SVG 格式
    threads: {}, // 建議開啓多線程
    css: {
        // 覆蓋默認的 css 設置,一般不需要進行更改
        // fontFamily: "站酷慶科黃油體",
        // fontWeight: 400,
    },
});

管理

font-server 是一個用於內網的字體存儲和管理服務,支持通過 WebHook 對外通知信息,並允許外部程序通過端口進行內部數據訪問。

主要功能包括:

  1. 用户可以上傳原始字體文件,系統會保存這些字體文件。
  2. 觸發打包字體功能後,切割服務器會自動獲取內部存儲的字體文件,並對其進行切割,然後將切割後的字體片段存入內部文件系統。
  3. 支持 WebHook 訂閲功能,觸發 hook 事件後,系統會廣播訂閲 url,通知外部程序相關事件信息。
  4. 在切割完成後,外部監聽程序可以獲取內部的切割分片,並將其部署到外部公開的 OSS 系統上。特別地,內外 OSS 系統應該使用相同的路徑。
  5. 用户可以通過 OSS 系統提供的 CDN 加速訪問字體文件,同時嵌入字體加載 HTML 片段,瀏覽器會自動加載相應的 CSS 文件和字體文件。
  6. 提供簡單的 Admin 界面,方便用户進行可視化操作。

通過部署 font-server 服務可以便捷高效管理業務內字體

優化

現在擁有了分割後的字體,可直接上傳到靜態資源存儲中進行使用了,接下來介紹提高字體加載速度的方式

  1. 切割分包大小適當:建議是設置 50-100KB 左右範圍進行打包,這樣單個包的大小不會太大,HTTP/2 的加載速度也夠快。cn-font-split 的默認值是 70 KB 能夠滿足大多數場景。
  2. 使用支持併發加載的 CDN:開啓 CDN 的 HTTP/2 支持
  3. 一定要配置 HTTP 緩存條件:在有緩存時,用户打開你的網站是可以達到 50ms 內瞬間加載完所有字體包的。由於字體文件配置一次就基本上不會進行改動,所以可以持久緩存。
  4. 文檔站點的 預加載:如果網站有條件,可以在首頁或者是所有頁面,在瀏覽器空閒的時候,使用 js 的 fetch (force-cache) 請求所有的字體包。這樣瀏覽器會把字體都加入進緩存中,從而保證其它頁面的文字也能迅速加載。至於分包的具體名稱,可以使用 reporter.json 文件查看。

請勿使用 Preload 預下載 CSS 文件

Preload 預下載會全量下載對應文件,這樣會導致字體按需下載失效。但是你可以預加載幾個常用的字體文件分片,這個需要你手動去判斷加載,流程較為複雜。

其他問題

  • 字體文件下載搶佔 JS 請求問題: 字體文件如果在入口 HTML 文件中加載,那麼瀏覽器會查看 HTML 中需要使用的字,並加載字體,但是在 JS 中使用數據請求就會出現問題。已經發出的字體下載佔用了瀏覽器的下載併發數,進而推遲 JS 下載。建議是使用 JS 添加 link 標籤動態導入 css 的方式延遲大概 150ms 即可。
  • 強制使用分包時,源字體沒有某些 字形 ,導致一個包內沒有被分滿:使用一個只有大致 6373 字符的字體,但是採用 Noto-Serif-SC 分包策略,那麼部分包內會有缺失字體的現象,這是正常的。這個特性,插件將不會進行干涉。建議較全的字體包可以使用 Google 字體的中文分包方式,而小字體包使用自動分包策略就好了。

參考資料

  • https://chinese-font.netlify.app/post/get_start/
  • https://chinese-font.netlify.app/post/performace_turbo/
  • cn-font-split - 中文 Web Font 切割工具
  • chinese-free-web-font-storage - 字體分包成品倉庫
  • font-server 中文字體切割服務器
  • online-split 在線字體分包器
  • analyze 在線字體分析器

Add a new 评论

Some HTML is okay.