Skip to content

Consider treeshaking module for serving files in dev mode #8237

Open
@AlexandreBonaventure

Description

@AlexandreBonaventure

Clear and concise description of the problem

Hello!
Lately as our codebase has grown bigger and bigger over the last months we've been experiencing slow page reloading using Vite.
That is not surprising given that our module size went off the chart, but it really is becoming a real pain point for us.
I hear that we are not alone in this case, reading through some related issues:
#8232
and I totally agree with what @patak-dev says here:
#7608 (comment)

The thing is, HMR has some reliability issues in our large codebase (where sometimes patching generates some issues) and these issues are very hard to debug, and creating a minimal reproduction is a huge amount of energy (for potentially no results)
I failed to follow up on that ticket as well: #3719


With all that said, we are guilty of doing something that really does not help:
we often import shared code with an index file because it is handy:

// /shared/index.ts
export { a } from './a'
export { b } from './b'
export { c } from './c'
// Component.vue
import { a, b } from '/shared'

// instead of 
import a from '/shared/a'
import b  from '/shared/b'

Of course, I already hear people say: 'Duh! just don't do this and import every single module individually you lazy dumbass'
I would answer: easier said than done when your codebase is a big monorepo and you share hundreds of compositions/components/libraries/helpers....
We obviously see that this is way forward if we want to address our pain points with slow reloads.

END OF CONTEXT----

Suggested solution

Like I said above, we have clear directions for improving the perf of our app in development but this whole issue got me thinking about the module loading strategy of Vite's dev server, and I wanted to start a discussion about considering to support treeshaking for module delivering because I think it could potentially help others.

Let's take the example above:

// /shared/index.ts
export { a } from './a'
export { b } from './b'
export { c } from './c'
// Component.vue
import { a, b } from '/shared'

// instead of 
import a from '/shared/a'
import b  from '/shared/b'

Currently Vite delivers /shared/index.ts as is and the browser will load c module even though we're not using it. If c has some other dependencies, browser will load them as well, etc.. You end up loading a whole module dep branch that we're not even using.
In my wildest dreams, Vite could transform Component.vue as such:

// Component.vue
import { a, b } from '/shared?dep=a,b'
// /shared/index.ts?dep=a,b
export { a } from './a'
export { b } from './b'
// c module is ruled out

I have created a small stackblitz to highlight the current Vite behaviour:
https://stackblitz.com/edit/vitejs-vite-cjqcd4?file=src/App.vue
image

Did you guys ever consider it ? Am I out of my mind ?

Basically my thought is: if Vite was "smart" enough to treeshake module for creating the dep tree, we would not have the need to refactor at all, and potentially it could speed up the app loading for a lot of users.

I most likely have a naive conception of how the whole thing works and I don't how much is feasible on that front but I wanted to kickstart discussion nonetheless. There are probably a lot of different requirements regarding side-effects etc.. and I understand it is potentially a huge Pandora's box...

Alternative

No response

Additional context

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestp4-importantViolate documented behavior or significantly improves performance (priority)performancePerformance related enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions