Open lslzl3000 opened 2 years ago
Hello @lslzl3000. Please provide a minimal reproduction using a GitHub repository or v2.vuepress.vuejs.org/new. Issues marked with need reproduction
will be closed if they have no activity within 3 days.
It would be helpful if you could provide a reproduction repo.
@meteorlxy I have created a simple repo to test VitePress
and VuePress
https://github.com/lslzl3000/vuepressVSvitepress
It has about 1000
.md files, just simple doc generated from babylon.js
you can try build with VitePress
and VuePress
You will see how much longer the VuePress
will take
In my Macbook Pro 2022 with M2, VuePress: 13mins+
vs VitePress:60-70s
VuePress
also use much much more memory than VitePress
It has to build with NODE_OPTIONS=--max_old_space_size=20480
, otherwise node process will exit by JavaScript heap out of memory
If build with full VuePress
theme and other plugins, it will take more time
@meteorlxy any progress? closed by bot
This issue is marked as stale
because it has not had recent activity. Issues marked with stale
will be closed if they have no activity within 3 days.
This issue is marked as stale
because it has not had recent activity. Issues marked with stale
will be closed if they have no activity within 3 days.
I think we should add a new 'need review' label to stop issue like these closed by bot @meteorlxy
I started to be annoyed about this stale bot
Any update on this issue? 1500+ md files, build time 23min+: https://github.com/nushell/nushell.github.io/actions/runs/3036416348
这个问题能不能加急处理下?或者有没有其他什么替代方案?谢谢
I am focusing this issue these days.
Vitepress loads markdown files directly through a converter, and there is no global "Pages" scope (access other page infomation from one page), which means that vitepress directly luanch a app.
Meanwhile, vuepress have lifecyles, it's tranforming all markdown files to vue compoent and provides "pages data" to let plugins and theme proceed them, also, vuepress is registing all routes at start up and loads pages data with promises.
Besides the structure, one of the reasons which slows down vuepress ssr speed is that we are transforming almost every packages when generating ssr:
So that we will take more time to generate a ssr bundle before proceeing SSG. This is caused by pnpm support. But I do curious about why SSG speed is donzens times slower then vitepress, probably caused by taking much more memory with the "pages map full of promises" .
@lslzl3000 Would you please run another test with your repo after we migrate to ESM?
@meteorlxy I have a deeper dig in to our code, pageData only changes during router navigation, but SSG doesn't need those at all, so maybe it could be possible for us to stop loading the whole @internal/pageData
, and just load that page Data instead during SSG, I think that will probably reduce memory usage and speed up SSG. Loading all page data through promise when rending any page surely has negative effects during SSG
Hello, I'm looking for some solution as well. On my case I have around 2K posts and is impossible do a build, with 10GB on max_old_space_size
does not works.
Have someone more with this issue? We can try to fix and open the PR or is better go to VitePress?
I used to bring up the issue of VuePress scalability on its GitHub repository (https://github.com/vuejs/vuepress/issues/2689). In my project (https://github.com/openupm/openupm-next), I have around 3000 pages generated by a custom VuePress plugin's onInitialized
method. The API allows you to provide all pages through app.pages.push(page)
instead of using a generator that yields items individually. The intentional design of VuePress leads to keeping everything in memory. With each page consuming approximately 1 MB of memory (the estimation could be totally wrong), the total memory usage for 3000 pages amounts to about 3 GB, which may not sound excessive.
My project was initially built with VuePress v1, but I encountered some difficulties during a partial migration to VuePress v2 using --max_old_space_size=14000
. It's worth noting that a significant number of efforts have been made to address such issues in VuePress v2, which drives my curiosity about the bottleneck.
For illustration, let's consider @lslzl3000's repository (https://github.com/lslzl3000/vuepressVSvitepress), which contains 914 markdown files, each having an average file size of 22KB. Conducting a quick test yielded the following results:
Profiling 1: 914 pages | Peak Memory | Time |
---|---|---|
vuepress dev | 868 MB | 10s |
vitepress dev | 209 MB | Instantly |
vuepress build | 12.2 GB + swap | Out of memory during compiling with vite |
vitepress build | 5.9 GB | 1m59s |
A few additional notes:
htop
's RES
(resident size) column.--max_old_space_size=12000
.Let's double the page numbers by duplicating pages under the docs
folder.
Profiling 2: 1828 pages | Peak Memory | Time |
---|---|---|
vuepress dev | 1.3 GB | 20s |
vitepress dev | 209 MB | Instantly |
vuepress build | 12.2 GB + swap | Out of memory during compiling with vite |
vitepress build | 8.6 GB | 4m51s |
My major takeaways are two points:
Vuepress build costs much more memory than Vitepress. But it's comparing apples and oranges for different feature sets.
The memory usage of both Vuepress and Vitepress grows almost linearly with the number of pages. For vitepress, it costs 4.8 MB/page.
That is a bit counterintuitive - I assume the build time grows linearly with the number of pages, not the memory usage. The behavior is not friendly with large websites that rely on cloud-based build services (GitHub actions for example). We can suffer with more build time, but a large memory VM is usually very expensive or unnecessary for generating a static website with thousands of pages, think about a 10K page website that requires a 48 GB memory VM.
After reading https://github.com/vuepress/vuepress-next/issues/1262's proposal, it seems hard to improve:
@Mister-Hope:
During the build process, this cannot be done, webpack and vite all need to load and analyze all codes to pack the application, this means the more you put inside a project, the more codes they need to handle, so the compiling stage needs a linear space of memory comparing to content. These memory are taken by bundler, and it's not quite related to VuePress itselfs, unless we do not require a bundler to pack our spa anymore.
On the vite community it's also a hot topic: https://github.com/vitejs/vite/issues/2433, I'm processing it slowly and hopefully find some clues.
It seems a pitfall you're going hit when you grow to a larger scale, and the solution is not very obvious here.
Refs #994, #1262
I also conducted a quick test on @hustcer's repository (https://github.com/nushell/nushell.github.io), which comprises 676 markdown files, each with an average file size of 6 KB.
Here are the profiling results for the test:
Profile | Pages | Peak Memory | Time |
---|---|---|---|
vuepress build | 676 pages | 1.7 GB | 1m16s (with Git plugin on) |
The outcome is entirely acceptable. The primary distinction when compared with lslzl3000/vuepressVSvitepress is that the average markdown file size of nutshell.github.io is significantly smaller (22KB vs. 6 KB).
This implies that before delving into vite bundle options, the most immediate area to address is reducing the overall project size. While this approach may not be suitable for a purely markdown-based VuePress site, it might prove beneficial for some dynamically generated pages. One potential strategy could be deferring the loading of heavy data to runtime, such as fetching a JSON file from the public folder.
@favoyang Thanks for your investigation.
Some problems of performance IMO:
Transforming all md files to vue files and collect page data in prepare stage, and store page data in memory. This is what make our dev server start slowly and consume more memory. If we change to only transform md -> vue on demand when visiting the page, it would be much faster in dev. But the drawback is we'll lose our current auto sidebar functionality.
vue-router might be the killer of build. According to #1353, vue-router is too expensive for static site. That should be the reason why VitePress implements a custom lightweight router instead. If we change to use a lightweight router, it might be much faster in build.
SPA might not be the solution of static site, and that's why we have to bundle all files together and causing linear memory usage increase in build.
I've been wanting to try these things for a while, but don't have enough time. TBH it should be faster after those changes, but it would also make VuePress more like VitePress. Thus I also don't have much motivation to do so. 😞
I have put a lot of effort into this project, although it is not perfect. I am grateful to have you who are still using this project. ❤️
@meteorlxy, I truly appreciate your consistent assistance.
I am aware that the terms "performance" and "scalability" can have diverse meanings depending on the context. They may refer to:
In my previous comments, I addressed the first three aspects. Currently, my primary focus lies on the memory footprint, as it could potentially impede a smooth production build. By implementing the strategy of deferring the loading of heavy data to runtime and relocating large data from frontmatter to JSON files hosted at public/
, I have observed a significant reduction in the memory footprint. Essentially, the idea involves separating data and code once again, which might stand in contrast to the traditional Static Site Generation (SSG) approach.
To clarify my use case further, envision a blog containing an extensive number of pages. The idea is to fetch and render markdown format content at runtime, catering to a scenario where the number of pages is substantial.
Feedback on other ideas
Transforming all md files to vue files and collect page data in prepare stage, and store page data in memory. This is what make our dev server start slowly and consume more memory. If we change to only transform md -> vue on demand when visiting the page, it would be much faster in dev. But the drawback is we'll lose our current auto sidebar functionality.
If the auto sidebar is the sole feature that necessitates such extensive data processing, it could possibly be deferred for computation until later stages during runtime to exchange a better dev experience.
vue-router might be the killer of build. According to https://github.com/vuepress/vuepress-next/pull/1353, vue-router is too expensive for static site. That should be the reason why VitePress implements a custom lightweight router instead. If we change to use a lightweight router, it might be much faster in build.
I'm not entirely sure about the extent to which this optimization has contributed to the build time. Although conducting optimizations is crucial, it's essential to run a benchmark on a sample project and analyze the results to ensure that everyone has a clear understanding of the impact.
However, it seems the PR itself can also influence runtime performance, which could be a reasonable consideration.
SPA might not be the solution of static site, and that's why we have to bundle all files together and causing linear memory usage increase in build.
My initial intuition about Static Site Generation (SSG) is that common parts of the website, such as the core functionality and layout, are bundled together during the build process. These common parts typically form the main framework of the website and are known as the "static core."
On the other hand, the actual content and data of each page are treated as individual entities. These pages are analyzed and generated separately, resulting in specific JavaScript chunks for each page. These chunks are then loaded dynamically at runtime as needed.
The beauty of this approach is that, regardless of how large the project grows in terms of content and pages, the build memory footprint remains relatively constant and does not scale with the size of the website. The build time, too, scales linearly with the number of pages or content items, which makes it an efficient and scalable solution for generating static sites.
Perhaps my intuition is mistaken. That many details results in pushing all converted files to the vite compiler together - which drives more memory footprint scaled linearly with the number of pages.
Once again, thank you for your unwavering dedication and hard work. While I might not be familiar with the internal details of VuePress and VitePress, one advantage of being an independent project is the ability to mold it according to your vision and goals. Every framework possesses its own set of strengths and weaknesses, and it's not necessary for one to perfectly align with another in all aspects.
mark
Updates here, we have a new pr which avoids heavy cost on router.resolve
https://github.com/vuepress/vuepress-next/pull/1433
This would speed up build and webpaage performance, but little on memory cost.
Hello guys,
I was able to enhance the performance of my builds significantly with Vitepress after implementing a few improvements. Currently, my blog features around 2300 articles and is running smoothly on Netlify's free hosting platform 🎉.
If you're interested in giving it a try, take a look at my Vitepress repository clone. I've created a branch with a 'prepare' command in the package.json file to ensure compatibility for direct use in my projects. You can simply add the branch version directly to your package.json file for experimentation. However, please note that I don't plan to maintain this branch after the pull request is merged; it's intended for testing purposes only.
If you find this enhancement helpful or if it suits your needs, please consider leaving a like on my open pull request (PR) here to expedite the merge process. Your support would be greatly appreciated, and it can contribute to having these improvements in the upcoming versions.
Some updates:
Since v2.0.0-rc.3, we have replaced vue-router's original routes with lightweight custom routes to get better performance.
Some results from @Mister-Hope :
Case A: 4m41s → 1m28s Case B: 4m22s → 1m29s
For the case provided here
VuePress build time improved from 13min to 4min.
To answer the original question - the differences between VuePress and Vitepress - in short, the bottleneck is vue-router.
VuePress is a typical SPA project with vue-router. Imagine that if you build a project with thousands of pages, you would have to define all the routes - and it would be slow to build for sure.
In contrast, VitePress totally drops vue-router, so that we don't need to define all the routes. Instead, VitePress implemented a super light weight router with the help of vite.
Thus, for VuePress:
Description
Try to build with 1000 .md files Vuepress takes more than 10min to compile and render, in both vite-bundler and webpack-bundler
Meanwhile, VitePress@1.0.0-alpha.4 only takes 30s
The core part of build-bundler - Vite is the same, so the problem may be how VuePress processes or organises
.md
and.vue
. What is the difference between VitePress and VuePress during compiling & rendering?Used Package Manager
npm
System Info