Skip to content
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

Docusaurus Faster #10556

Open
slorber opened this issue Oct 4, 2024 · 34 comments
Open

Docusaurus Faster #10556

slorber opened this issue Oct 4, 2024 · 34 comments
Labels
proposal This issue is a proposal, usually non-trivial change

Comments

@slorber
Copy link
Collaborator

slorber commented Oct 4, 2024

Docusaurus v3.6 is out with the Docusaurus Faster options 🥳 🎉

https://docusaurus.io/blog/releases/3.6

Docusaurus Faster

This is a meta-issue for the Docusaurus Faster project.

The goal is to modernize our infrastructure and greatly reduce the time and memory it takes to build a Docusaurus site in production mode, to fix this long-standing issue #4765.

yarn add @docusaurus faster

Before using these flags, you will need to add an extra package encapsulating all the opt-in dependencies:

It includes multiple experimental PRs adding new siteConfig.future.experimental_faster options:

const config = {
  future: {
    experimental_faster: {
      optionName: true
    },
  },
}

We recommend turning them on all at once with a simple boolean shortcut. We also recommend turning future.v4 feature flag on, because some Docusaurus Faster options rely on upcoming changes.

const config = {
  future: {
    v4: true, // opt-in for Docusaurus v4 planned changes
    experimental_faster: true, // turns Docusaurus Faster on globally
  },
}

But you can also turn them on/off one by one to troubleshoot potential problems.

Note that the rspackBundler option requires swcJsLoader, swcJsMinimizer, and lightningCssMinimizer to be enabled first.

It is possible that certain combinations of options do not work, and our CI doesn't cover all possible permutations (only true / false).

It also includes notable memory improvements:

What to expect

With experimental_faster: true, our Docusaurus website builds:

Although rebuilds (with warm ./node_modules/.cache) are not faster (yet), we recommend you enable the experimental_faster: true option to future-proof your site against our new dependencies and report us potential problems you encounter.

Our core plugins/themes are all compatible with this new option, and we expect most community plugins to be compatible out-of-the-box. Some plugins might need minor adjustments to make them compatible with Rspack, and we'll help the community to make our ecosystem compatible with Rspack.

This option is relatively safe to use in production: we have deployed our own website with it already:

  • If your Docusaurus site is standard, it should be fine out of the box
  • If your Docusaurus site is more complex, make sure to test it thoroughly and give us feedback

For Docusaurus plugins authors

Some plugins implementing the configureWebpack() lifecycle hook might need to adjust their code to add support for Rspack.

I will write a guide for them in this sister issue: #10572

Upgrade PRs

Example upgrade PRs to look at, including some benchmarks.

Community websites:

Popular plugins:

Contributing to this issue

We want our community to share feedback on this Docusaurus Faster project.

Please try to adopt it as part of the v3.6+ / canary releases, and tell us how it works for you.

If you encounter problems, please let us know here, and we might create dedicated issues if needed.

This general issue is a great place to follow the Docusaurus Faster project overall, as we try to stabilize it and aim to make it the default for an upcoming major version.

@sserrata
Copy link
Contributor

sserrata commented Oct 9, 2024

Thanks @slorber, sharing comparison results for our OpenAPI plugin site.

Cold Build No Optimization

[PERF] Build > en > Bundling with webpack - 41.58 seconds!
[PERF] Build > en > SSG > Load App renderer > Load server bundle - 8.49 ms
[PERF] Build > en > SSG > Load App renderer > Server bundle size = 17.241 MB
[PERF] Build > en > SSG > Load App renderer > Evaluate server bundle - 225.13 ms
[PERF] Build > en > SSG > Load App renderer - 234.15 ms
[PERF] Build > en > SSG > Generate static files - 3.26 seconds!
[PERF] Build > en > SSG - 3.50 seconds!
[PERF] Build > en > postBuild() - 10.58 ms
[PERF] Build > en > Broken links checker - 28.01 ms
[SUCCESS] Generated static files in "build".
[PERF] Build > en - 46.38 seconds!
[PERF] Build - 46.38 seconds!
[INFO] Use `npm run serve` command to test your build locally.
✨  Done in 51.97s.

