Page Load Detection
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Page Load Detection is a critical feature in Rendertron that determines the precise moment a web page has finished loading all its resources and completed its initial rendering. This is essential for accurately serializing the state of modern web applications, especially Progressive Web Apps (PWAs) and Single-Page Applications (SPAs) that rely heavily on client-side JavaScript for rendering content. Rendertron uses an automatic detection mechanism based on network activity to decide when a page is "ready". This process is constrained by a configurable timeout to prevent indefinite hangs.
Historically, Rendertron supported an explicit signal from the page, but this was removed in version 2.0.0 in favor of a more robust, fully automated approach.
Sources: README.md:80-82, CHANGELOG.md:14, src/renderer.ts
Automatic Detection via Network Idle
Rendertron's primary strategy for detecting page load completion is to wait until the network is idle. It uses Puppeteer's page.goto method with the waitUntil: 'networkidle0' option. This option considers navigation successful when there have been no new network connections for at least 500 ms. This approach effectively handles pages that fetch data or execute scripts asynchronously after the initial load event has fired.
Sources: README.md:80-82, src/renderer.ts:111-112
Implementation Details
The core of this mechanism is found in the Renderer.serialize method.
// src/renderer.ts:109-112
// Navigate to page. Wait until there are no oustanding network requests.
response = await page.goto(
requestUrl, {timeout: this.config.timeout, waitUntil: 'networkidle0'});
This ensures that Rendertron waits for asynchronous operations, like the one tested in script-after-load.html, to complete before it proceeds to serialize the DOM.
Sources: src/renderer.ts:109-112, src/test/app-test.ts:48-52
Page Load and Rendering Flow
The following diagram illustrates the sequence of events from receiving a render request to returning the serialized HTML, highlighting the page load detection step.
This diagram shows the rendering process, with the crucial networkidle0 wait determining when to proceed with serialization.
Sources: src/rendertron.ts:92-97, src/renderer.ts:109-112, 150-155
Rendering Timeout
To prevent requests from hanging indefinitely on pages with continuous network activity or other issues, Rendertron enforces a rendering budget timeout. If the page does not reach the networkidle0 state within this time, the rendering process is aborted, and a partial response may be returned.
Sources: README.md:84-86
Configuration
The timeout is configurable via the config.json file or can be passed during initialization.
| Property | Default | Description |
|---|---|---|
timeout | 10000 | The timeout in milliseconds for rendering a page. |
Sources: README.md:126, src/renderer.ts:111-112
The Renderer class receives this configuration and applies it directly to the page.goto call.
Sources: src/renderer.ts:26, src/rendertron.ts:31
Handling of Web Components
Page load detection is also influenced by the presence of Web Components. To ensure custom elements are rendered correctly before serialization, Rendertron forces the Shady DOM and Shady CSS polyfills to be enabled. This is done by evaluating scripts on the page context before the main navigation occurs, ensuring the environment is prepared for rendering web components.
// src/renderer.ts:93-95
page.evaluateOnNewDocument('customElements.forcePolyfill = true');
page.evaluateOnNewDocument('ShadyDOM = {force: true}');
page.evaluateOnNewDocument('ShadyCSS = {shimcssproperties: true}');
This proactive step is crucial for accurate serialization, as the networkidle0 state might be reached before web component polyfills have finished their work without this intervention.
Sources: src/renderer.ts:93-95, README.md:88-98, src/test/app-test.ts:63-68
Deprecated Explicit Render Signal
In versions prior to 2.0.0, Rendertron supported an explicit signal from the client-side code to indicate rendering completion. A page could set window.renderComplete = true to tell Rendertron it was ready to be serialized.
This feature was removed in version 2.0.0 in favor of the fully automatic networkidle0 approach.
Sources: CHANGELOG.md:14
A test for this functionality still exists in the codebase but is marked as failing, confirming its deprecation.
Sources: src/test/app-test.ts:152-156
The test resource explicit-render-event.html shows how this mechanism was intended to be used, with a script setting the window.renderComplete flag after an asynchronous operation.
<!-- test-resources/explicit-render-event.html:16-23 -->
<script>
window.renderComplete = false;
</script>
<script>
setTimeout(() => {
document.body.textContent = 'async loaded';
window.renderComplete = true;
}, 5000);
setTimeout(() => {
document.body.textContent = 'should not be reached';
}, 11000);
</script>
Sources: test-resources/explicit-render-event.html:16-23
Summary
Rendertron employs a robust, automatic page load detection strategy centered around Puppeteer's networkidle0 wait condition. This allows it to reliably handle modern, asynchronous web applications. The process is safeguarded by a configurable timeout and includes special handling for web components to ensure accurate rendering. The older, manual approach of using a window.renderComplete flag has been deprecated and is no longer supported.