Performance
SwiftAgency is measured, not just described as fast. These are Lighthouse 13.5 results on the production build with the demo content, the Signal preset and the light theme.
Scores
Section titled “Scores”| Page | Desktop | Mobile performance | Mobile LCP | Mobile CLS |
|---|---|---|---|---|
/ |
100 / 100 / 100 / 100 | 97 | 2.2 s | 0.047 |
/work |
100 / 100 / 100 / 100 | 98 | 2.3 s | 0.000 |
/case-study/northgate-architects |
100 / 100 / 100 / 100 | 99 | 1.9 s | 0.000 |
/case-study/halden-rail |
100 / 100 / 100 / 100 | 98 | 2.1 s | 0.000 |
/case-study/tessellate-festival |
100 / 100 / 100 / 100 | 97 | 2.3 s | 0.000 |
/services |
100 / 100 / 100 / 100 | 98 | 1.8 s | 0.000 |
/studio |
100 / 100 / 100 / 100 | 99 | 2.1 s | 0.022 |
/careers |
100 / 100 / 100 / 100 | 98 | 1.8 s | 0.005 |
/journal |
100 / 100 / 100 / 100 | 98 | 2.4 s | 0.000 |
/journal/two-languages-one-sign |
100 / 100 / 100 / 100 | 97 | 2.3 s | 0.000 |
/de/contact |
100 / 100 / 100 / 100 | 98 | 1.8 s | 0.015 |
/id/privacy |
100 / 100 / 100 / 100 | 99 | 1.8 s | 0.003 |
Desktop is Performance, Accessibility, Best Practices and SEO. On mobile, Accessibility, Best Practices and SEO are 100 on every page, and Total Blocking Time is 0 ms everywhere: the whole site ships about 20 KB of JavaScript.
Mobile uses Lighthouse’s default simulation of a mid-range phone on a throttled 4G connection. What remains of mobile LCP is mostly the 88 KB variable font behind the width-axis effect; text never waits for it, but it shares bandwidth with the hero image.
The full tables are in docs/LIGHTHOUSE.md in the theme.
Measure it yourself
Section titled “Measure it yourself”npm run buildnpm run preview # http://localhost:4321npx lighthouse http://localhost:4321/ --preset=desktop --viewnpx lighthouse http://localhost:4321/ --view # mobileOr run the same checks as CI, seven pages three times each:
npm run lighthouseMeasure the production build, never npm run dev. The dev server skips optimisation and loads extra tooling.
CI keeps the scores
Section titled “CI keeps the scores”GitHub Actions runs Lighthouse CI on every push and pull request. The job fails when a page drops below:
| Category | Minimum (desktop) |
|---|---|
| Performance | 95 |
| Accessibility | 100 |
| Best practices | 100 |
| SEO | 100 |
The pages and thresholds are in lighthouserc.json. Reports are saved as a lighthouse-reports artifact on each run, so you can open a failing report and see exactly what changed.
What makes it fast
Section titled “What makes it fast”- Static HTML with CSS inlined into each page, so the first paint needs no extra request.
- Images through
astro:assets: WebP, a responsivesrcset, explicit dimensions, lazy loading below the fold andfetchpriority="high"on the hero. - Self-hosted variable fonts with metric-matched fallbacks, so the font swap doesn’t move the layout.
- No framework. Interaction is a handful of small TypeScript modules. Keystatic’s React is loaded in development only.
- No scroll listeners. Scroll effects use CSS scroll-driven animations and
IntersectionObserver.
Keep it fast with your content
Section titled “Keep it fast with your content”- Export large, don’t pre-compress. Astro makes the sizes. A 2400px JPEG is a good source; a 12 MB PNG makes builds slow but pages still fast.
- One
priorityimage per page, the one at the top. See Media. - Don’t fade in the hero. Keep
data-revealoff the largest element on screen at load. - Think before adding scripts. An analytics or chat widget can cost more than the whole theme. Load it with
defer, or after the page has loaded, and measure again. - Turn off the preset switcher (
theme.switcher: false). Then only one preset’s CSS ships.