-
-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Consider treeshaking module for serving files in dev mode #8237
Comments
@AlexandreBonaventure thanks a lot for bringing this up here. I migrated our project to vite it took us almost 3 weeks fixing dependencies and errors but we hit this issue unfortunately. You mentioned changing imports for improving dev server performance can you please share a guide or docs link do we have it anywhere. Our project is open source - https://github.com/appsmithorg/appsmith/tree/release/app/client/src. And for a redux file save I see my browser sends about 1500 requests to the vite dev server, should I need to change any imports or restructure I can look into it. Thanks |
My team has also run into this issue on my project. Index files make logically grouping sections of your codebase much cleaner, but using them in import statements significantly effects the startup speed of vite, as things stand now. Also, it's worth pointing out that this could also have significant positive impacts on vite-based tools, such as Vitest, and playwright's new experimental component testing setup. |
Running into this issue as well. 700 files and can take 10+ seconds for a HMR. I followed https://carljin.com/vite-resolve-request-files-a-ton.html which didn't help much for my use case. |
My team hit this issue as well in our migration from Webpack to Vite. It wasn't obvious initially as we were starting with small chunks of code pertaining to only 1 React app, but as we added more React apps and corresponding entrypoints (we have a multi-page app setup) the issue surfaced, causing a page not to load in local development mode. We were scratching our heads for a bit trying to figure it out because the error was coming from a module way down in the dependency tree for another module tied to a route that we weren't viewing/loading. We looked through the network requests and started swapping out import statements, which resolved the issue. I wasn't able to find anything in the docs about using |
Resolved it in a similar way, Vite seems to take a different approach than webpack (which is apparently better). So I had to change a ton of imports and it got better. |
has a good way to solve this problem now? |
I've came across a similar issue with my team while working on our company's software overhaul. Just for the record, we're using Storybook to document all kinds of things, from components to data strategies. We've came up with a lot of custom components to make our documentation even more interactive and impactful. All these components are made available and imported through an index file. Now, whenever we'd import any component from that entry file - in development mode - it would initiate browser requests to load all files imported by this entry file. This makes some pages really slow to (re)load since they would load a whole bunch of files even though it only actively consumes a very specific piece of code. Given the lack of actual solution on Vite side, I've ended up writing a simple Vite plugin which mimics tree-shaking when importing code from entry files. This appears to work pretty well with our codebase as the number or browser requests drastically decreased (since we've adopted it). I thought it could maybe help some of you guys out there, so i've tried to make it a public package. This is still very experimental and I can't tell for sure this will suit your needs, but I would love to see it being field-tested and get any feedback. |
@Dschungelabenteuer Does this only work for entry files? Could it be adapted to work for |
When I added a simple icon import, every page load/navigation started taking 30-60s and build times also increased by about 20s. Would be nice to see this prioritized |
@ryan-mcginty-alation I am so sorry I've just noticed your message, could you be a bit more explicit about what you're trying to achieve here ? Please feel free to open an issue on that repo, I'll be happy to answer :-) |
We experience the same beahior on our project as well. |
My team is starting a React + Vite project right now and I would love some info or traction on this issue before we get too deep into the project. If the simple solution is "just use webpack" then I'd rather do that now than get months into this project with Vite and have to refactor a lot. |
It's just about the way you handle imports. don't use barrel files and you may be good. the problem gets worse if you use monorepos and import many files. |
Which is the best/preferred method then?
Or should I just directly import in each file like below:
|
If there's a lot of imported files in the different index files of your application, it might cause slow down in development. The current project I'm working on, while migrating from webpack to vite, we had to change a lot of imports to from one import statement to multiple one, because our shared module had too many import statements which caused network bottleneck each time we reloaded the page. By changing the imports we've manage to make our vite setup fast. To do the migration, we've build a couple of codemods using https://github.com/facebook/jscodeshift. |
Back in the day we use things like |
Maybe it is getting batter after all vercel/next.js#54572 🤞 |
We've started to experience same thing in our project for development environment when we removed multiple entry points and kept only one (to keep production bundle in check). Previously, we had multiple entry points which didn't load all the modules (more than 1000) but only required ones. Although, it made production build to generate lot of chunks. |
Any updates on this issue? |
Facing the same issue here, did anyone find any solution for this? |
Anyone is actually using vite HMR in a large project with fetching hundreds of files? I tried warmup but it doesn't help reduce files need to fetch on load. |
I would like to push for a build-in option here as well. My use case are "Cypress Component Tests", which runs using the Vite dev server. Since all test files are loaded in isolation the whole dependency tree of a tested component is being loaded. Without tree-shaking this can quickly result in downloading too many files were all requests are also intercepted by Cypress itself. This can slow down all tests significantly. |
Couldn't we do it only when Given that transforming is the bottleneck, I'd expect this would still help as it would greatly reduce the number of files to transform. |
I don't think the issue is within libraries (which we do support sideEffects today) as we already prebundle libraries. I think the bottleneck reported so far is in large codebases and source code where barrel files are used often. We currently don't support Plus even with side-effects configured, there's extra work needed to decipher what // barrel.js
export * from './a'
export * from './b'
export * from './c' Each file would need to be loaded and transformed anyways. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I understand that the following barrel file is difficult to transform: export * from './path-1';
export * from './path-2'; But why are barrel files with named exports slow? Can't Vite see exactly where the import is coming from? export { thingy, thing } from './path-1';
export { something, somethingy } from './path-2'; |
It's because of side-effects as well (#8237 (comment)). That plus the |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I hijack your reply to share my two cents in general of best practise for treeshaking. I really dont encourage to explicitly import certain functions. It drops the benefit of the namespace concept. // How would I know, `map(...)` function belongs to lodash
import { map } from 'lodash-es'
// It's more straightfoward, that I'm using lodash, when I call `_.map(...)`
import * as _ from 'lodash-es' Maybe cherry-picking of used functions is a doable solution for now, but I would rather importing/exporting everything and let build tool to find a way to keep the used functions. If a human being can do, so can a build tool. (maybe some GPT4 based build tool can breakthrougth in the near future) |
Man I can't wait for this to work :). For now we decided to remove all the barrel files from our small project. |
facing same issue |
If you're here because barrel files make the dev server very slow, and you've basically wanted something like
Hope this helps some of you. Feel free to post issues on the repo or contribute. |
I think it can be at times. E.g. consider some of the Svelte icon libraries we've seen with thousands of
The
That may be true currently. Though I imagine we could add something that works like the scanning from dependency prebundling that just quickly looks for imports and builds a graph of the project. That may be easier in a rolldown world where we can more easily share code between prebundling and building. |
Unfortunately, sometimes the recommendation to avoid using Barrel Files cannot be fulfilled. We have a layered architecture with static DI. // di.mts
...
export let useCases: UseCases; // <== link to Barrel File
export function initUIUseCases(uc: UseCases) {
useCases = uc;
}
... the application initializes it with a real link at startup // app.mts
import useCases from '../use-cases/index.mts'; // <== Barrel File
import { initUIUseCases } from '../ui/di.mts';
initUIUseCases(useCases);
... and then it's used in container as import { useCases } from '../ui/di.mts';
function Container() {
const data = useCases.useUCase1();
return { ...}
}
export default UserContainer; It seems to me that a possible solution could be a hint to vite which dependencies in the form of Barrel Files should be preprocessed to resolve real modules or developer can prepare a module which resolves the dependencies for dev server and internally the resolving result should be
|
@Idonoghue did you manage to get this working with import alias? |
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:
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:
Currently Vite delivers
/shared/index.ts
as is and the browser will loadc
module even though we're not using it. Ifc
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:I have created a small stackblitz to highlight the current Vite behaviour:
![image](https://user-images.githubusercontent.com/4596409/169301671-4f98de2c-a901-424d-9473-2cea3ce20572.png)
https://stackblitz.com/edit/vitejs-vite-cjqcd4?file=src/App.vue
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
The text was updated successfully, but these errors were encountered: