{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreibbazlcm3n6x5fpwqvbentzbd2bokyauquw3vhlat4rl6ylwy47hq",
"uri": "at://did:plc:jwwkv3fzfiicoyeonnrjchrt/app.bsky.feed.post/3mm4lwfkbr4i2"
},
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreic5knryxm7hwtz2nwhld6tig76uxwo5aic3uxfir66jvo6w5auaqm"
},
"mimeType": "image/png",
"size": 4470
},
"path": "/journal/site-optimization",
"publishedAt": "2026-05-05T00:18:41.000Z",
"site": "https://engeltje.org",
"tags": [
"performance",
"fonts",
"optimisation",
"programming",
"Article",
"ImageMagick’s default quality setting for WebP is 75",
"@font-face"
],
"textContent": "For some time I’ve known that not all of my website is amazingly optimised, but I hadn’t really looked into it. But recently I decided to do something about it when I noticed that my homepage was almost 6MB on first load. And it’s not a bloated web app either, but a personal website. Kinda embarrassing. While I could argue that the site gets cached anyway and I didn’t want to lose quality on my photos, I also didn’t want it to feel sluggish. So in this article I want to share the steps I took to cut the homepage weight by 90%.\n\n## The font problem\n\nThe actual start of all of this was when I noticed I did not install the japanese subset of Shippori Mincho correctly. The font was rendering with missing glyphs, so I thought I’d install the full subset to fix it. But I made the mistake of not realising that the full `japanese_latin` woff2 subset contains thousands of kanji I will likely never use, and each weight came in around 650KB. Just the two font files were already over 1.3MB.\n\nI only really needed to render one character `天`. So I thought, maybe I can just subset that one character out of the full font and serve it separately? So that’s exactly what I did.\n\nThe fix was to use `pyftsubset` from the `fonttools` library to carve out a woff2 containing only that single character:\n\n\n pyftsubset shippori-mincho-v17-japanese_latin-regular.woff2 \\\n --text=\"天\" \\\n --flavor=woff2 \\\n --output-file=shippori-mincho-ten-regular.woff2\n\nThe result was a mere **668 bytes** woff2 font file. For one character. I then scoped it in CSS with `unicode-range` so the browser only fetches it when it actually encounters that glyph in the DOM, and kept the small `latin` woff2 (27KB) for everything else:\n\n\n @font-face {\n font-display: swap;\n font-family: 'Shippori Mincho';\n font-weight: 400;\n src: url('/fonts/shippori-mincho-ten-regular.woff2') format('woff2');\n unicode-range: U+5929;\n }\n\nWhile I was optimising, I also decided to remove other things such as all the TTF fallback sources. Every browser that supports woff2 is from 2015 or later, there’s not really an audience that uses a browser engine older than 2015 that visits my site regularly enough to justify the extra weight.\n\nAdding onto that I stopped preloading Amiri, which, although a beautiful font, I only use for blockquotes. So there’s no reason to preload it on a homepage that’ll likely never use it.\n\nThat brought the total down from **5.8MB to around 3.5MB**. Better, but still not great.\n\n## The actual culprit: images\n\nSkimming through the Network tab by size made the real problem obvious.\n\nFile| Size\n---|---\n1.jpg| 871KB\n2.jpg| 1.39MB\n3.jpg| 1.23MB\n\nThese are cover images for the homepage, sent back without major compression as they’re just JPEGs directly exported from my camera. The source files were 4272×2848px while the element they display in is about 600px wide.\n\nSo the first obvious thing to do is that I converted them to WebP, which immediately helped for two of the three. The first image actually got _larger_ , from 871KB to 1.3MB likely because ImageMagick’s default quality setting for WebP is 75, which is a lot higher than how aggressive the existing JPEG compression had been. `1.jpg` in particular is a very detail-heavy photo so I resorted to setting the WebP quality to 20.\n\nI also wrote a small script to halve the dimensions of each WebP while preserving the aspect ratio exactly so it would be better sized for the cover element:\n\n\n for f in *.webp; do\n w=$(magick identify -format \"%w\" \"$f\")\n h=$(magick identify -format \"%h\" \"$f\")\n magick \"$f\" -resize \"$((w / 2))x$((h / 2))\" \"$f\"\n done\n\nI ran this twice.\n\n**Update: 2026-05-06** : After more compression of the cover pages, I got the image sizes down even more for a total page load of around 400KB. This was done by running:\n\n\n for f in *.webp; do\n magick \"$f\" -resize 800x534 -quality 82 \"$f\"\n done\n\nThe new final sizes are:\n\nFile| Original JPEG| Compressed JPEG| Resized WebP| Second resize WebP\n---|---|---|---|---\n1.webp| Original: 8.3MB| Compressed: 871KB| Resized: 224KB| Second resize: 146KB\n2.webp| Original: 4.8MB| Compressed: 1.39MB| Resized: 85KB| Second resize: 62KB\n3.webp| Original: 4.9MB| Compressed: 1.23MB| Resized: 86KB| Second resize: 76KB\n\nDown from ~3.5MB to under 300kb combined while the images still look sharp at normal viewing sizes. You’d only notice degradation at maybe 200% zoom on a high-DPI display, which is an acceptable tradeoff for a 90%+ reduction in file size.\n\n## Result\n\nStage| Page weight\n---|---\nOriginal| ~5.8MB\nAfter font cleanup| ~3.5MB\nAfter image optimisation| ~400KB\n\nA 90%+ reduction. The site now feels way snappier on first load, on a decent connection it loads instantly.\n\n> As a minor side note, I also made the Last.fm album cover fetch a lower resolution but the difference there was negligible by a few KB.\n\n* * *\n\nThe whole process took a few hours, most of which was figuring proper compression settings. It also improved my PageSpeed Insights score from around 89 to 100.\n\nPageSpeed Insights Results\n\nI know it’s not really a goal to reach a perfect 100, but it was nice to see. So if there’s anything to take away from this post, it’s that you should absolutely optimise your images and fonts if you care about performance. But of course, that’s all up to you.",
"title": "How I reduced my site's size from 5.8MB to under 400KB"
}