Skip to content
performance

How We Get 100 Lighthouse on Every Site

February 25, 2026 Updated September 17, 2026 By Alex Crabinsky
How We Get 100 Lighthouse on Every Site

Every Amrify template has to score 100 in Performance, Accessibility, Best Practices and SEO before it can ship. Not on a blank demo page: on sites with a navigation, a hero photo, a contact form, a blog and a sticky call button, running in production for real businesses.

The scores are not a tuning exercise done at the end. They are the consequence of a handful of architectural decisions and one CI job that refuses to merge anything that breaks them. Here are the decisions.

Why Templates Lose Points After You Buy Them

The typical template demos at 95 and lands at 65 once a real business is in it. The pattern is always the same: a hero photo that nobody resized, a second font family for the headings, an analytics tag pasted in the head, a carousel that brought a framework runtime along. Each is a few points. Together they are a red score.

So the system is built so that adding content cannot do that. Images go through a pipeline that resizes them. Fonts are a config value with a load strategy attached. Scripts are gated behind IDs you set on purpose. Interactive parts are islands that load only where they render.

Ship No JavaScript Unless a Widget Needs It

Astro renders pages to HTML and includes no client framework unless a component asks for one. The free Starter takes that all the way: there is no JavaScript framework in it at all. The mobile menu is the Popover API, the FAQ accordion is <details>, scroll reveals and page transitions are CSS, and dark mode follows the system setting through light-dark() color tokens.

Amrify Pro adds interactive widgets (estimate calculator, quote wizard, reviews carousel, before-and-after slider) as SolidJS islands, mounted per widget. SolidJS compiles to direct DOM updates without a virtual DOM runtime, so a page pays only for the widget it shows:

<!-- static by default: zero JS -->
<Header />
<HeroSection />
<ServicesGrid />

<!-- an island, hydrated only when it scrolls into view -->
<EstimateCalculator client:visible />

A roofing homepage with no calculator on it ships no calculator code. That sounds obvious and is the single largest reason Total Blocking Time stays at zero.

Images Are the Usual Culprit

Most failed Performance audits are image audits. The templates route every content image through Astro’s built-in image pipeline:

  • Modern formats. Images are converted to WebP at build time
  • Right-sized. A srcset is generated so a phone downloads a phone-sized file
  • Reserved space. Every image carries width and height, so nothing shifts when it arrives
  • Priority for the hero. The LCP image is loading="eager" with fetchpriority="high" and can be preloaded from config; everything below the fold is lazy

That combination is what keeps Cumulative Layout Shift at zero on pages full of photos and keeps the hero inside the LCP budget on a simulated phone connection.

Fonts Without a Flash

Web fonts fail Lighthouse two ways: they block text from rendering, or they swap in late and shift the layout.

The templates use Astro’s Fonts API with the Google provider. At build time Astro fetches the family named in the site config, writes the font files into the site’s own output and emits the @font-face rules, so a visitor’s browser never opens a connection to Google. Only the weights the design uses are requested, the fallback stack is the system UI font, and the brand font is preloaded with <Font preload /> so the hero text does not wait on a late discovery. The result is one small same-origin font request instead of two third-party connections, and no flash of invisible text.

A CSS Budget You Do Not Have to Think About

Tailwind CSS 4 scans the templates at build time and emits only the classes in use, so the stylesheet stays small no matter how big the component library behind it is. Astro then inlines small stylesheets into the page (build.inlineStylesheets: "auto"), which removes a render-blocking request on the pages that matter most.

One rule we learned the hard way: no global transition-all. A transition on every element makes a theme switch visibly crossfade the whole page, which looks like a bug and reads as one in a layout-shift trace. Transitions are scoped to the things a user actually interacts with.

Accessibility Is a Build Concern, Not a Review Concern

The Accessibility category is where hand-built sites lose points quietly. The templates bake the fixes into the shared layouts, so a new site cannot forget them:

  • Semantic structure. One h1, headings in order, <nav>, <main> and <footer> landmarks, ARIA only where HTML has no element for the job
  • Contrast. Theme colors are checked against WCAG AA. If you add a dark palette, check it on its own; a pair that passes in light mode routinely fails in dark
  • Keyboard. Every control is reachable and operable by keyboard, with a visible focus ring
  • Skip link. A “skip to content” link for screen reader and keyboard users

The SEO Category

The fourth category is technical hygiene, all generated from config and content:

  • Title, description, Open Graph and X card tags on every page, with a per-page social image
  • JSON-LD for Organization or LocalBusiness, Article, FAQPage and BreadcrumbList, built from the same validated content that renders the page
  • A canonical on every page and a sitemap generated at build time
  • robots.txt and llms.txt

The full list is in the 25-step Astro SEO checklist.

Dark Mode Without the Flash

Dark mode is a classic way to fail an audit: the page paints light, the saved preference loads, the page repaints dark. Both the Starter and Pro avoid the repaint by making the theme a property of the CSS rather than a script.

Every color token is a light-dark() pair, so the browser picks the right value from the visitor’s system setting before anything renders. When the optional toggle is on, a single inline statement in <head> re-applies a saved data-theme before first paint, which is the only theme-related JavaScript on the page. Page transitions are native cross-document view transitions declared with the @view-transition at-rule, so there is no client-side router to carry state across, no swap event to hook, and nothing to crossfade. The correct theme is the only theme the page ever paints.

The Gate

None of the above would hold without enforcement. Every template runs Lighthouse in CI on real built pages, and a build fails if any of the four categories drops below 100. The rule catches the third-party script someone pasted in, the oversized photo, the button whose new color fails contrast, and it catches them before a client ever loads the page.

Check It Yourself

The proof is public. The showcase lists live production sites built on this system. Pick one and run it through the free Website Grader, which uses Google’s own PageSpeed test on a simulated phone; there is no email gate and it takes about thirty seconds. Those are real sites with real photos and real forms, not a demo tuned for the test.

When the Starter repo opens at launch, clone it, add your own content, and run pnpm lighthouse before you deploy. The gate travels with the code.


Do not take the number from this post; take it from Google. Grade any live Amrify site with the free Website Grader, then grade your own site right after and compare the four columns. If the second set is where you want to be, the free Starter is the codebase the first set came from.

Tags: performance
Share:

Ready to build your next agency site?

Start with the free tools today and the free Starter at launch, or own Amrify Pro - every niche template in one purchase.

Get Amrify Docs