[Proposal] We should have mechanism to know that delayed.js is loaded (delay phase has started)
Problem statement: The delayed.js library is effective for loading third-party or deferred scripts, but if some block needs to handle things during delay phase, it requires importing block code in delayed.js, leading to code dispersion. For example, if a developer wants to utilize the Video.js library for adaptive streaming, it’s beneficial to render a poster image while deferring script loading to improve the LHS score.
Consider the following scenarios:
- The video block is not loaded in the page.
- The video block is loaded before delayed.js.
- The video block is loaded after delayed.js.
This necessitates writing logic within delayed.js to determine whether Video.js needs to be loaded, resulting in scattered code.
// video-block.js
export function loadVideoJs() {
// fetch scripts and render video
}
// delayed.js
if (document.querySelector('.video-js')) {
const { loadVideoJs } = await import("./blocks/video-block.js");
loadVideoJs()
}
While cases 1 and 2 can be managed with scattered code, case 3 poses a challenge. To handle case 3, we need some identifier to check if delayed.js is loaded since the script is not added to dom.
Proposal :
- set
DELAYED_PHASEproperty in window to handle case 3. - Trigger
delayed-phaseevent once delayed.js is loaded
e.g.
// video-block.js
export function loadVideoJs() {
// fetch scripts and render video
}
export decorate(block) {
if (window.DELAYED_PHASE) {
await loadVideoJs();
} else {
document.addEventListener('delayed-phase', loadVideoJs);
}
}
// delayed.js
document.dispatchEvent(new Event('delayed-phase'));
Window.DELAYED_PHASE = true;
Benefits :
- Colocated code for blocks which needs to handle things during delay phase
- Easier integration for shared blocks. No documentation is needed to use shared block which relies on delay phase
Customers using video block: Volvo Maruti suzuki
@rofe , @davidnuescheler , could you please share your thoughts on this ? Do you think it would be beneficial to have a mechanism to indicate delayed phase (via event + state variable) so that code dependent on delayed phase can be decoupled from delayed.js and be handled independently based on the state/ event,
I think this makes sense... but can easily be implemented at the project level (project owns delayed.js and the block code).
If we end up adding those lines to all projects (+/- event name, namespacing...), we will add them to the boilerplate.