Skip to content

Feature: Enable Plugin loadContent caching, improve plugin reload perf #5393

@milesj

Description

@milesj

🚀 Feature

This feature request will help to avoid slow builds/hot reloads by allowing plugin authors to cache effectively.

Do note that this is a plugin author feature request and not for the end-user.

Have you read the Contributing Guidelines on issues?

Yes

Has this been requested on Canny?

No

Motivation

Plugin authors can utilize the loadContent life-cycle (docs) to async/sync load content needed for the plugin. However, this method is called every time a file is changed while the development server is running.

Typically this is ok and wanted functionality, but if the code within loadContent takes a considerable amount of time to process, then the entire experience is degraded. I ran into this while building docusaurus-plugin-typedoc-api, as the TypeDoc build process is rather slow (roughly 30 seconds).

To help alleviate this problem we can cache the long processes, but there is no way to invalidate the cache, or know when we should rebuild.

API Design

My proposal is to pass a "build state" object to the loadContent life-cycle method. This object would contain the following properties:

  • firstLoad (boolean) - A flag representing the 1st time loadContent is called. Triggered by both build and start. This will allow authors to effectively cache miss on new builds.
  • changedFiles (string[]) - A list of files that have changed since the last rebuild/reload. This will allow authors to determine whether to cache hit/miss based on file paths/extensions.

Using my TypeDoc problem above, an example of this in practice would look something like.

async loadContent({ firstLoad, changedFiles }) {
	const cachePath = path.join(context.generatedFilesDir, 'typedoc.json');
	const hasTsFiles = changedFiles.some(file => file.match(/\.tsx?$/));

	// Run TypeDoc and write to cache if first load or TS files have changed
	if (firstLoad || hasTsFiles) {
		await generateTypeDocJson(cachePath);
	}

	return import(cachePath);
}

Have you tried building it?

No, not yet...

I have tried to detect whether a rebuild is happening, but there's no way to persist plugin state. For example, the following does not work, it always logs 1.

export default function() {
	let count = 0;

	return {
		async loadContent() {
			count += 1;
			console.log(count);
		}
	};
}

Have also looked into environment variables, but nothing related to rebuilds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureThis is not a bug or issue with Docusausus, per se. It is a feature request for the future.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions