What the CMS does to your hero image

#images #performance #wordpress

A ticket for something else took me back to a practice’s homepage I’d sped up in January. The page sat there for a beat before it drew anything. This was on my own broadband, on a laptop plugged into a wall.

The hero image was 2.4 MB. In January I’d gotten that hero down to 180 KB and I remember being pretty pleased with myself about it.

It isn’t a mystery and it isn’t anybody’s fault. There was a summer promotion in May and somebody swapped the hero for it. The file they swapped in came straight out of the photographer’s Dropbox at 4000px wide.

The CMS took the file, scaled it into the slot, and served it. The interface worked exactly the way it was built to work.

Now with four sizes

I didn’t expect the CMS to have already tried to help.

WordPress has generated responsive images by itself since 4.4 landed in December, which is really good and I was happy about it at the time. You upload one file and it makes a few smaller copies. Then it writes the srcset for you off what it made. This is what it made for the summer hero.

the srcset, file by file
hero-summer.jpg             4000x2667    2.4 MB   <- the src, and in the srcset
hero-summer-1024x683.jpg    1024x683      236 KB
hero-summer-768x512.jpg      768x512      139 KB
hero-summer-300x200.jpg      300x200       22 KB
Text

That’s four files and correct markup, sizes attribute and everything. But every one of the copies is a re-encode of the original at WordPress’s default quality. None of them has been anywhere near an optimizer. The biggest is 236 KB at a smaller size, which is more than January’s whole hero weighed.

The theme also asks WordPress for the full-size image, so the 4000px original is the src. WordPress keeps the src in the srcset, and nothing sits between it and the 1024. So on any screen wider than 1024 the browser skipped all of WordPress’s work and took the whole 2.4 MB.

The automation I’d been wishing for did arrive. It just arrived set to whatever the WordPress core team picked as a reasonable guess about a site they’ll never see.

I had already written this post

I’m in a practice’s site for an afternoon at a time. The practice has it for years.

Everything I do in that afternoon is a snapshot of a decision. Every one of those decisions sits there waiting to be made again later by somebody else in a hurry, through an interface built for exactly that. The optimizer I ran that hero through is an app on my laptop. It has never run on their server and it never will.

I wrote a post last fall that ends by saying the only version of this that survives is the one in the pipeline. That meant resizing on upload and a quality setting, the unglamorous infrastructure that keeps working while nobody is paying attention. Then in January I dragged a hero through the app on my laptop, uploaded it by hand, and called the homepage done.

I don’t have a good explanation for that. I think I read my own conclusion as a thing I now understood instead of a thing I now had to go ask for.

So the work in January wasn’t wrong. It had a shelf life I hadn’t thought about even once, which turned out to be “until somebody changes something.”

It came with friends

Once I started looking, the images were only the loudest one.

Take the editor. Five months after I was last in there, the homepage copy has inline styles baked into it. There’s an <h1> halfway down the page because it was the size somebody wanted. There’s also text that’s bold where it should be a heading.

That last one is the same problem I ran into with alt attributes in December, arriving from a different direction. The field accepted what it was given and the page looks fine. The problem is invisible unless you go and look.

This is what it looks like at five months. Four years of it is a line item in a redesign, which I watched land on a different project in May and somehow filed as that project’s problem.

As for plugins, somebody installed a slider because they wanted a slider. It came with its own copy of jQuery, an icon font the theme already had a different one of, and a Google Font in a weight nothing on the site uses. That isn’t a criticism of anybody. They were handed an interface with a button on it that says Install, and the button installed it.

Nobody has to remember

There are four things I’d like us to do, roughly in order of how well they’d hold up.

Move the processing to the server. Resize on upload, re-encode at a sane quality, and cap the longest edge at something the design actually uses. Whether that’s a plugin, a hook, or an image CDN sitting in front of the whole site matters much less than the fact that it isn’t optional and it isn’t on my laptop. This is the only one on the list that works whether or not anybody remembers it exists, which is the property I’m actually after.

Constrain the upload. Refuse the 2.4 MB file with a message that says why and what to do instead. I held out longest on this one because rejecting a person’s file feels hostile. But this page was slow for a month before anybody noticed. I now think quietly accepting the file was the more hostile option.

Restrict the editor. Take out the formatting controls that produce things the CSS doesn’t support. If there’s no color picker there’s no pink heading. I’ve never heard of anybody missing a color picker. They do say the site looks messy, which is the color picker one step downstream.

And give somebody a number to watch. It’s the weakest of the four because it needs a human to notice. But a monthly look at what the homepage weighs would have caught this one in May, and it costs nothing to set up.

Who died and made me the arbiter

You could read this post as just me wanting to lock a practice out of its own website, and that reading is about half right.

It is their site. They paid for it and they run their business on it. A developer deciding they can’t be trusted with an upload form is the kind of paternalism that makes people hate their agency.

I’ve been on the receiving end of somebody else’s well-meant constraint. Without the reason attached it’s hard to tell from an arbitrary one.

I’d say two things back though. (1) A constraint you agreed to in advance is a completely different thing from one you discovered by being blocked. So the work is in the conversation and not in the code. “We’ll cap uploads at 2000px because a photo bigger than that makes the page slow on phones and doesn’t look any better” is a sentence I can’t picture a practice arguing with.

And (2) most of these make their job easier instead of harder. Nobody at a front desk wants to think about JPEG quality settings. They want to put the summer picture on the website and have it look right. Every decision the site takes off their plate is one they were never being paid to make in the first place.

The list I write now

Running the summer photo through the optimizer took five minutes and it’ll last until the next promotion. I also started keeping a list and that’s the change I expect to last.

When a ticket has me making something on a practice’s site faster or cleaner, I now write down what a person will still be able to do to it after I close the ticket. They can change the pictures, edit the copy, add a page, or install something. Then I go down it asking which ones can undo what I just did.

It’s a short list and it takes about 20 minutes. In January it would have told me to ask for resizing on upload instead of trusting the one file I’d uploaded.

I used to think of the job as making a fast site. Now it seems closer to making a site where the slow thing isn’t the easy thing to do, which is duller to be good at and holds up a lot longer.

The person who swapped that hero was doing their job well. They had a promotion to get up, a picture that looked great, and a form that took the picture without complaining. Nothing anywhere in that sequence had any reason to tell them otherwise. I think building the thing that tells them is the job, and it isn’t one I can do by hand an afternoon at a time.

Read similar posts

View posts by tag

#accessibility #agency #ai #careers #cross-browser-compatibility #css #culture #debugging #documentation #ecommerce #forms #git #html #images #javascript #performance #php #privacy #scss #security #shopify #small-print #tooling #typography #wordpress