Open ChristopherPHolder opened 1 month ago
The pink chunks are what we talking about:
The general chunk structure is pretty nice. But the more import('...')
entries you create, the more of these pink <2kb chunks appear
For us these micro chunks are created by: 1) Redux actions that are used at 2+ places. These chunks look like
import{Mb as e}from"./chunk-OMCORABT.js";var t=e("[Product] Clicked");export{t as a};
2) Or assets from { loader: { ".webp": "file" }
that are used at 2+ places. These chunks look like:
var l="./media/image-FZ7VCKMX.webp";export{l as a};
Would be awesome if esbuild could inline the file
loader string or via a minChunkSize
pull into the largest parent chunk.
Gzip and less http requests would make this more efficient. And you reduce the chance of running into the maximum allowed requests limit.
When code splitting,
esbuild
does not seem to take into account code that is already downloaded or cannot be loaded on its own.It seems important to distinguish between an application real entry points and its sub-entry points, as this has a direct impact on loading performance.
Lets say an application can only be accessed via main.ts, so it only has real "entry point", and then it has a bunch of lazy features "sub-entry points".
If the piece of shared code is consumed by main.ts, when the lazy feature imports it, the code is already there and it will be cached in some way. But in the case where there are many lazy features and many pieces of shared code that are consumed by main.ts it will split this into many little chunks.
Is there a benefit in splitting code that will necessary be imported in main.ts which will then also be imported in one of its lazy features?
These chunks seem unnecessary and are causing performance issues as to many chunks will increase load time can have a direct impact on user experience on
Core Web Vitals
.Is there a way to reduce these "unnecessary chunks"?
Ideally i would like that when building
esbuild
looks at the node tree graph and recognizes when the code should have already been loaded by a parent node and does not splitting into smaller chunk.Is there any way currently to reduce the number of chunks? Potentially with a plugin?
I have notice that by using bundles strategically i can reduce the number of chunks but this is not an ideal approach and it seems i am partially opting out of tree shaking.
I have tested this approach on a minimal angular application.
And created a minimal reproducible example using only esbuild, and typescript.
Minimal Preproduction
https://github.com/ChristopherPHolder/esbuild-code-splitting
The example is a minimal node cli with no dependencies only meant to illustrate this issue.
The CLI contains an execution file from where its meant to be accessed
app.js
. In theory it should not be accessed from anywhere else.It constrains 3 file which are
ui{1,2,3}.js
and are statically imported both inapp.js
and infeature{1,2,3}.js
which are in turn dynamically imported inapp.js
and nowhere else.Even tho, all
ui{1,2,3}.js
are statically imported inapp.js
which is the only real declared entry point, it will create a chunk for each of these 3 files.If we on add an index.js from where all
ui{1,2,3}.js
are imported then it will still chunk them as a separate file but it will only create 1 additional chunk.I am aware that this is currently expected behaviour as the docs states it pretty clearly:
However, i am looking for a solution to reduce the number of chunks, as this seems to be a large performance issue at the moment.