Level 5, Professional Practice, Chapter 20 of 24
Accessibility & Performance
Why this matters
Imagine shipping a beautifully designed app, only to learn that a customer using a screen reader can't tell which button submits the order form, or that someone on a train with a weak signal gives up waiting for your page to load. Both of these are everyday realities, not edge cases. Roughly one in six people worldwide lives with some form of disability, and a huge share of web traffic happens on mid-range phones over patchy networks. Accessibility and performance aren't polish you add at the end; they're part of whether your work actually functions for the people who rely on it.
The encouraging news is that most of what you've already learned points you in the right direction. Semantic HTML, thoughtful CSS, and clean JavaScript are the foundation of both accessible and fast experiences. This chapter gives you the vocabulary, tools, and habits to check your work against real standards, so accessibility and performance stop being vague aspirations and become concrete, testable parts of your process.
The lesson
Accessibility is mostly about structure you already know
Back in the HTML chapters, you learned to reach for elements like <button>, <nav>, <label>, and heading levels instead of generic <div>s and <span>s for everything. That habit is the single biggest accessibility win available to you. Screen readers, keyboard navigation, and browser accessibility trees all depend on semantic meaning: a <button> is automatically focusable and operable with Enter or Space, while a <div> styled to look like a button has none of that behavior unless you rebuild it yourself with JavaScript and ARIA attributes. The lesson is simple but easy to forget under deadline pressure: before reaching for ARIA or custom JavaScript behavior, ask whether a native HTML element already does the job.
When native elements aren't enough, ARIA (Accessible Rich Internet Applications) attributes fill the gaps by describing roles, states, and relationships to assistive technology. Attributes like aria-label, aria-expanded, and role let you tell a screen reader what a custom widget is and what state it's in. But ARIA is a supplement, not a substitute, for good HTML, and misusing it can make things worse than having no ARIA at all. A widely cited accessibility principle is: no ARIA is better than bad ARIA. Your goal is always to give every interactive element a clear name, a role the browser understands, and a state that updates as the user interacts with it.
- Use one <h1> per page and keep heading levels in logical order so screen reader users can navigate by structure.
- Give every form input a connected <label>, and every icon-only button an accessible name via text or aria-label.
- Make sure every interactive element is reachable and operable using only the Tab and Enter/Space keys.
- Don't rely on color alone to convey meaning; pair it with text, icons, or patterns.
- Respect prefers-reduced-motion for users who are sensitive to animation.
1<button id="favorite" aria-pressed="false" aria-label="Add to favorites">2 ★3</button>45<script>6 const btn = document.getElementById("favorite");7 btn.addEventListener("click", () => {8 const isPressed = btn.getAttribute("aria-pressed") === "true";9 btn.setAttribute("aria-pressed", String(!isPressed));10 });11</script>Performance is a user experience feature
You already know that JavaScript runs on the user's device, not yours, and that network requests take time — you saw this clearly when working with fetch and APIs. Performance work builds directly on that understanding. Two broad categories matter most: loading performance, which is how quickly the page becomes usable, and runtime performance, which is how smoothly it responds after that. Loading performance is shaped by things like image size, the number and size of your CSS and JavaScript files, and how many render-blocking resources sit between the browser and a visible page. Runtime performance is shaped by how efficiently your JavaScript updates the DOM and responds to events, echoing the DOM lessons from earlier chapters.
Modern browsers expose real measurements instead of guesses. The Lighthouse panel in Chrome DevTools scores a page on performance, accessibility, best practices, and SEO, and gives specific, actionable suggestions like 'serve images in next-gen formats' or 'eliminate render-blocking resources.' Core Web Vitals — Largest Contentful Paint (how fast the main content appears), Cumulative Layout Shift (how much the page jumps around while loading), and Interaction to Next Paint (how responsive the page feels) — are the metrics real companies track because they correlate with whether people stay on a site or leave. Treat these tools the way you'd treat console.error output: informative signals worth acting on, not noise to ignore.
- Compress and correctly size images; a 4000px photo displayed at 400px wastes bandwidth for no visual benefit.
- Load non-critical JavaScript with
deferorasyncso it doesn't block the page from rendering. - Minimize layout shift by reserving space for images and ads with explicit width and height.
- Avoid unnecessary re-renders and DOM thrashing in JavaScript loops.
1<img2 src="/images/hero.jpg"3 alt="Team collaborating around a laptop"4 width="1200"5 height="600"6 loading="lazy"7/>89<script src="/js/analytics.js" defer></script>Testing with real tools, not guesswork
Both accessibility and performance benefit enormously from automated checks, because human review alone misses things. Browser DevTools include an Accessibility panel that shows the computed accessibility tree for any element, revealing exactly what a screen reader would announce. Automated linters like axe or the Lighthouse accessibility audit catch missing labels, poor color contrast, and invalid ARIA usage in seconds. None of these tools replace testing with an actual screen reader or keyboard-only navigation, but they catch the most common mistakes early, the same way console warnings caught bugs earlier in your JavaScript work.
Try it yourself
This card component looks fine visually but fails several accessibility and performance checks. Fix it: make the image icon decorative or labeled appropriately, turn the clickable div into a real button, add a label to the hidden checkbox, and add loading='lazy' plus width/height to the image.
Chapter boss project
Boss Project: The Accessibility & Performance Audit
Take any page you've built in a previous chapter (or build a small three-section landing page if you'd like a fresh start) and put it through a full audit. Run the Lighthouse accessibility and performance reports in DevTools, note every issue it flags, and fix each one directly in your code rather than dismissing warnings.
Then go beyond the automated tool: unplug your mouse for five minutes and navigate your entire page using only the keyboard. Note anywhere you get stuck, anywhere focus disappears, or anywhere you can't tell what's selected. Fix those issues too, since automated tools only catch part of the picture.
Write a short report (as a README or comment block) listing what you found and what you changed, in your own words, as if you were briefing a teammate on the state of the page.
- Lighthouse is built into Chrome DevTools under the 'Lighthouse' or 'Performance insights' tab; run it in an incognito window for the most accurate results.
- A visible focus outline is not optional decoration; if you've removed `outline: none` anywhere, make sure you replaced it with an equally visible custom focus style.
- Check image dimensions and alt text first, since they're usually the fastest wins for both categories.
- If a custom widget doesn't work with Tab and Enter, consider whether swapping it for a native element would remove the problem entirely.
Level-up checklist
Tick these off once each one is true for you.
