Triggering Render Completion# has several heuristics for automatically detecting when a page is done rendering:

  • waiting for the "load" event
  • waiting for the event loop to become free
  • tracking and waiting for in-flight requests (media, css, Ajax requests) to complete
  • waiting for websocket activity to die down
  • detecting endless websocket activity and ignoring it after a few seconds
  • a native Chrome Headless feature: (virtual time policy)
  • detecting endless requests to a similar resource (ad networks frequently do this) and ignoring it

But sometimes this isn't enough, for example, here are some edge cases we've seen:

  • you want to finish the render faster through explicit control
  • async UI work with long after the "load" event
  • animations and svg
  • infinite loops (not something that can be solved other than a code fix)
  • other things we haven't thought of

3 Solutions#

1. Configure to wait longer#

Try our HTTP header: Prerender-Wait-Extra-Long: true which will add approximately ~2s to your render time.

2. Explicitly control when the page is done rendering#

note: was previously known as (rebranded 2022-05-01)

This option is not recommended because it requires diligence and if not configured correctly causes your pages to time out.

When your page starts loading, set:

window.prerendercloudReady = false

and when it's ready to be pre-rendered, set:

window.prerendercloudReady = true

Note: You must set it to true because that's what waits for before returning a response. If never set true, it will just timeout.

In General, the approach looks like:

window.prerendercloudReady = false;
window.fetch("").then(res => {
  // do some rendering
  window.prerendercloudReady = true;

In ReactJS this could look like:

but this gets hard to manage if you a big tree of components each making their own async requests.

componentWillMount() {
  window.prerendercloudReady = false;

componentDidMount() {
  window.prerendercloudReady = true;

// react doesn't call this on first render (hence componentDidMount)
componentDidUpdate() {
  window.prerendercloudReady = true;

3. Worst case scenario#

For extreme situations, you can simply set a timer:

window.prerendercloudReady = false;
setTimeout(() => {
  window.prerendercloudReady = true;
}, 6000);