Retour au blog

PageSpeed Improvements on pwask.com

Performance29 décembre 20252 min de lecturePar l'équipe PWASK

Summary of performance, accessibility, and best-practice optimizations implemented on PWASK, with code examples.

PageSpeed Improvements on pwask.com

Why these improvements?

We targeted PageSpeed Insights findings (Performance, Accessibility, Best Practices) to improve perceived speed, reduce network payload, harden security headers, and ensure readable typography in both light and dark themes.

Image optimization

Avatars

Avatars were ~500–600 KB each while rendered at ~40×40 px. We resized to 80×80 (@2x) and compressed to ~4 KB per image (≈ 99% reduction).

# Batch resize and compress avatars
magick *.jpeg -resize 80x80^ -gravity center -extent 80x80 -quality 85

PNG → WebP

Large PNGs were converted to WebP for superior compression, and references updated.

magick image.png -quality 85 image.webp
magick pwa-starter-kit-1024.png -quality 85 pwa-starter-kit-1024.webp
magick pwa-starter-kit-512.png  -quality 85 pwa-starter-kit-512.webp

The Open Graph image (og-image.jpg) was optimized at 1200×630, quality 80 (~124 KB → ~44 KB).

Next.js Image Optimization

We removed the unoptimized flag to leverage Next.js' image pipeline (lazy-loading, modern formats, srcset).

// Before
<Image src="/images/avatars/alice.jpeg" width={36} height={36} className="object-cover" unoptimized />

// After
<Image src="/images/avatars/alice.jpeg" width={36} height={36} className="object-cover" />

Accessibility: contrast and readability

Several light-theme texts used low-contrast shades (text-gray-500/600, text-amber-600). We strengthened contrast using darker variants (e.g., text-gray-700, text-amber-700/800) aligned with WCAG AA.

// Example
<p className="text-sm text-gray-600">...</p>
// ➜
<p className="text-sm text-gray-700">...</p>

Correct image aspect ratio

The Hero image was square (500×500) while the original is portrait (1024×1536). We corrected to 512×768 to avoid warnings and distortion.

<Image src="/images/pwa-saas-starter-kit.webp" width={512} height={768} />

Best practices: scripts & install banner

Defer non-critical scripts

Service Worker registration is now deferred, reducing initial render impact (FCP).

// src/app/[locale]/layout.tsx
<script defer dangerouslySetInnerHTML={{ __html: `if('serviceWorker' in navigator){ /* ... */ }` }} />

PWA install banner

To avoid the "preventDefault() without prompt" warning, we show our custom UI quickly (5s) after the beforeinstallprompt event.

// src/components/InstallPrompt.tsx
setTimeout(() => { setShowPrompt(true); }, 5000);

Security: hardened HTTP headers

Added HSTS, XFO, COOP/COEP, Referrer-Policy, Permissions-Policy, and a comprehensive CSP via next.config.ts.

// next.config.ts (excerpt)
export default {
	async headers() {
		return [{
			source: '/:path*',
			headers: [
				{ key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
				{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
				{ key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },
				{ key: 'Cross-Origin-Embedder-Policy', value: 'credentialless' },
				{ key: 'Content-Security-Policy', value: "default-src 'self'; img-src 'self' data: https: blob:; connect-src 'self' https://*.supabase.co wss://*.supabase.co" },
			],
		}];
	},
};

Results

  • Performance: 100/100 (mobile), LCP ≈ 1.2 s
  • Accessibility: 100/100 (contrast fixes)
  • Best Practices: 100/100 (security headers, optimized images)
  • Payload: avatars ~15 MB → 120 KB (total), OG ~44 KB, heavy PNGs converted/removed

These improvements are live on pwask.com and built into the starter to give you a solid, high-performance base.