A snippet of an archived email conversation between accessibility professionals: George Zamfir, David Newton, Henri Helvetica, Monica Piotrowicz, Alice Boxhall and Tim Kadlec. I have noted who I thought was speaking, but it was hard to tell from the thread. Please comment if I can update the attribution!
- SR = Screen reader
- AT = Assistive technology
- a11y = Accessibility
- VO = Voiceover
...the page has been rendered and painted. However, the SR is still waiting for the loading to complete entirely before creating that list of items. My first thought was that maybe there's a way to get SR's to be more aggressive here—if the page is rendered, why not build that list?
Just because the page is rendered doesn't mean the accessibility tree (I think that's what you mean by "list of items") is generated 100%. And screen readers (SR) wait for that to happen first. All SRs have some waiting mechanism for this reason.
A bit of info on a11y trees, feel free to skip if this is boring :)
The accessibility tree is a subset of the DOM tree (generally speaking) but they're parallel structures and the all-important accessibility APIs sit in the middle to expose the DOM info to the a11y tree. Part of this reason is simplicity & performance, funny enough. Here's how to inspect the a11y tree.
Is the a11y tree built from the DOM, or built in parallel to the DOM? If it’s built from the DOM, then we should always expect the DOM to be ready before the a11y tree, and expect DOM changes to finish before a change in the a11y tree is finished. But if they’re built/updated in parallel, there might be some interesting opportunities for performance enhancement.
Sometimes though, SRs also scrape the DOM directly. In most cases it's because SRs find that they can't get all the info they need from the APIs alone; this happens in particular when new HTML/5 elements become part of the spec and this is where ARIA fills the gap. Other times, SRs like ChromeVox bypass the a11y APIs completely and scrape the DOM directly. I'll refrain from commenting on this :) But more seriously Alice may have context as why ChromeVox is doing that.
So, why do SRs wait for the a11y tree to be generated to 100%? I think there are 2 answers here: 1/ Because the a11y tree is a mess to generate in the first place and all OSs / SRs / browsers / a11y APIs do it slightly differently. Thus even the damn a11y tree is different from one combo to another. Which is why <a href="#" role="button"> is a link in JAWS (older versions) but a button in VO.
This is…interesting. It sounds like if we actually wanted to look for improvements, there would be multiple fronts to target: 1) web devs who make potentially poorly performing sites, 2) gaps in web standards that lead to inconsistent implementations, 3) AT devs who make potentially poorly performing products. I think the place you’d get the most traction is with the standards, which would hopefully filter down to improvements from web and AT devs.
I think that SRs feel they have enough on their hands just reading the damn a11y trees and building asynchonicity is unnecessary complexity. I have no idea what would happen or should happen if ATs don't wait for the a11y tree to be generated to 100%. Well, except for VO :)
I don’t think an SR shouldn’t wait for the a11y tree to be built. I’m more curious if there are optimizations that can be made about when it starts getting built, how quickly it gets built, and what is sufficient for considering it done.
But even when VO allows you to do some things (TAB is one of them) it tells you if stuff is not completely loaded. For example bring up a headings list (VO+U) while cnn.com is loading and it will first say "loading headings..." (or smth like that). On another note I think this is a good example of improved performance, or at least perceived improvement. And that's just because VO chose to be more asynchronous.
2/ Because some SRs are not very good at dealing with dynamic DOM tree changes (and by extension a11y tree changes). And they might interpret a partial tree as the full tree and SR users missing out on content.
As a real-world example facebook.com comes to mind. The website is built (to handle the bazillion visits each day) in such a way that each module is delivered to the browser one at a time; well, mostly. Each module is a DOM node and contains everything that needs to be rendered: data, html, css, js, etc. (BTW, this was fascinating to me, if you want to know more about fb performance have at it). Even with not-so-old SRs (JAWS 13, 14) they have a hard time just dealing with the synchronous building of the a11y tree. So much so that they would often crash :). So, I think that giving users access to a partial tree while asynchronously loading the rest opens up the door to a whole new set of problems. As in, "hey there new DOM node injected asynchronously when did you get here?" :). If that new DOM node is the Newsfeed, then oups :)
I don't think there's a way around waiting, for us website builders. Well, except for optimizing what we load (hello CNN).
I think we can move on the next bit, which (coincidentally :D) is the more interesting bit for me: What does this mean for the way we talk about performance?
This is a great point, and something I’m very interested in. I’m giving a talk next month that tries to frame performance, a11y, responsive web design and progressive enhancement as all being part of the same philosophy, and how to think about these all together. It’s all about delivering content to the user in the best way possible, right?