Partially Busy/Loading “View First” Pages Experiments

This page is for testing circumstances in which you have partial content — so-called “view-first” content — loaded on a page and spinners or some other static or animated temporary graphic loaded as placeholders for content that the page is waiting on (because of slow services, network delays, a desired visual effect, etc.).

Question: Are there loss of focus issues that could impact a screen reader user or DOM navigation anomalies that interfere with an accurate understanding of the page for an assistive technology user?

You can test 17 implementations:

  1. Image alone:
    Unloaded content is represented by an image alone, with alternative text of “loading.”
  2. Image wrapped, remove the aria-hidden div:
    Unloaded content is represented by an image wrapped in two div elements, an outer div with role=img and aria-label=loading, and an inner div that is aria-hidden=true. The label and role are removed from the outer div at load time and the inner div is replaced by the loaded content.
  3. Image wrapped, remove the aria-busy div:
    The same as the second implementation, except the inner div is aria-busy=true.
  4. Image wrapped, keep the div, remove the aria-hidden attribute:
    The same as the second, except we keep the inner div and replace just the image, removing aria-hidden from the inner div.
  5. Image wrapped, keep the div, remove the aria-busy attribute:
    The same as the third, except we keep the inner div and replace just the image, removing aria-busy from the inner div.
  6. Image aria-hidden, below accessible text loading message, remove image after adding content below it
    Similar to first implementation, except image is aria-hidden and loading image is plain text above the image. When content loads, aria-hidden image is removed.
  7. Image aria hidden, no loading message, remove image after adding content below it
    Similar to 6 but without the loading message text.
  8. Image in aria-busy div, load content then set div to aria-busy=false
    Uses aria-busy for the busy container.
  9. Image in aria-hidden div, load content then set div to aria-hidden=false
    Same as 8, except we use aria-hidden for the container. This might be a recommended technique, when used with an aria-live notification, for all platforms except iOS, which has a DOM rendering bug (see 17).
  10. Image in aria-hidden div, faux image above, load content, remove label on faux image
    Like 9, except we add a faux image above the new content area (a span with aria-label=loading role=img, then load the content, set aria-hidden=false, and remove faux image's semantics by setting it to role=presentation and removing the label.
  11. Image in aria-hidden div, heading above given loading message:
    Like 9, with addition of aria-label on heading of content above the loading content, which tells the user that something below has not yet completed loading.
  12. Image in aria-hidden div, upon load, notification is pumped into aria-live region in the new content
    This technique is the same as 9, except we append to the loaded content an aria-live region, which contains the "new content loaded" message, as an attempt to trick iOS VoiceOver into refreshing its internal DOM snapshot/virtual buffer. (Note: This test implementation disables the normal live region announcements, since we are stuffing live region messages into the new content.)
  13. Image in aria-hidden div, temporary, onfocus activated link above turned on when content loads
    This technique is the same as 9, except there is an (initially) inactive link element above the new content regions that, when the new content finishes loading and a user focuses the link, forces focus to the first element within the new content. Trigger link element is removed from the DOM after being used once. Like 12, this is an attempt to work around a Safari+iOS VoiceOver bug, which makes newly added content unavailable to the screen reader. (Note: Because this implementation requires a slightly different page structure on page load, it gets in own special page.)
  14. Image in aria-hidden div, temporary, onfocus activated screen reader text-only link turned on when content loads
    An evolution of 13 with some extra perks (view the link), which removes the focus timing delay and uses hidden accessible text in a link as the trigger. The text changes after load to something more friendly — from “new content loading” to “content loaded” (hoping focus gets thrown even if hidden text is typically non-interactive in VO iOS)
  15. Image in aria-hidden div, temporary, onfocus activated floating transparent image link turned on when content loads
    An evolution of 13, which removes the focus timing delay and uses a floating and transparent image as a trigger (because previous test failed in Talkback: no focus event was detected on the hidden accessible text)
  16. Image in aria-hidden div, temporary, onfocus activated link above turned on when content loads, onfocus targets node that removes itself once blurred (version which uses blur to remove target)
    An evolution of 14, which attempts to remove the burden from developers in having to decide/know in advance what to focus in the newly loaded container. This may help make the technique a bit more robust, since iOS VoiceOver is so finicky about what can get programmatic focus.
  17. Image in aria-hidden div, temporary, onfocus activated link above turned on when content loads, onfocus targets node that removes itself once blurred (version which targets an empty container which is never removed)
    Like 16, but the blur triggering removal of the target was causing iOS to lose focus. This one just leaves the (now empty) target in the page. It introduces the potential of a blank swipe target but focus issues are gone. This might be a recommended technique for iOS, until Apple addresses this DOM rendering bug.

View-First Test Settings

An ARIA live region announcement is used to notify the user when loading is completed. This can be turned off if desired.

Once initiated, the loading images will be replaced by content. The first image is replaced in 10 seconds, the second, 5 seconds later, to allow for the tester to navigate the screen reader to the loading images prior to content load.



The content testing area is between the horizontal rule separators, below.


Heading Already Loaded

Some content in a paragraph and stuff loads below me in 10 seconds.

I leave a white and turbid wake; pale waters, paler cheeks, where'er I sail. The envious billows sidelong swell to whelm my track; let them; but first I pass. Yonder, by ever-brimming goblet's rim, the warm waves blush like wine.

More Content Loads Below in 15 Seconds

a link as a tab target