When we launched our free Website Health Check, the first site we tested was our own. softxmind.com scored 81 out of 100 (grade B), with 4 critical issues and 7 warnings. Within a day it scored 100/100 in all six categories, and Google PageSpeed Insights rated it 100 for performance, accessibility, best practices and SEO. This is exactly what we found, what we changed, and what we learned along the way.
Key takeaways
- Our biggest problems weren't speed. They were privacy (no privacy policy, analytics without consent) and security (missing headers and no email spoofing protection).
- Moving DNS providers had silently removed our domain's email records, including SPF and DMARC.
- A cookie banner that appeared a second late pushed our Speed Index from "good" into "needs improvement". Rendering it with the page took Speed Index from 3.9 s to 1.1 s.
- Not every optimisation helps: inlining all our CSS would have more than doubled the page's download size, so we didn't ship it.
The starting point: 81 out of 100
| Category | First scan | Final scan |
|---|---|---|
| Performance | 99* | 100 |
| Security | 59 | 100 |
| SEO | 100 | 100 |
| Accessibility | 94 | 100 |
| Privacy & cookies | 45 | 100 |
| Mobile | 100 | 100 |
| Overall | 81 (B) | 100 (A) |
*Google's speed test wasn't available during that first scan, so the performance figure comes from running Google PageSpeed Insights on the homepage directly. The overall 81 was calculated from the other five categories.
The site was already fast and well optimised for search. The surprises were elsewhere.
Fix 1: Privacy, from 45 to 100
The report's top two issues were both privacy:
- No privacy policy linked. We simply didn't have one on the new site, an easy thing to miss in a redesign.
- Tracking without consent. Google Analytics loaded for every visitor, including those in Europe, with no cookie banner.
What we did:
- Published a Privacy Policy, Terms of Service and Cookie Policy that describe what the site actually does, and linked them in the footer.
- Added a consent banner with equally prominent Accept and Reject buttons, and a Cookie settings link in the footer to change the choice later.
- Set Google Consent Mode v2 defaults to "denied" before any Google tag can load.
- Changed Google Analytics to load only when allowed: after opt-in for visitors in Europe, and after the first interaction elsewhere. Visitors who reject it have its cookies removed.
A side benefit: Google's tag no longer competes with the page while it loads, which helped our speed scores too. More on the rules in our guide to website privacy compliance.
Fix 2: Security, from 59 to 100
Security headers
The site was missing several standard protective headers. We added them in the framework's configuration so every page sends them:
- Content-Security-Policy listing only the third parties the site really uses.
- Strict-Transport-Security (HSTS) for two years, including subdomains.
- X-Frame-Options: SAMEORIGIN against clickjacking.
- X-Content-Type-Options: nosniff, Referrer-Policy and Permissions-Policy.
We also stopped the server announcing its framework in an X-Powered-By header. Before shipping the CSP, we tested every page type (forms, video embeds, the admin area and bot protection) to make sure nothing was blocked.
The email surprise
The scan flagged no SPF record and no DMARC record. When we looked closer, the domain had no mail records at all. They had been lost when we moved our DNS to a new provider. That meant anyone could spoof our domain, and our own transactional emails were at risk.
While we were adding SPF and DMARC, the team set up the new mailbox provider at the same time, and we briefly ended up with two SPF records and two DMARC records. Two SPF records make SPF fail completely, so we merged them into one record covering both the mailbox provider and our sending service, and kept a single DMARC policy set to quarantine. The full method is in our guide to checking and fixing SPF and DMARC.
Fix 3: Accessibility, from 94 to 100
Google Lighthouse flagged three problems:
- Colour contrast. Some muted grey text on white had a contrast ratio of about 4.1:1, just under the 4.5:1 minimum. Darkening it by one shade fixed it without changing the design's feel.
- Links without names. The social media icons in our footer had no text a screen reader could announce. Adding an
aria-labelto each fixed it. - Tap targets. The new footer links (Privacy, Terms, Cookies) were too small and close together for comfortable tapping on a phone. We gave each a 44 px tap area.
Fix 4: Performance, from 99 to 100, and Speed Index from 3.9 s to 1.1 s
Oversized client logos
Our client logo carousel loaded the original image files, some over 300 KB each, about 1.7 MB in total, to display them roughly 150 pixels wide. Serving them through automatic image optimisation cut each one to a few kilobytes.
The cookie banner that slowed us down
After adding the consent banner, Speed Index (how quickly the visible screen finishes drawing) jumped to 3.9 seconds. We compared frame-by-frame recordings of Google's test and found two causes:
- The banner appeared about a second after the page, so the screen kept changing.
- Its HTML sat at the very end of the page, so on slower connections it arrived last.
We moved the banner to the start of the HTML and had a tiny inline script decide whether to show it before the first paint. Now it appears with the page, and visitors who have already chosen never see it flash.
Images that jumped the queue
Some logos and icons far down the page were being downloaded at the highest priority, competing with the fonts and styles the first screen needs. Making them load lazily left only the truly critical files at the front of the queue. Speed Index dropped to 1.1 seconds.
The optimisation we didn't ship
One option to remove the last render-blocking stylesheet was to inline all CSS into every page. We measured it first: because of how our framework embeds styles, the compressed page grew from 34 KB to 79 KB. That costs more than the 0.1 seconds it saves, so we kept the external stylesheet and adjusted our tool to ignore speed opportunities under 0.3 seconds, which Google gives no weight anyway.
The result: 100/100
Google PageSpeed Insights now rates the homepage 100 for performance, accessibility, best practices and SEO on mobile, and every Core Web Vital is in the "good" range.
What we learned
- Fast isn't the same as healthy. A site can score 99 for speed and still have serious privacy and security gaps.
- Infrastructure changes break invisible things. Re-check DNS and email records after any migration.
- Compliance features affect performance. A consent banner needs to be built as carefully as the rest of the page.
- Measure before you optimise. The most-recommended fix isn't always a net win.
- Use real recordings to debug. Frame-by-frame filmstrips showed the cause of our Speed Index problem in minutes.
Frequently asked questions
How long did it take to get from 81 to 100?
About one working day, including writing the privacy pages, adding the consent system and security headers, fixing DNS and tuning performance. Most individual fixes took under an hour.
Is a perfect website health score realistic for most businesses?
For most marketing and business websites, yes, or very close. The common issues (security headers, privacy policy, consent, meta tags, image sizes and email records) are well understood and quick to fix.
Did adding a cookie banner hurt performance?
At first, yes: it pushed Speed Index from good to "needs improvement" because it appeared late. Rendering it with the page and deciding visibility before the first paint fixed it completely.
What was the single most important fix?
Restoring SPF and DMARC. It protects customers from invoice fraud using our domain, and it's invisible until something goes wrong.
Can you do the same for our website?
Yes. Run a free check to see where you stand, then use "Get these fixed" on your report or request a quote. Our engineers will reply within 24 hours with a fixed-price plan.
How does your site compare? Run a free website health check and see your score in about 30 seconds.