Cold Build With Experimental Faster Enabled

[PERF] Build > en > Bundling with webpack - 23.44 seconds!
[PERF] Build > en > SSG > Load App renderer > Load server bundle - 7.16 ms
[PERF] Build > en > SSG > Load App renderer > Server bundle size = 17.767 MB
[PERF] Build > en > SSG > Load App renderer > Evaluate server bundle - 222.76 ms
[PERF] Build > en > SSG > Load App renderer - 230.31 ms
[PERF] Build > en > SSG > Generate static files - 1.82 seconds!
[PERF] Build > en > SSG - 2.06 seconds!
[PERF] Build > en > postBuild() - 9.49 ms
[PERF] Build > en > Broken links checker - 27.01 ms
[SUCCESS] Generated static files in "build".
[PERF] Build > en - 26.79 seconds!
[PERF] Build - 26.79 seconds!
[INFO] Use `npm run serve` command to test your build locally.
✨  Done in 32.52s.

Edit from @slorber: results above are still based on Webpack.

See PaloAltoNetworks/docusaurus-openapi-docs#1003 for the real upgrade.

Benchmark shows demo site building:

  • 2.7x faster on cold builds
  • 1.2x slower (for now) on warn builds

@slorber

This comment was marked as outdated.

@slorber
Copy link
Collaborator Author

slorber commented Oct 11, 2024

The Rspack support has been merged: #10402

You can try canary 0.0.0-6101 or above to benefit from all the upcoming perf improvements.

Here's an example PR upgrading the React Native website: facebook/react-native-website#4268

How to benchmark

One way to benchmark this is to use hyperfine with an env variable:

const config = {
  future: {
    experimental_faster: (process.env.DOCUSAURUS_FASTER ?? 'true') === 'true',
  },
}

For cold builds:

hyperfine --prepare 'yarn clear' --runs 5 'DOCUSAURUS_FASTER=false yarn build' 'DOCUSAURUS_FASTER=true yarn build'

For warm rebuilds:

DOCUSAURUS_FASTER=false yarn build
hyperfine --runs 5 'DOCUSAURUS_FASTER=false yarn build' 'DOCUSAURUS_FASTER=true yarn build'

Troubleshooting slow builds

It's possible that enabling this new option does not give you the expected speed increase.

Perf logger

You can get a more verbose performance logger with the DOCUSAURUS_PERF_LOGGER=true env variable, giving you the time it takes to execute each step:

image

Rsdoctor

Another option is to use Rsdoctor, which works for both webpack and Rspack.

It can tell you which loader/plugin/phase is slow while bundling your app.

For many Docusaurus sites (including ours), the slow loaders are postcss/css-loader, mdx loader, and the image loaders of our ideal image plugin. Despite these slow loaders, Docusaurus Faster builds 3x faster.

It is possible that a Docusaurus plugin you use slows down your build. Rsdoctor might be able to give you insight on that.

We'll probably release an official Rsdoctor plugin for Docusaurus, but in the meantime here's a Docusaurus plugin we built to integrate it into our own site: https://github.com/facebook/docusaurus/blob/main/website/src/plugins/rsdoctor/RsdoctorPlugin.ts

@o-l-a-v
Copy link

o-l-a-v commented Oct 22, 2024

Tested with a relatively large internal documentation site.

PS > Get-ChildItem -File -Recurse | Group-Object -Property 'Extension' | Sort-Object -Property 'Count' -Descending | Format-Table -Property 'Count', 'Name'

Count Name
----- ----
  748 .md
  553 .png
   71 .jpg
   24 .json
   10 .webp
    8 .svg
    5 .order
    4 .py
    3 .drawio
    3 .html
    3 .pdf
    2 .mdx
    2 .xml
    1 .xlsx
    1
    1 .avif
    1 .zip

