Normal view

a docs site with an illustration on every tutorial page, 5.9 MB down to about 550 KB, and what actually did it

1 September 2026 at 14:45

I maintain the documentation site for a small tool I build, and about a year ago I put an illustrated guide character on every tutorial page, because the audience is not technical and a wall of text was losing them somewhere around step four. Forty one tutorial pages, a hundred and sixty eight illustrations, roughly four per page. This is what that did to the site and what actually fixed it, because most of what I tried first was the wrong lever.

The starting position was bad in a boring way. For the first thirty pages I uploaded whatever came out of the image generator. PNG, about fifteen hundred pixels wide, roughly 1.35 MB each. WordPress then did what WordPress does. Thumbnail, medium, medium_large, large, the 1536 variant, the 2048 variant, three more sizes the theme registers, plus a scaled copy for anything over the big image threshold with the original kept alongside it. Ten files on disk for every one picture on screen. The uploads folder was about 560 MB and roughly sixteen hundred files for what a reader would describe as a hundred and sixty eight pictures. The media library grid took several seconds to paint and every file was called some variant of guide_final.

Page weight was the visible symptom. A typical tutorial page carries four illustrations, so four times 1.35 MB is 5.4 MB, and the theme, fonts, CSS and markup were another 500 KB on top. Call it 5.9 MB for a page whose actual content is six hundred words and two code blocks. Largest contentful paint on a throttled mobile profile was 4.8 seconds. Time to first byte on the shared host it lives on was around 480 milliseconds cold.

Compressing before upload rather than after was worth more than everything else put together. Every illustration now gets resized to nine hundred pixels wide, converted to WebP and compressed, and only then uploaded. That takes each one from 1.35 MB to about 78 KB. The ordering is the whole trick. If compression happens inside WordPress after upload, the library is still storing a large original and generating all its derived sizes from it, so the disk cost stays. If the file is already small when it arrives, every derived size is small and the original on disk is small too.

Then I stopped WordPress generating sizes that nothing on the site uses. A filter on intermediate_image_sizes_advanced drops the 1536 and 2048 variants and two of the three theme sizes, leaving thumbnail and medium. Files per image went from ten to three. After that I regenerated the library and deleted the orphans, and the uploads folder went from 560 MB to about 20 MB, which is a smaller number than the theme.

Explicit width and height on every image, lazy loading on everything except the first illustration, and fetchpriority set high on that first one. None of that changed the weight at all and all of it changed how the page feels, because the layout stopped jumping around while images resolved.

Page caching came last, which surprised me, because caching is the first thing that gets suggested whenever this comes up. Docs pages change maybe twice a month, so the lifetime is set to a day and it purges on save. Warm time to first byte is now about 90 milliseconds. Cloudflare sits in front with a rule treating everything under the uploads path as immutable for a year, which is only safe because a changed illustration always gets a new filename. I also dropped one of the two webfonts and subset the other, which took the theme payload from about 500 KB to about 240 KB.

Where that leaves a tutorial page is roughly 550 KB total, of which 312 KB is the four illustrations at 78 KB each. Largest contentful paint 1.3 seconds on the same throttled profile.

The honest part is that the illustrations still cost real weight. A text only page on the same theme comes in around 240 KB. The guide character roughly doubles a page, and I chose that trade rather than got it for free, so I now cap it at four illustrations per page and never put one above the fold on an index page. If the tool were aimed at developers I would probably not have done it at all.

The bigger problem is not weight, it is drift. Regenerating the same character for a new page does not give back the same character. Same character, same notes, and the sleeve reads a different length, the fringe lands on the other side of the forehead, the green of the coat comes back slightly colder. On one page in isolation nobody would notice. Two pages open in adjacent tabs and it reads as a sibling. So I keep a folder of about sixty approved renders and reuse them rather than generating fresh, and when a page genuinely needs a pose that does not exist yet, I make a batch of eight and keep whichever is closest to the existing set rather than whichever is best on its own. Twice I have gone back and replaced an image on an older page because a newer one made the old one look wrong. Every image on the site is a still for the same reason, since I can hold a set together with stills and I have never managed it with anything that moves.

The guide character is AI generated. No illustrator drew it and no model posed for it. That is stated in the site footer and on the about page, and I would rather it sit there in my own words than turn up later as somebody's discovery.

Standardising the art was the other half of the fix and it is the half nobody writes about. There are five poses on the entire site and no others: pointing at something, holding something, sitting, arms folded, and looking at a screen. The character is always angled the same way, a fraction off centre. The crop is always from the knees up. The background is always transparent and never a scene, which means one file works on both the light and the dark theme without a second export. Everything is exported at exactly nine hundred pixels wide, so nothing on any page is at a different scale from anything on any other page.

Filenames carry the pose and the page slug with underscores, and the alt text gets written at the moment the file is made rather than in the editor at publish time. Those two habits are why the media library is navigable at all now. The old library was not unusable because it was large. It was unusable because it was anonymous.

The site itself is WordPress, the guide character gets drawn in APOB AI, and every image goes through ShortPixel before it ever reaches the media library.

The thing I would do differently from the start is decide the pose set before drawing anything, the same way a project settles its icon set before building screens. I generated on demand for the first six months and it produced about ninety illustrations, no two of which shared a crop, and most of those had to be remade from nothing once the rules existed. That rework cost more time than the entire performance exercise did.

Forty one tutorial pages are live and nine more are still drafts. The only check I run before publishing now is the size of the folder the images came out of, which takes about four seconds and would have saved me a fortnight if I had started doing it a year ago.

submitted by /u/Mental-Telephone3496
[link] [comments]
❌