Repository navigation
tech(core): load the formatjs Intl polyfill from a lazy module - #1644
Conversation
|
But this will not reduce the plone.staticresources package size issue described in #1640 right? |
|
I do not really understand the need of this "lazy loading" refactorings. I fact, I thought that's what module federation is made for -> to load resources only if they are needed ... or am I missing here something? /cc @thet |
|
The module federation machinery only makes sure that the same resource isn't loaded twice from different bundles. As a side effect it also enforces code splitting via the async import in the bundle entry point ( Loading only when it's needed is only done via async imports ( However, how this PR solves the issue isn't also clear to me. It looks like it's just async-importing another module where other async imports are done - the same async imports as before. But I'll give this another thought after I have finished my current thought on a different topic and had some lunch. 🤯 |
core/intl-loader.js dynamically imports `locale-data/${baseLang}.js` from
the ~766-file @formatjs/intl-datetimeformat/locale-data directory. Webpack
turns that into a context and emits one lazy chunk per file (~110 MB of
chunks plus ~220 MB of source maps), and the production build runs out
of the default Node heap. baseLang never carries a region or script
suffix, so the ~450 variant files were never requestable.
See #1640.
Constrain the context with webpackInclude to base-language files
(de.js, pt.js, ...). Regional variants still resolve through the polyfill's
own fallback (pt-BR -> pt, de-AT -> de), as they did before. The include is
matched against the absolute file path, so it must not be anchored at "./".
Move the polyfill-force import and the locale-data context into a separate
lazy intl-polyfill.js, loaded only after feature detection fails, so the
context map is not part of the pat-structure chunk.
Measured on a production build, 3587 -> 3145 chunk files, 767 -> 324
locale chunks, dist 380 MB -> 170 MB, bundle.min.js -13 KB (webpack's
runtime chunk-hash map shrinks with the chunk count).
c19c35e to
3b8878b
Compare
|
I updated the PR and the description. Still needs a bit of testing. |
|
I got help reviewing that. The extra async import here improves some webpack build artefact internals - there is a chunk lookup table and that is moved down to the chunk and so not initially polluting the bundle size. This is the conversation: Please look at the latest commit and explain why the changes make loading of the intl polyfill cheaper. It was an async lazy import before and is the same afterwards, AFAIK.
|
thet
left a comment
There was a problem hiding this comment.
LGTM!
Also I can reproduce the smaller bundle size - different chunk counts and sizes, but still a big improvement!
Fixes #1640.
core/intl-loader.jsdynamically importslocale-data/${baseLang}.jsfrom the ~766-file@formatjs/intl-datetimeformat/locale-datadirectory. Webpack turns that into a context and emits one lazy chunk per file: ~110 MB of chunks plus ~220 MB of source maps, and the production build runs out of the default Node heap.baseLangnever carries a region or script suffix, so the ~450 variant files (pt-BR.js,zh-Hans.js, ...) were never requestable. This PR:webpackIncludeto base-language files (de.js,pt.js, ...). Regional variants still resolve through the polyfill's own fallback (pt-BR→pt,de-AT→de), as before. Note: webpack matcheswebpackIncludeagainst the absolute file path, so the pattern is not anchored at./.intl-polyfill.js, loaded only after feature detection fails, so the context map is not part of the pat-structure chunk.Production build, before → after:
Re module federation (@petschki, @thet): MF only avoids loading a shared module twice. It does not change what webpack emits for a dynamic-import context, so the chunk count is only reduced by narrowing the context.