PS >

Locally, Windows, Yarn v4.5.1, NodeJS v20.18.0. Used following command in PowerShell for timing the build:

yarn docusaurus clear; $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew(); yarn build; $Stopwatch.Stop(); $Stopwatch.Elapsed.ToString()
  • 3.5.2: 00:02:32.9615610
  • Canary with experimental_faster: true: 00:01:10.1179920

We're pretty stoked on that speedup. 😊

@sedghi
Copy link

sedghi commented Oct 28, 2024

which version of docusaurus comes with this experimental config? since i can't get it to run in 3.5.2

[ERROR] Error: These field(s) ("future.experimental_faster",) are not recognized in docusaurus.config.js.
If you still want these fields to be in your configuration, put them in the "customFields" field.
See https://docusaurus.io/docs/api/docusaurus-config/#customfields
    at validateConfig (/Users/alireza/dev/admin/cornerstone3D.git.worktrees/beta/node_modules/@docusaurus/core/lib/server/configValidation.js:299:15)
    at loadSiteConfig (/Users/alireza/dev/admin/cornerstone3D.git.worktrees/beta/node_modules/@docusaurus/core/lib/server/config.js:39:62)
    at async Promise.all (index 1)
    at async loadContext (/Users/alireza/dev/admin/cornerstone3D.git.worktrees/beta/node_modules/@docusaurus/core/lib/server/site.js:37:97)
    at async loadSite (/Users/alireza/dev/admin/cornerstone3D.git.worktrees/beta/node_modules/@docusaurus/core/lib/server/site.js:136:21)
    at async createReloadableSite (/Users/alireza/dev/admin/cornerstone3D.git.worktrees/beta/node_modules/@docusaurus/core/lib/commands/start/utils.js:50:16)
    at async Command.start (/Users/alireza/dev/admin/cornerstone3D.git.worktrees/beta/node_modules/@docusaurus/core/lib/commands/start/start.js:22:28)
[INFO] Docusaurus version: 3.5.2

@sedghi
Copy link

sedghi commented Oct 28, 2024

Answering myself, it is 3.5.2-canary-6125, I'll update the speed benchmarks soon

