core: [Bug report] Compiling & rendering too too too much slower than VitePress
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
System:
OS: macOS 12.4
CPU: (8) arm64 Apple M2
Memory: 6.52 GB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.15.1 - /usr/local/bin/node
Yarn: Not Found
npm: 8.11.0 - /usr/local/bin/npm
Utilities:
Git: 2.32.1 - /usr/bin/git
Browsers:
Chrome: 103.0.5060.134
Edge: Not Found
Firefox: Not Found
Safari: 15.5
npmPackages:
System:
OS: macOS 12.4
CPU: (8) arm64 Apple M2
Memory: 6.52 GB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.15.1 - /usr/local/bin/node
Yarn: Not Found
npm: 8.11.0 - /usr/local/bin/npm
Utilities:
Git: 2.32.1 - /usr/bin/git
Browsers:
Chrome: 103.0.5060.134
Edge: Not Found
Firefox: Not Found
Safari: 15.5
npmPackages:
@vuepress/bundler-vite: ^2.0.0-beta.49 => 2.0.0-beta.49
@vuepress/bundler-webpack: ^2.0.0-beta.49 => 2.0.0-beta.49
@vuepress/cli: 2.0.0-beta.49
@vuepress/client: 2.0.0-beta.49
@vuepress/core: 2.0.0-beta.49
@vuepress/markdown: 2.0.0-beta.49
@vuepress/plugin-active-header-links: 2.0.0-beta.49
@vuepress/plugin-back-to-top: 2.0.0-beta.49
@vuepress/plugin-container: 2.0.0-beta.49
@vuepress/plugin-docsearch: ^2.0.0-beta.49 => 2.0.0-beta.49
@vuepress/plugin-external-link-icon: 2.0.0-beta.49
@vuepress/plugin-git: 2.0.0-beta.49
@vuepress/plugin-google-analytics: ^2.0.0-beta.49 => 2.0.0-beta.49
@vuepress/plugin-medium-zoom: 2.0.0-beta.49
@vuepress/plugin-nprogress: 2.0.0-beta.49
@vuepress/plugin-palette: 2.0.0-beta.49
@vuepress/plugin-prismjs: 2.0.0-beta.49
@vuepress/plugin-pwa: Not Found
@vuepress/plugin-pwa-popup: Not Found
@vuepress/plugin-register-components: ^2.0.0-beta.49 => 2.0.0-beta.49
@vuepress/plugin-search: Not Found
@vuepress/plugin-shiki: ^2.0.0-beta.49 => 2.0.0-beta.49
@vuepress/plugin-theme-data: 2.0.0-beta.49
@vuepress/plugin-toc: Not Found
@vuepress/shared: 2.0.0-beta.49
@vuepress/theme-default: 2.0.0-beta.49
@vuepress/utils: 2.0.0-beta.49
vue: 3.2.37
vue-loader: 17.0.0
vue-router: 4.0.16
vuepress: ^2.0.0-beta.49 => 2.0.0-beta.49
vuepress-vite: 2.0.0-beta.49
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 2
- Comments: 21 (8 by maintainers)
@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 SSGI 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
onInitializedmethod. The API allows you to provide all pages throughapp.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:
compiling with viteA few additional notes:
htop’sRES(resident size) column.--max_old_space_size=12000.Let’s double the page numbers by duplicating pages under the
docsfolder.compiling with viteMy 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:
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
Updates here, we have a new pr which avoids heavy cost on
router.resolvehttps://github.com/vuepress/vuepress-next/pull/1433
This would speed up build and webpaage performance, but little on memory cost.
@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. ❤️
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:
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.
@meteorlxy I have created a simple repo to test
VitePressandVuePresshttps://github.com/lslzl3000/vuepressVSvitepressIt has about
1000.md files, just simple doc generated frombabylon.jsyou can try build withVitePressandVuePressYou will see how much longer the
VuePresswill takeIn my Macbook Pro 2022 with M2,
VuePress: 13mins+vsVitePress:60-70sVuePressalso use much much more memory thanVitePressIt has to build withNODE_OPTIONS=--max_old_space_size=20480, otherwise node process will exit by JavaScript heap out of memoryIf build with full
VuePresstheme and other plugins, it will take more time