Accessibility and Performance
May 05, 2016
This post represents a final distillation of my talks given on Accessibility and Performance at Fronteers, Seattle JS and Generate NYC in April 2016.
When pages heavy with content and ads load in web browsers, such as CNN.com (Youtube video), the experience can be very clunky and unpleasant for all users; not to mention how much of their monthly allotted data is used up loading all those resources. For screen reader users, it's exacerbated: visual content streams in while an auditory progress counter struggles to reach 100% so the page can be consumed.
As someone who likes fixing user experience problems, I wondered: for all the time and energy spent improving web performance, could we do more to improve the experience for users of assistive technologies (AT) as well?
A11y and Performance Sitting in a Tree
The underlying mechanics driving this assistive technology issue came up in an email thread over a year ago amongst some accessibility/web professionals, kind enough to loop me in: George Zamfir, David Newton, Monika Piotrowicz, Henri Helvetica, Alice Boxhall and Tim Kadlec. A really great conversation went around regarding how the accessibility tree works, where the performance slowdowns are in regards to accessibility, and what could be done about it.
After nearly a year had gone by I kept thinking about the thread, which was filled with interesting accessibility questions and answers from some very thoughtful folks. I asked if anyone had given a technical talk on it so I wouldn't steal anyone's thunder. It turns out they hadn't, so I researched the topic further. What follows is my attempt to add accessibility to the #webperf conversation dominating the mainstream conference circuit.
Known User Impacts
Two things I noted right away were sluggish interactivity for keyboard users and the screen reader loading progress issue mentioned above. Delayed user input because the browser is struggling to download and execute a ton of scripts, styles and resources doesn't just pose an annoyance: users could give up on using your website entirely and never come back!
<select> element). I will come back to this idea with regards to ARIA a little later on.
What impacts the accessibility tree?
The takeaway is to avoid expensive operations where the browser has to recalculate how to position and display objects in a webpage, such as
elem.scrollTop, to name a few. (A longer list can be found in this handy gist from Paul Irish.) For accessibility as well as performance, you should limit costly lookups and operations all the time, but especially when a page is loading.
A note on performance metrics: there currently isn't any method for measuring performance of the Accessibility Tree (as far as I know; here are some ideas from Paul Irish). Many people have privacy concerns surrounding accessibility tracking, which impacts any conversation on the topic. You could look at the Navigation Timing API and check when the DOM is interactive and ready, but that only covers the DOM. I would love to see something like "Accessibility Tree Ready" in the Navigation Timing API but gaining consensus would be a challenge. I'm also not sure how practical it would be…but as web performance fundamentals love to say "you can't optimize what you can't measure", it would provide us with something interesting!
Originally at Fronteers I made 3 recommendations for front-end developers to optimize for accessibility and performance; things I learned after working on Angular Material and years of building websites and web applications:
- Use the browser default HTML elements and CSS wherever possible.
- Include default ARIA and tabindex values in HTML rendered from the server.
- Prioritize accessible actions in the critical rendering path.
These were well received except for number 2: for the reasons of progressive enhancement and ARIA rule #1, serving
<md-checkbox role="checkbox" tabindex="0" aria-checked="false"></md-checkbox> gave some people the willies. Although this sample was taken directly from Angular Material, it highlighted two conflicts:
- Use default HTML elements first before using ARIA (contradicting one of my optimizations).
Although it was tough to hear that day, I was really grateful to get feedback from Mallory about NOT setting ARIA defaults in HTML in case JS doesn't load: eliminating optimization #2. I had even done a practice run of the talk before and no one mentioned it, however this kind of feedback is very important to listen to. Progressive enhancement, accessibility and web performance are very closely related: they are all about serving the best possible experience to the widest range of people, who sometimes don't have the latest technology or fastest connection.
Being a member of the Angular team for a while meant I was often confronted with an elephant in the room: what if something goes wrong with JS when your entire application depends on it? (see
A modal-related tangent: I want to see more default elements such as the native
<dialog>, a customizable
Don't forget that people rely on keyboards and assistive technologies to interact with the Web. They need basic accessibility support before you even get to performance tuning. So if you haven't done that yet, start there!