amphtml: Early styling suggestion on fast failure to load v0.js

Background AMP pages use a clever CSS animation to hide rendering until the AMP runtime has loaded, in order to avoid the dreaded flash of unstyled content:

(Simplified by removing the vendor-prefix variants):

<style amp-boilerplate>
animation:-amp-start 8s steps(1,end) 0s 1 normal both}
@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}
</style>

For browsers which don’t execute Javascript, there is a fallback:

<noscript>
<style amp-boilerplate>
body {animation:none}
</style>

If Javascript is enabled, but the AMP javascript is slow to load, the 8 second animation unblocks the rendering after 8 seconds. A reasonable compromise.

Problem Sometimes Javascript is enabled, and the AMP javascript fails to load in a manner which is detectable much earlier than 8 seconds. For example, if DNS fails to resolve to cdn.ampproject.org, a publisher’s CORS header prevents loading the cross-origin resource, or an overzealous ad blocker prevents the request.

In these situations, it would be nice to “fail fast” and unblock the visibility of the page faster than 8 seconds.

Proposal We can take advantage of the onerror attribute in browsers that have support and we can use this feature to “fail fast”. For example:

<script async src="https://cdn.ampproject.org/v0.js"                       
  onerror="document.getElementsByTagName('body')[0].style.cssText += 
           'webkit-animation:none;' +
           '-moz-animation:none;' +
           '-ms-animation:none;' + 
           'animation:none'"></script> 

This seems to work, though there is probably a shorter / more elegant version. I could use help in finding that minimal incantation.

I propose that we add this onerror attribute to all v0.js script tags in the AMP Cache and anywhere the AMP transformers run, such as the AMP Packager. We should also allow this exact onerror string in the AMP validator, though not require it.

@ampproject/wg-runtime for thoughts and @cramforce who originally designed the CSS timeout animation.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 1
  • Comments: 53 (47 by maintainers)

Most upvoted comments

@westonruter @schlessera FYI for the Wordpress Optimizer

I think it might be good to have an attribute on the <html> tag set to cheaply detect whether ESM is used or not (without regexing the content or iterating over the nodes).

This should probably be i-amphtml-module/i-amphtml-esm to denote ESM support, instead of denoting no ESM support, as the modules are only added by the optimizer, and hand-coding AMP (which would have no ESM) should not need the additional tag to be valid.

I’d be fine with Option A.