Blog Optimization with Service Workers and Caching
IntroductionThe blog requires loading third-party fonts, which can be quite large, a whopping 16MB. As a result, I sought to optimize the on-demand loading of fonts and leverage Service Workers.On-Demand Font LoadingIn a typical CSS setup, fonts are automatically loaded, but every time the webpage is refreshed, they are downloaded again. To address this, I used JavaScript to create a binary blob file in the browser, caching the font. Here's the code:fetch('https://api.yuhenm.top/api/file/source?name=LXGWWenKaiGBScreen.woff', { cache: 'force-cache' // Force cache }) .then(response => response.blob()) .then(blob => { // Create a temporary URL for the font file const fontUrl = URL.createObjectURL(blob); // Create a tag const style = document.createElement('style'); // Set the tag's content style.textContent = ` @font-face { font-family: LXGWWenKaiGBScreen; font-size: 16px; font-style: normal; font-display: swap; src: url(${fontUrl}) format('woff'); } * { font-family: LXGWWenKaiGBScreen; } body { font-family: LXGWWenKaiGBScreen; } `; // Add the tag to document.head.appendChild(style); // Mark the font caching status as loaded localStorage.setItem('customFontLoaded', 'true'); });However, this was not sufficient. Although I had OneDrive as a traffic outlet, the font size was still too large. To address this, I implemented on-demand loading by splitting the font into different fragments using Node.js.import { fontSplit } from "@konghayao/cn-font-split"; fontSplit({ FontPath: "./fonts/LXGWWenKaiGBScreen.ttf", destFold: "./build", css: { fontFamily: "LXGWWenKaiGBScreen", // Not recommended; we already have a built-in parsing module }, targetType: "woff2", // ttf woff woff2; note that browser support for eot files is very low, so we do not support it chunkSize: 50 * 1024, // Split size testHTML: true, // Output an HTML report file reporter: true, // Output a JSON report });The code above splits the font, allowing CSS to load the font content on demand:@font-face { font-family: "LXGWWenKaiGBScreen"; src: url("./e9b0555612176c4be508d0952695540e.woff2"); font-style: normal; font-weight: regular; font-display: swap; unicode-range: U+21,U+22,U+23,U+24,U+25,U+26,U+27,U+28,U+29,U+2A,U+2B,U+2C,U+2D,U+2011,U+2E,U+2F,U+30,U+31,U+32,U+33,U+34,U+35,U+36,U+37,U+38,U+39,U+3A,U+3B,U+3C,U+3D,U+3E,U+3F,U+40,U+41,U+42,U+43,U+44,U+45,U+46,U+47,U+48,U+49,U+4A,U+4B,U+4C,U+4D,U+4E,U+4F,U+50,U+51,U+52,U+53,U+54,U+55,U+56,U+57,U+58,U+59,U+5A,U+5B,U+5D,U+5E,U+5F,U+60,U+61,U+62,U+63,U+64,U+65,U+66,U+67,U+68,U+69,U+6A,U+6B,U+6C,U+6D,U+6E,U+6F,U+70,U+71,U+72,U+73,U+74,U+75,U+76,U+77,U+78,U+79,U+7A,U+7B,U+7C,U+7D,U+7E,U+223C,U+A1,U+A2,U+A3,U+A4,U+A5,U+A6,U+A7,U+A8,U+A9,U+AA,U+AB,U+AC,U+AE,U+AF,U+B0,U+B1,U+B2,U+B3,U+B4,U+2CA,U+B5,U+B6,U+B7,U+2219,U+B8,U+B9,U+BA,U+BB,U+BC,U+BD,U+BE,U+BF,U+C0,U+C1,U+C2,U+C3,U+C6,U+C8,U+CA,U+CB,U+CC,U+CD,U+CE,U+CF,U+D0,U+D2,U+D3,U+D4,U+D5,U+D7,U+D8,U+D9,U+DA,U+DB,U+DD,U+DE,U+DF,U+E6,U+F0,U+F7,U+F8,U+FD,U+FE,U+FF,U+131,U+141,U+142,U+152,U+153,U+160,U+161,U+178,U+17D,U+17E,U+192,U+2C6,U+2C7,U+2D8,U+2D9,U+2DA,U+2DB,U+2DC,U+2DD,U+2014,U+2018,U+2019,U+201A,U+201C,U+201D,U+201E,U+2020,U+2021,U+2022,U+2026,U+2030,U+2039,U+203A,U+2044,U+20AC,U+2122,U+2212,U+FB01,U+FB02,U+3001,U+3002,U+30FB,U+2C9,U+3003,U+3005,U+2015,U+2016,U+3014,U+3015,U+300A,U+300B,U+300C,U+300D,U+300E,U+300F,U+3016,U+3017,U+3010,U+3011,U+2236,U+2227,U+2228,U+2211,U+220F,U+222A,U+2229,U+2208,U+2237,U+221A,U+22A5,U+2225,U+2220,U+2312,U+2299,U+222B,U+222E,U+2261,U+224C,U+2248,U+223D,U+221D,U+2260,U+226E,U+226F,U+2264,U+2265,U+221E,U+2235,U+2234,U+2642,U+2640,U+2032,U+2033,U+2103,U+FF04,U+FFE0,U+FFE1,UOn-demand loading is achieved through the use of unicode-range, which tells the browser which characters are in which files, allowing for on-demand loading.Service Workers UsageThe "handsome" theme of this blog has Service Workers functionality, which I discovered by examining this section of the code.I wanted to cache all resource files, but after numerous investigations, it still wasn't possible due to 302 redirects, as each request was not reused. This is a drawback of OneDrive as a resource source.I noticed that Service Workers can cache successfully due to the use of the front-end caches interface. So, I considered modifying it myself.However, due to the hash value differences and 302 redirects, my modifications were unsuccessful after numerous attempts.I also attempted to use indexedDB for caching but ultimately decided against it.