interviewpath
  • 0day streak
  • 10total XP
  • Level 1

Focus mode

Accessibility and web performance

Read alongside

ARIA Authoring Practices Guide (APG): 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.

Objectives

  • Explain why semantic HTML comes first and apply the rules of ARIA use: native element first, no conflicting roles, keyboard support, never hiding focusable content, and an accessible name for every control.
  • Implement keyboard operation and focus management for a modal dialog and for a client-side route change.
  • Check text and UI contrast against WCAG 2.2 AA thresholds and test a page with a screen reader.
  • Define LCP, INP and CLS with their good thresholds and explain how they are assessed (75th percentile, field versus lab data).
  • Diagnose a slow page with the DevTools Performance panel and Lighthouse, attributing the problem to network, script, rendering or layout shifts.
  • Propose fixes for the common causes of poor LCP, INP and CLS, including bundle size and rendering cost.

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: none is 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.

Self-check before you finish

  1. Why is a native button preferable to a div with role="button"?
  2. What must happen to focus when a modal dialog opens and when it closes?
  3. What does aria-hidden="true" do, and why must it never be on a focusable element?
  4. What contrast ratio does WCAG 2.2 AA require for body text and for large text?
  5. What does INP measure that load metrics miss?
  6. Why can field data disagree with a Lighthouse run?
  7. Name three causes of layout shift and the fix for each.