Over the past week I've been doing free technical audits for sites posted in feedback subreddits (r/websitefeedback, r/reviewmyshopify and similar) - measuring each one with curl, Chrome DevTools and raw HTML reads before commenting. Eight audits in, the same handful of problems keeps showing up, and they're mostly NOT the things speed tools yell about. Here they are, with real numbers.
1. Your share preview is your storefront window - and it's often empty
A merch brand about to promote its store to an engaged social audience had no og:image, no twitter:image, and no meta description. Every link shared to Instagram Stories, X, Discord or iMessage unfurled as a text-only card with a blank thumbnail - for a brand whose entire pitch is aesthetics. Same store's homepage title tag was the bare domain (the platform fallback when the SEO title is unset).
The fix is minutes: one strong social sharing image + a homepage meta description, set before the promo push, not after. If you check nothing else before launch, check what your link looks like when pasted into a chat.
2. Entrance animations hide your page from the people you're trying to impress
An education platform's hero - headline, guarantee box, CTA - sat at opacity 0 for over six seconds on my first cold load, while entrance animations waited for ~10MB of eager-loaded media. A coaching site had the same pattern: full navy screen, zero words, until a fade-in ran. Both sites look great in the founder's warm-cached browser. First-time visitors on a school Chromebook or hotel wifi see a blank panel - and that's exactly the audience being courted.
If content is invisible until JavaScript says otherwise, your worst-case first impression is nothing at all. Fade things in fast, or don't gate the hero on animation at all.
3. Photos exported as PNG are quietly most of your page weight
One founder photo: 640x720 pixels, exported as PNG with alpha, 783KB - referenced three times on the page. Saved as JPG or WebP it's ~50KB, a 15x cut on a single file with zero visible change. The same site's lifestyle photos were all 200-260KB PNGs; the page shipped ~4MB of images with not a single loading="lazy".
Rule of thumb that would have fixed every case I saw: photos are never PNG. PNG is for screenshots, flat graphics and things that need transparency - and if a photo needs transparency, it needs WebP.
4. Measure before you optimize - the platform may have already solved it
I almost posted "your hero image is 1.2MB" on a supplement store's thread. Then I re-checked with a browser Accept header: Shopify's CDN was auto-converting that PNG to an 84KB WebP for real visitors. The image problem I was about to report didn't exist - the site's actual gaps were metadata and content repetition. Same story on a Ghost blog: the theme was fine (TTFB 50-130ms, proper responsive images); the weight was two membership/payment scripts loading ~900KB on every page view, whether or not the reader would ever subscribe.
Half the value of measuring is finding problems. The other half is not "fixing" things that were never broken.
5. Config leftovers ship to production and nobody notices
My favorite find of the week: a programming blog whose article:publisher meta tag pointed at a beekeeping Facebook page - a copy-paste leftover from another site, shipping in the head of every post. The same blog's og:image was a generic stock photo served from a *.r2.dev URL - Cloudflare's dev-only preview endpoint, rate-limited and not meant for production. Elsewhere: an email popup wired to fire on first scroll, seconds into a first visit; three h1 elements on one page because a hidden brand h1 shipped in the header template.
None of these show up in Lighthouse. All of them showed up in sixty seconds of reading the raw HTML head. Your head section is small - read it once with your own eyes before launch.
The meta-lesson
Speed tools score what they can score. Most of what actually hurt these eight sites - blank share cards, animation-gated heroes, identity metadata borrowed from stock libraries and beehives - scores fine. The audit method that caught everything above is embarrassingly simple: curl the page, read the head, check the wire sizes, load it once cold on a throttled connection, and paste your own URL into a chat app to see the card.
(All examples are from public feedback threads where owners explicitly asked for critique; numbers are from my measurement logs. I've kept sites anonymous here - the point is the patterns, not the naming.)
Top comments (6)
"Speed tools score what they can score; most of what actually hurt these eight sites scores fine." That's the sentence, and it's the same reason I stopped trusting my own automated audit's green checkmarks. I run a static scanner across my tools, and the failures it can't see are exactly the class you're describing — the leftover that ships because nothing measures it: a dev-only endpoint, a stray config, a second h1 nobody flagged.
The "same 5 across 8 sites" pattern is the most useful part for me. When the same thing breaks everywhere, it stops being a bug and becomes a checklist item — cheaper to enforce once than to rediscover eight times. I keep a running file of exactly these "nobody warns you" repeats for my own stack, and three of your five are going into it, because a recurring failure written down once is a failure you stop paying for.
The og:image one especially lands, because it fails silently and socially — invisible to you, visible to everyone who shares the link. That's the worst quadrant: broken where you never look. Great, measurement-first writeup.
Thanks — "broken where you never look" is a better phrasing of the og:image failure mode than mine. And the running-file idea is exactly where this ends up: after enough of these, the interesting artifact isn't any single audit, it's the recurrence list. Curious which of your own "nobody warns you" repeats didn't overlap with my five — that non-overlap is probably where my next checklist item comes from.
That non-overlap question is the right one, and it splits our two lists cleaner than I expected. Your five are all failures a measurement tool can't see — the thing that scores fine and still hurts. Almost every repeat on my list is the opposite: a failure the tool sees and reports wrong. Different mode of the same disease.
The ones that'd never show up in a web audit, because they're infra-layer and environment-specific:
Line yours and mine up and the combined checklist is really "the two ways a tool fails you": it stays silent about a real problem (yours), or it reports a real signal that means something else here (mine). Your og:image is the silent kind; my 405 is the lying kind. If I had to hand you one for your next item, it's that last shape — the same signal means different things in different environments — because it's the one that survives being written down and actually travels across stacks. Great thread.
The silent kind vs the lying kind — that's the cleanest name for this split I've seen, and I'm stealing it. Your firewall example is the nastier of the two: a silent tool wastes your time once, but a status line that lies teaches you to distrust the whole layer, and you never fully un-learn that.
And taking you up on the handed-down shape — from my side of the fence the "same signal, different meaning" list writes itself: a 200 that's really the theme's "nothing found" template rendering beautifully (soft 404, every audit tool scores it green), a Lighthouse run that "regressed" only because run one hit a cache MISS and run two hit a HIT, and one identical render-delay number that can mean an intro animation, a blocking font, or layout waiting on JS — three different fixes behind the same metric. That might genuinely be the next post. Thanks for the ammunition.
Your soft-404 is my health check with a frontend — a 200 rendering the "nothing found" template beautifully is exactly "database: true" written by a page whose database is dead. Same lie, different layer, and every automated tool scores both green, because green is the thing they were built to confirm. You just found the prettiest possible version of it.
But look at what your three examples do together: they split "same signal, different meaning" into its own three axes. The soft-404 is one signal, two states — success vs empty. The Lighthouse cache MISS/HIT is one signal, two conditions — cold vs warm. The render-delay number is one signal, three causes — animation, font, layout-on-JS. State, condition, cause: a single metric can fork on any of the three, and the reader assumes it forked on none. That's not three anecdotes; that's the skeleton of the post.
And you're right that the lying kind is nastier, for exactly the reason you named. A silent tool costs you an afternoon; a lying status line costs you your trust in the whole layer, and you never fully get it back. I still read the body before the status code — months after a firewall taught me to — on endpoints that have never once lied to me. The distrust outlives its cause, which might be the truest measure of how expensive a lying signal really is. Write the post. I'll be first in the comments.
State, condition, cause — you found the structure I didn't know the draft was missing. I had them lined up as parallel anecdotes; your split turns the list into an actual diagnostic: when a metric surprises you, first ask which axis it forked on. That goes in, credited. The post lands this week — I'll hold you to that first comment.