Performance & Accessibility Checklist
When to use: Before launch. Monthly audits. After major changes.
The test: Load page on 3G. Try with keyboard only. Still usable?
Core Web Vitals (2024)
These are the metrics Google uses for ranking:
- LCP (Largest Contentful Paint) under 2.5s
- FID (First Input Delay) under 100ms
- CLS (Cumulative Layout Shift) under 0.1
- FCP (First Contentful Paint) under 1.8s
- TTI (Time to Interactive) under 3.8s
Quick Wins
| Problem | Solution |
|---|---|
| Slow LCP | Compress images, use CDN |
| High CLS | Set image dimensions, avoid layout shifts |
| Slow FID | Defer non-critical JavaScript |
| Slow FCP | Inline critical CSS |
Mobile Performance
- Load time under 3 seconds on 3G
- No horizontal scroll
- Touch targets 44px minimum
- Text readable without zoom (16px+)
- Thumb-friendly navigation
Breakpoint Testing
Test at these widths:
| Device | Width |
|---|---|
| Mobile (small) | 320px |
| Mobile (large) | 375px |
| Tablet | 768px |
| Desktop | 1024px |
| Large desktop | 1440px |
Accessibility (WCAG 2.1 AA)
Visual
- Color contrast 4.5:1 for normal text
- Color contrast 3:1 for large text (18px+ bold)
- Information not conveyed by color alone
- Focus states visible on all interactive elements
- No flashing content (3 flashes/second max)
Keyboard
- All interactive elements reachable via Tab
- Focus order matches visual order
- No keyboard traps
- Skip link to main content
- Enter/Space activates buttons
Screen Readers
- All images have alt text
- Decorative images use alt=""
- Form fields have visible labels
- Error messages associated with fields
- Headings in logical order (H1 > H2 > H3)
- Landmarks used (main, nav, aside, footer)
Image Optimization
- WebP or AVIF format used
- Responsive images with srcset
- Lazy loading for below-fold images
- Width and height attributes set
- Compressed (80% quality usually fine)
Size Guidelines
| Use | Max Size |
|---|---|
| Hero image | 200KB |
| Card image | 50KB |
| Icon | 5KB |
| Logo | 20KB |
Script Performance
- Critical JS inlined or preloaded
- Non-critical JS deferred
- No render-blocking scripts
- Third-party scripts audited
- Bundle size monitored
Third-Party Checklist
- Analytics loading async
- Chat widgets lazy-loaded
- Social embeds lazy-loaded
- Fonts preconnected
Testing Tools
Automated
| Tool | What It Tests |
|---|---|
| Lighthouse | Performance, accessibility, SEO |
| axe DevTools | Accessibility |
| WebPageTest | Load performance |
| WAVE | Accessibility |
Manual
| Test | How |
|---|---|
| Keyboard | Unplug mouse, navigate with Tab/Enter |
| Screen reader | VoiceOver (Mac) or NVDA (Windows) |
| Color blindness | Chrome DevTools > Rendering > Emulate |
| Slow connection | Chrome DevTools > Network > Slow 3G |
Monitoring
Metrics to Track
- Core Web Vitals in Search Console
- Real User Monitoring (RUM) enabled
- Error rates monitored
- Performance budget set
Performance Budget Example
JavaScript: < 300KB
CSS: < 100KB
Images: < 500KB total
Fonts: < 100KB
Total page weight: < 1MB
LCP: < 2.5s
TTI: < 3.8s
Playwright Accessibility Test
const { test, expect } = require("@playwright/test");
const AxeBuilder = require("@axe-core/playwright").default;
test("Accessibility audit", async ({ page }) => {
await page.goto("/");
const results = await new AxeBuilder({ page })
.withTags(["wcag2a", "wcag2aa", "wcag21aa"])
.analyze();
expect(results.violations).toEqual([]);
});
Quick Diagnosis
| Symptom | Likely Cause | Fix |
|---|---|---|
| Page feels slow | Large images | Compress, use WebP |
| Layout jumps | Missing dimensions | Add width/height |
| Can't Tab to element | Missing tabindex | Fix focus order |
| Low contrast warning | Text too light | Darken text or lighten background |
| Screen reader skips content | Missing landmarks | Add semantic HTML |