I'm seeing

  • dev: 15 seconds -> 2 seconds
  • build: +3 mins before giving any error (I'm upgrading to 3.x from 2.x) to 10 seconds with relevant mdx erros

Nice job

Update: build is down from +3 minutes to 30 seconds

f2c-ci-robot bot pushed a commit to halo-dev/docs that referenced this issue Oct 31, 2024
Support for building projects via rspack has been added in the latest Canary version of Docusaurus, which significantly improves compilation speed. 

```bash
❯ hyperfine --prepare 'pnpm clear' --runs 5 'DOCUSAURUS_FASTER=false pnpm build' 'DOCUSAURUS_FASTER=true pnpm build'
Benchmark 1: DOCUSAURUS_FASTER=false pnpm build
  Time (mean ± σ):     70.715 s ± 17.150 s    [User: 134.096 s, System: 31.651 s]
  Range (min … max):   52.330 s … 88.497 s    5 runs

Benchmark 2: DOCUSAURUS_FASTER=true pnpm build
  Time (mean ± σ):     30.094 s ±  4.572 s    [User: 64.061 s, System: 28.384 s]
  Range (min … max):   25.832 s … 37.655 s    5 runs

Summary
  DOCUSAURUS_FASTER=true pnpm build ran
    2.35 ± 0.67 times faster than DOCUSAURUS_FASTER=false pnpm build
```

see: facebook/docusaurus#10556 (comment)

```release-note
None 
```
@ld-web
Copy link

ld-web commented Nov 12, 2024

Thanks a lot @slorber, I upgraded today on a Docusaurus website with around 60 Markdown files including Mermaid charts, in Github Actions pipeline it went from average 1m30 build time to 12s ! Impressive ! 💯

@mike-solomon
Copy link

To add to the list of wins - with faster enabled on one of my sites with 4651 markdown files, the build job went from taking up to 15 minutes to build down to only ~7.5 minutes 🥳 . Thanks so much for the effort y'all put into optimizing this.

@felipecrs
Copy link
Contributor

felipecrs commented Nov 18, 2024

The build from an internal website here went from 4m18s to 1m8s. A great deal, thank you very much!

@jdussouillez
Copy link

Migrated a small doc today very easily, no problem.

Build time went from 1m29s to 0m14s! 🚀 Thanks!

@ShangjinTang
Copy link

ShangjinTang commented Nov 23, 2024

Incredible and impressive improvement.

Tested at same environment on same machine with clean build command hyperfine "rm -rf build && yarn build":

  • Docusaurus 3.5.2:

    Time (mean ± σ):     98.320 s ± 13.658 s
    Range (min … max):   87.976 s … 113.801 s
    
  • Docusaurus 3.6.3 with config future: { experimental_faster: true, }:

    Time (mean ± σ):     19.712 s ±  1.784 s
    Range (min … max):   18.664 s … 21.772 s
    

Took only 20% (19.712s / 98.320s) build time compared to previous version.

@karl-cardenas-coding
Copy link

Our Spectro Cloud documentation build time went from 1 hour and 15 minutes to 35 min 🎉

For context, our builds run on a self-hosted GitHub runner with 8 CPU 16 GB Memory and 150 GB SSD.

@jackw
Copy link

jackw commented Dec 18, 2024

Our Grafana plugin-tools docs builds times went from 36s to 11s build time. Every little helps!

Really appreciate the efforts everyone made here. 👏👏👏

@slorber
Copy link
Collaborator Author

slorber commented Dec 20, 2024

Important security notice for Docusaurus Faster users

Version 1.1.7 of @rspack/core has been compromised with a malicious npm publish.

More info here:
https://github.com/web-infra-dev/rspack/releases/tag/v1.1.8

The 1.1.7 version was published yesterday. The Rspack team reacted quickly to deprecate it and publish a safe 1.1.8 version within 1h after the 1.1.7 malicious publish.

@rspack/core is installed as part of @docusaurus/faster.

If you are unlucky and installed it yesterday during that 1h period, you may have installed that compromised Rspack version. This may also happen when upgrading dependencies or re-generating your package manager lock file.

You can check the @rspack/core version your site is using with package manager commands:

  • npm why @rspack/core
  • yarn why @rspack/core

Alternatively, you can look at node_modules/@rspack/core/package.json for the version field.

If your Docusaurus site is using Rspack v1.1.7, make sure to upgrade to v1.1.8 immediately, and check for unusual activity on your system (analysis of the malicious script)

More info here:
https://github.com/web-infra-dev/rspack/releases/tag/v1.1.8


Note that the large majority of Docusaurus users should not be affected:

  • @rspack/core is not installed by default, it is only installed manually with @docusaurus/faster
  • The Rspack team reacted within 1h so even if you use @docusaurus/faster, you really need to be unlucky if you have installed/resolved dependencies at the worst possible time yesterday

@CMCDragonkai

This comment has been minimized.

@alirezamirian
Copy link

Build time going from 3:20 build time to 0:24 🚀
Amazing job, and a very nice approach to implement with the incremental API!
Is there any plan for allowing .swcrc the same way .babelrc was supported when using babel loader for js?
I needed to set jsc.parser.decorators to true and had to either patch @docusaurus/faster or disable swcJsLoader for now.

@slorber
Copy link
Collaborator Author

slorber commented Jan 27, 2025

Build time going from 3:20 build time to 0:24 🚀 Amazing job, and a very nice approach to implement with the incremental API! Is there any plan for allowing .swcrc the same way .babelrc was supported when using babel loader for js? I needed to set jsc.parser.decorators to true and had to either patch @docusaurus/faster or disable swcJsLoader for now.

thanks for reporting!

You should be able to customize the swc loader using our existing siteConfig.webpack.jsLoader config, as explained here: #10556 (comment)

Maybe using .swcrc already works. I haven't tried, but we didn't do anything to explicitly disable support of this file.

@slorber
Copy link
Collaborator Author

slorber commented Jan 27, 2025

Docusaurus v3.8+ will introduce a new Docusaurus Faster option: ssgWorkerThreads .

Depending on your site, it could reduce the SSG time by 50%+ (even more for larger sites), and decrease total build time by more than 15%+.

If you have Docusaurus Faster enabled globally, it will be enabled by default when you upgrade to v3.8+.


This new option requires to turn on a Docusaurus v4 future flag: future.v4. removeLegacyPostBuildHeadAttribute: this permits to opt-in for a breaking change we plan in our plugin API in the upcoming major version of Docusaurus. In practice, this shouldn't cause any trouble, I haven't seen any community plugin using this API, and is relatively safe to turn on.

If you are using Docusaurus Faster, I recommend using the following settings:

export default {
  future: {
    v4: true, // Opt-in for upcoming v4 breaking changes
    experimental_faster: true, // Turn all Docusaurus Faster options on
  },
};

@alirezamirian
Copy link

@slorber Thanks, using webpack.jsLoader option works. Tested again and .swcrc is not picked up.

@karl-cardenas-coding
Copy link

@alirezamirian @slorber We ran into the same issue and disabled the flag swcJsLoader: false because for some odd reason, Netlify returns an exit code 2 when the flag is enabled. All other CI/CD systems, such as GitHub Actions, work fine. It's only in Netlify that we see this issue.

I tried the workaround mentioned in the comment linked above and had no luck. Will this prevent us from upgrading to 3.8 in the future?

@slorber
Copy link
Collaborator Author

slorber commented Jan 28, 2025

@karl-cardenas-coding

We ran into the same issue

The same issue? Which one exactly?

I never heard of such a timeout issue affecting only Netlify.

v3.8 doesn't enable Docusaurus Faster by default, it would be a breaking change that can only be done in an upcoming major version of Docusaurus. I'm not sure yet when we'll turn Docusaurus Faster on by default. During the transition, we'll eventually keep an option for users to downgrade to Webpack and "Docusaurus Slower".

@karl-cardenas-coding
Copy link

@slorber My bad, I wasn't specific. It's really odd, if we keep swcJsLoader: true, it fails only in Netlify (link to logs. Locally and in our GitHub Action everything works fine. We don't get an error message in Netlify that is helpful.

At first we thought it was because of the CSS deprecation warning, but that's not the case as we got those as well when swcJsLoader: false is set. I've also tried different Netlify tricks, like setting the build command to CI= to ignore build errors on warning and no luck. I'm really puzzled as to why our Netlify breaks when swcJsLoade is set to true

¯_(ツ)_/¯

@taraspos
Copy link

Hi @slorber,
I'm seeing following build when trying to upgrade from 3.6 to 3.7 (tried with 3.7.0-canary-6207 too):

Panic occurred at runtime. Please file an issue on GitHub with the backtrace below: https://github.com/web-infra-dev/rspack/issues
Message:  width 3 given for non-narrow character
Location: index.crates.io-6f17d22bba15001f/swc_common-5.0.0/src/syntax_pos.rs:714

Run with COLORBT_SHOW_HIDDEN=1 environment variable to disable frame filtering.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
<empty backtrace>
Aborted
error Command failed with exit code 134.

I tried building with NODE_ENV=production to disable incremental builds and SKIP_HTML_MINIFICATION=true (as mentioned in #9985 (comment)) but it still fails.

You can reproduce it by trying to build:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue is a proposal, usually non-trivial change
Projects
None yet
Development

No branches or pull requests