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
feat: implement multithreading for rendering and local search indexing, use JSDOM for better section split performance and reliability. #3386
base: main
Are you sure you want to change the base?
Conversation
modify log format, use dash instead of parenthesis
For discussions general parallelism, please go to #3183 |
@brc-dd Do you have time to look at this? |
Ah, I'm currently looking into other PRs. Will get back to you on this in few days. |
Sure, thanks! |
Latest perf: vitepress v1.0.0-rc.33
✓ building client + server bundles - 9.05 seconds
+ ✓ rendering pages - 25.24 seconds
✓ generating sitemap - 0.01 seconds
build complete in 34.5 seconds. This is more than 50% speedup compared to single thread (60.95s). I think this is good enough to be included as an experimental feature (not enabled by default). |
The bundle step vitepress/src/node/build/bundle.ts Lines 149 to 156 in 09e48db
vitepress/src/node/markdownToVue.ts Line 23 in 09e48db
|
Is there a repo I can use for test? My own project do not have heavy deps so I have no way to test it. |
One low hanging fruit could be running two builds in two workers. But I do not know if it would really help. |
Never mind, I found the cause: a global variable is used to pass around site config. Not exactly the cause of the problem above, I've done many other tricks to make vite happy in a worker thread. |
… bundle by default
@brc-dd I've reverted changes related to parallel bundling. Everything else is stable and ready for review. Regarding parallel bundling, I've tried several different approaches (as you can see in the commit history), but each of them has their own problems.
I've developed some tricks to get around the problems above, but those tricks are hacky and unstable. Also, forcing markdown renderer to stay in main thread will produce heavy RPC overhead, making it even slower than single thread. I think it's better to create another PR dedicated for parallel bundling, when there is actually someone complaining about bundling performance. |
BTW, local search indexing now only takes about 10 seconds for 1700 pages. It previously took 4.7 hours. |
This PR looks very promising. Any updates? |
Before
vitepress v1.0.0-rc.33 ✓ building client + server bundles - 9.43 seconds - ✓ rendering pages - 1 minute, 0.95 seconds ✓ generating sitemap - 0 seconds build complete in 1 minute, 10.56 seconds.
After
vitepress v1.0.0-rc.33 ✓ building client + server bundles - 9.4 seconds + ✓ rendering pages - 42.26 seconds ✓ generating sitemap - 0.01 seconds build complete in 51.85 seconds.
Challenges
In addition to vuetifyjs/vite-ssg@1f1663a, this PR also need to handle the problem of passing siteConfig to worker threads. This is very challenging because we cannot just import userConfig multiple times for each worker, since userConfig may have side-effects or internal state dependencies.
After some research, I found that there does not exist such a package for this unique challenge, therefore I created one (rpc-magic-proxy) for it. This utility will (1) serialize siteConfig into a pure static object so it can be sent through RPC channel, and (2) deserialize it on the worker side as a proxy. It will proxy all the function calls back to the main thread. With only one side effect being all the function calls have to be "awaited".
Thanks to the asynchronous coding paradigm that have already been taken in this project, I did not encounter any issue plugging this proxy into the render function.
One thing worth mentioning is that, due to the RPC proxy overhead, the speedup is not as significant as seen in #3374. But it still brought 30% speedup when building large sites, so it can be a nice-to-have option.
Comments and insights needed!
Please feel free comment on possible problems and/or ways to improve parallelism!