-
Notifications
You must be signed in to change notification settings - Fork 4.7k
iAPI: Fix and refactor runtime initialization logic #71123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Conversation
|
I've been testing different implementations here for As an example, these are the logs obtained for the And these are for the implementation using One interesting conclusion from these results is that, in Safari, the |
|
Another interesting finding is that we should avoid using top-level awaits in our code. When a module statically imports another module using a top-level Let's consider the init code that delays the hydration. Imagine we await // Defer hydration to the end of the task queue.
await postTask( hydrateRegions );All |
|
After further investigation, we have concluded that the only method to ensure that all script modules included in the HTML have been executed is to use const [navigation] = performance.getEntriesByType('navigation');
if (navigation.domContentLoadedEventStart > 0) {
// DOMContentLoaded has started or already completed
init();
} else {
document.addEventListener('DOMContentLoaded', init);
}Browser support aligns with import maps, so we're good there. Regarding top-level await: Our testing showed that Safari < 26 treats modules with top-level await as async. They can complete after DOMContentLoaded, breaking this guarantee. Since there is no known pattern using top-level await right now, we can document this as a known limitation for now. Anyway, we should also work on initializing |
6cb3949 to
81e9b19
Compare
|
Size Change: +49 B (0%) Total Size: 3.06 MB
ℹ️ View Unchanged
|
|
@luisherranz, I've updated this PR to use the approach you mentioned in #71123 (comment). I've added some e2e tests as well to ensure the race condition mentioned in #74184 (comment) is solved.
Should we address that in a new PR? I can open an issue to keep track of this. |
| initialVdom, | ||
| hydrateRegions, | ||
| getRegionRootFragment, | ||
| } from './hydration'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed init.js to hydration.js to further clarify this file's purpose. The same goes for the init function, now renamed to hydrateRegions. Let me know what you think about these changes.
|
|
||
| // Parses and populates the initial state and config. All the core directives | ||
| // are registered at this point as well. | ||
| populateServerData( parseServerData() ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the state and config initialization here so that index.js is the only file that calls functions.
I wanted to mention this somewhere in the documentation, although I'm unsure where to do so. 🤔 |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
What?
Closes #70870 and #74184.
Revisits the initialization logic to clarify all steps and when they run. Also, fixes a race condition during the iAPI initialization, causing a bug in the Image block.
For now, this PR serves more as an exploration to discuss possible implementations.
Why?
See #70870 for the initial motivation.
See #74184 for the Image block bug.
How?
Basically, the code changes are as follows:
index.ts. There is no longer any initialization of isolated parts in internal modules, as was the case with the initial state and config.init.tsfile has been renamedhydration.ts, as it only involves the hydration part. Theinit()function is now calledhydrateRegions().isDOMReadyhas been implemented. This function relies on domContentLoadedEventStart to detect whether theDOMContentLoadedevent has been dispatched. If not, it registers an event listener for that event, ensuring that all sync modules statically importing@wordpress/interactivityhave been evaluated before hydration, preventing errors from missing state, actions, or callbacks. If dispatched, hydration is guaranteed; however, missing properties at hydration time may cause directives such asdata-wp-initto fail.Testing Instructions