Triggering Render Completion#

Prerender.cloud 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 prerender.cloud 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 prerender.cloud 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#

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 prerender.cloud 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("example.com/api/my-api").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);
Hosted on Roast.io