Unit 2 · Software engineering · Lesson 15 of 15
Accessibility and web performance
Step 1: Learn the ideas
- Semantic HTML and the accessibility tree
- Accessible names, roles and states; rules of ARIA use
- Keyboard operability, focus order and focus management
- Dialogs, menus and composite widgets (APG patterns)
- Contrast and other WCAG 2.2 AA criteria
- Screen-reader and automated testing
- Core Web Vitals: LCP, INP, CLS
- Field data versus lab data
- Bundle size, code splitting and rendering cost
- Measuring with the DevTools Performance panel and Lighthouse
Why it matters
Accessibility and performance failures are defects that show up only for the users who hit them: someone on a keyboard, a screen reader, a low-end phone or a slow network. Frontend interviews test them inside ordinary questions: build a modal, then make it work with a keyboard and a screen reader; explain why a page feels slow and how you would find out.
Core ideas
Semantic HTML first. Native elements come with a role, a source for their accessible name, states and keyboard behavior: a <button> is focusable, activates on Enter and Space and is announced as a button, while a <div> with a click handler has none of that. Headings, landmarks (<main>, <nav>), lists, <label> and table markup shape the accessibility tree that assistive technology reads.
ARIA rules. ARIA changes what assistive technology is told, not how an element behaves. Use a native element whenever one exists; do not override native semantics without need; anything given an interactive role must also work from the keyboard; never put aria-hidden="true" on focusable content; give every interactive element an accessible name. A wrong role or a stale state can be worse than no ARIA at all.
Keyboard and focus. Everything operable by pointer must be operable by keyboard, in a tab order that follows the DOM. Avoid positive tabindex; use tabindex="0" to make a custom control focusable and tabindex="-1" for elements you focus programmatically, and keep a visible focus indicator. A modal dialog moves focus inside when it opens, keeps Tab within it, closes on Escape and returns focus to the control that opened it. A native <dialog> opened with showModal() makes the rest of the page inert and closes on Escape, but you still choose the initial focus and should verify where focus lands on close. After a client-side route change, move focus to the new page's heading or main region so screen-reader users notice the change.
Contrast and WCAG 2.2. Level AA requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text (1.4.3), 3:1 for the visual information that identifies controls and their states, and for meaningful graphics (1.4.11), a visible focus indicator (2.4.7) that is not entirely hidden by other content (2.4.11, new in 2.2), and pointer targets of at least 24 by 24 CSS pixels unless spacing or another exception applies (2.5.8, new in 2.2).
Testing. Automated checkers such as Lighthouse and axe find a subset of problems, like missing labels and low contrast; they cannot judge whether names are meaningful or flows make sense. Add manual passes: keyboard only, then a screen reader (VoiceOver on macOS, NVDA on Windows), then 200% zoom.
Core Web Vitals. Largest Contentful Paint measures loading (good: within 2.5 s), Interaction to Next Paint measures responsiveness across all interactions (good: 200 ms or less) and Cumulative Layout Shift measures visual stability (good: 0.1 or less). Each is assessed at the 75th percentile of page loads, segmented by mobile and desktop; INP replaced First Input Delay in 2024. Field data from real users is what counts; lab tools such as Lighthouse and a DevTools trace are reproducible and explain causes, but one lab run is not a user population.
Causes and fixes. Poor LCP: slow server responses, render-blocking CSS or scripts, or a hero image discovered late or lazy-loaded; fix with server rendering, preloading or fetchpriority="high" on the LCP image, and smaller critical CSS. Poor INP: long tasks in event handlers or large re-renders; break work up, yield, and render less. Poor CLS: images and embeds without dimensions, late-injected banners, swapping web fonts; reserve space with width and height or aspect-ratio. Bundle size costs twice, in bytes to download and in JavaScript to parse, compile and run on the main thread, so split code by route and check the Coverage panel for unused code.
Common misconceptions
- "Adding ARIA makes a component accessible." ARIA only changes announcements; keyboard behavior and focus still have to be built, and incorrect ARIA misleads users.
- "A perfect Lighthouse score means accessible and fast." Automated audits cover a subset of accessibility issues in one lab run; real users and field data can disagree.
- "
outline: noneis fine if the design looks cleaner." Removing the focus indicator without a visible replacement fails keyboard users and WCAG 2.4.7. - "Performance is only about load time." INP and CLS measure what happens after load; a fast-loading page can still feel broken.
- "Lazy-loading everything helps." Lazy-loading the LCP image delays it; load the hero eagerly with high priority and lazy-load content below the fold.
How to approach it
Practice on an app you control: put the mouse away, turn on a screen reader and fix what breaks; then record a slow interaction and fix the long task. Graduate questions usually stay with semantic HTML and keyboard basics; mid-level and senior frontend interviews expect an accessible widget implementation, precise metric definitions and a plan for finding a regression in production data.
Suggested order
- 1Read the APG "Read Me First" page and MDN "HTML: A good basis for accessibility"; replace every clickable div in a small page with native elements and proper labels.
- 2Read APG "Developing a Keyboard Interface" and the "Dialog (Modal) Pattern"; build a modal with focus moved in, Tab kept inside, Escape to close and focus restored, then compare with the native dialog element.
- 3Read WCAG 2.2 success criteria 1.4.3, 1.4.11, 2.1.1, 2.4.7, 2.4.11 and 2.5.8 with the Understanding documents for contrast, focus visible and target size; check your color pairs with the DevTools contrast information.
- 4Test the page with VoiceOver (macOS) or NVDA (Windows): navigate by headings, landmarks and form controls, and fix anything announced incorrectly.
- 5Read web.dev "Web Vitals" and the LCP, INP and CLS articles until you can state each definition and threshold from memory.
- 6Read the Chrome DevTools "Analyze runtime performance" tutorial; record a page load and a slow interaction, identify the LCP element, long tasks and layout shifts, fix one cause of each and re-measure.
- 7Run Lighthouse and the DevTools Coverage panel to find unused JavaScript and CSS; move one large dependency out of the initial bundle and compare.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
ARIA Authoring Practices Guide (APG)Start here
W3C Web Accessibility InitiativeSection: Read Me First
Why bad ARIA is worse than none; then the keyboard interface and accessible-name practices and the modal dialog pattern listed under this resource.
Open(opens in a new tab)Link responded, 5 Oct 2026MDN: Accessibility
MDN Web DocsSection: HTML: A good basis for accessibility
Semantic HTML and the accessibility tree; then WAI-ARIA basics for when ARIA is genuinely needed.
Open(opens in a new tab)Link responded, 5 Oct 2026Web Content Accessibility Guidelines (WCAG) 2.2
W3CSection: New Features in WCAG 2.2
The normative AA criteria named in the study steps and their Understanding documents, including what changed in 2.2.
Open(opens in a new tab)Link responded, 5 Oct 2026web.dev: Web VitalsStart here
Google Chrome team (web.dev)Section: Web Vitals
Metric definitions, thresholds and the 75th-percentile assessment; then the per-metric and optimization articles.
Open(opens in a new tab)Link responded, 5 Oct 2026Chrome DevTools: Analyze runtime performance
Google (developer.chrome.com)Section: Analyze runtime performance
Recording load and interaction traces, finding long tasks and layout shifts, and running Lighthouse.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
Use a small app you control, such as the pages built for the browser-runtime and state topics. Accessibility: complete one keyboard-only pass and one screen-reader pass (VoiceOver toggles with Command-F5 on macOS; NVDA is free on Windows), fix every issue you find, and build an accessible modal dialog and a disclosure menu following the APG patterns. Performance: record a page load and a slow interaction in the DevTools Performance panel, identify the LCP element, long tasks and layout shifts, apply one fix per metric and re-measure; run Lighthouse before and after, and list the problems it did not detect.
No external problems are linked; follow the guidance above.
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1Why is a native button preferable to a div with role="button"?
- Question 2What must happen to focus when a modal dialog opens and when it closes?
- Question 3What does aria-hidden="true" do, and why must it never be on a focusable element?
- Question 4What contrast ratio does WCAG 2.2 AA require for body text and for large text?
- Question 5What does INP measure that load metrics miss?
- Question 6Why can field data disagree with a Lighthouse run?
- Question 7Name three causes of layout shift and the fix for each.
You’re done when you can
- Build a modal dialog that passes a keyboard-only test and a screen-reader test, including focus return on close.
- State the WCAG 2.2 AA contrast thresholds for text and for UI components and check a color pair against them.
- Define LCP, INP and CLS with their good thresholds and explain the 75th-percentile assessment.
- Use a DevTools performance recording to find and fix one long task and one layout shift on a real page.


