Chunk-based Treeshaking for Tailwind? #14028
sphinxrave
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I have an idea about how we can accomplish chunk-specific css file for treeshaking tailwind. But I don't really know enough about postcss, build lifecycle, or very technical with JS build processes, so I don't think I'll lead this on, but would appreciate others picking through this idea.
Goal: render a custom chunk_[hash].css for each chunk of generated javascript.
Benefits:
We can build component libraries out of tailwind since only imported components would be in the chunks.
We can slim down the initial css delivery, but the trade off is the total cumulative css size is greater than before.
Let C be the set of all chunks in the project.
Let S be the set of all possible Tailwind selectors.
For each chunk
c ∈ C
, defineSet_c ⊆ S
as the set of Tailwind selectors used in chunkc
. We can probably get this by statically analyzing the chunk c's source, which tailwind is already good at.Let
G = (C, E)
be the dependency graph, whereE
is the set of edges representing dependencies between chunks.Define a function
Ancestors(c)
that returns the set of all ancestor chunks of c in G.Define a function
Entrypoints(c)
that returns the set of all entry points that can reach chunk c in G.Now we can formalize this algorithm for deciding which selectors go into which chunk:
For each chunk c, we can define the set of selectors needed by the chunk:
Needed(c) = Set_c
We can define the set of selectors already provided by all possible import paths:
Provided(c) = ⋃{Set_a | a ∈ Ancestors(c)}
The set of selectors that need to be included in the chunk's CSS file is:
Include(c) = Needed(c) \ Provided(c)
To optimize further, we can define the set of selectors that are guaranteed to be provided by all entry points:
GuaranteedProvided(c) = ⋂{Provided(e) | e ∈ Entrypoints(c)}
The final set of selectors to be included in the chunk's CSS file is:
FinalInclude(c) = Include(c) \ GuaranteedProvided(c)
Lastly, for optimization, we can try to hoist tiny chunks <4 (or x) kb into entrypoints to save network round-trips, or, if a selector is defined in more than
k
descendants, we can hoist that selector into a shared ancestor to prevent deduplication but increasing initial css delivery.Beta Was this translation helpful? Give feedback.
All reactions