perf(theme): optimize load theme config

This commit is contained in:
pengzhanbo 2024-08-30 19:11:47 +08:00
parent 5f13a1ba46
commit 047e0527f5
6 changed files with 42 additions and 81 deletions

View File

@ -6,7 +6,7 @@ export const theme: Theme = plumeTheme({
hostname: process.env.SITE_HOST || 'https://plume.pengzhanbo.cn',
plugins: {
shiki: { twoslash: true },
shiki: { twoslash: true, lineNumbers: 10 },
markdownEnhance: {
demo: true,

View File

@ -26,8 +26,6 @@ export interface Generate {
}
let generate: Generate | null = null
let generated = false
const whenGenerated: (() => void)[] = []
export function initAutoFrontmatter(
localeOptions: PlumeThemeLocaleOptions,
@ -64,16 +62,11 @@ export function initAutoFrontmatter(
export async function generateAutoFrontmatter(app: App) {
if (!generate)
return
generated = false
const markdownList = await readMarkdownList(app.dir.source(), generate.globFilter)
await promiseParallel(
markdownList.map(file => () => generator(file)),
64,
)
generated = true
whenGenerated.forEach(resolve => resolve())
whenGenerated.length = 0
}
export async function watchAutoFrontmatter(app: App, watchers: any[], enable?: () => boolean) {
@ -132,12 +125,3 @@ async function generator(file: AutoFrontmatterMarkdownFile): Promise<void> {
console.error(e)
}
}
export function waitForAutoFrontmatter() {
return new Promise<void>((resolve) => {
if (generate && !generated)
whenGenerated.push(resolve)
else
resolve()
})
}

View File

@ -65,13 +65,12 @@ export async function initConfigLoader(
loader.loaded = true
loader.dependencies = [...dependencies]
updateResolvedConfig(app, config)
runChangeEvents()
loader.whenLoaded.forEach(fn => fn(loader!.resolvedConfig))
loader.whenLoaded = []
}
export function watchConfigFile(app: App, watchers: any[]) {
export function watchConfigFile(app: App, watchers: any[], onChange: ChangeEvent) {
if (!loader || !loader.configFile)
return
@ -82,6 +81,8 @@ export function watchConfigFile(app: App, watchers: any[]) {
addDependencies(watcher)
onConfigChange(onChange)
watcher.on('change', async () => {
if (loader) {
loader.loaded = false
@ -121,7 +122,7 @@ export function waitForConfigLoaded() {
})
}
export function getResolvedThemeConfig() {
export function getThemeConfig() {
return loader!.resolvedConfig
}

View File

@ -22,6 +22,7 @@ import {
resolveSearchOptions,
} from '../config/index.js'
import { customContainerPlugins } from './containerPlugins.js'
import { markdownTitlePlugin } from './markdown-title.js'
export interface SetupPluginOptions {
app: App
@ -39,7 +40,7 @@ export function getPlugins({
const isProd = !app.env.isDev
const plugins: PluginConfig = [
markdownTitlePlugin(),
fontsPlugin(),
contentUpdatePlugin(),
activeHeaderLinksPlugin({

View File

@ -1,6 +1,6 @@
import type { App } from 'vuepress'
import { watch } from 'chokidar'
import { getResolvedThemeConfig } from '../loadConfig/index.js'
import { getThemeConfig } from '../loadConfig/index.js'
import { prepareArticleTagColors } from './prepareArticleTagColor.js'
import { preparedBlogData } from './prepareBlogData.js'
import { prepareEncrypt } from './prepareEncrypt.js'
@ -10,7 +10,7 @@ import { prepareIcons } from './prepareIcons.js'
export async function prepareData(
app: App,
): Promise<void> {
const { localeOptions, encrypt } = getResolvedThemeConfig()
const { localeOptions, encrypt } = getThemeConfig()
await Promise.all([
prepareArticleTagColors(app),
preparedBlogData(app, localeOptions, encrypt),

View File

@ -4,38 +4,14 @@ import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js'
import { getPlugins } from './plugins/index.js'
import { extendsPageData, setupPage } from './setupPages.js'
import { THEME_NAME, resolve, templates } from './utils/index.js'
import {
extendsBundlerOptions,
resolveAlias,
resolvePageHead,
resolveProvideData,
resolveThemeOptions,
templateBuildRenderer,
} from './config/index.js'
import {
getResolvedThemeConfig,
initConfigLoader,
onConfigChange,
waitForConfigLoaded,
watchConfigFile,
} from './loadConfig/index.js'
import {
generateAutoFrontmatter,
initAutoFrontmatter,
waitForAutoFrontmatter,
watchAutoFrontmatter,
} from './autoFrontmatter/index.js'
import { extendsBundlerOptions, resolveAlias, resolvePageHead, resolveProvideData, resolveThemeOptions, templateBuildRenderer } from './config/index.js'
import { getThemeConfig, initConfigLoader, waitForConfigLoaded, watchConfigFile } from './loadConfig/index.js'
import { generateAutoFrontmatter, initAutoFrontmatter, watchAutoFrontmatter } from './autoFrontmatter/index.js'
import { prepareData, watchPrepare } from './prepare/index.js'
import { prepareThemeData } from './prepare/prepareThemeData.js'
export function plumeTheme(options: PlumeThemeOptions = {}): Theme {
const {
localeOptions,
pluginOptions,
hostname,
configFile,
cache,
} = resolveThemeOptions(options)
const { localeOptions, pluginOptions, hostname, configFile, cache } = resolveThemeOptions(options)
return (app) => {
initConfigLoader(app, localeOptions, {
@ -48,14 +24,6 @@ export function plumeTheme(options: PlumeThemeOptions = {}): Theme {
},
})
waitForConfigLoaded().then(async ({ autoFrontmatter }) => {
autoFrontmatter ??= pluginOptions.frontmatter
if (autoFrontmatter !== false) {
await sleep(100)
generateAutoFrontmatter(app)
}
})
return {
name: THEME_NAME,
@ -69,42 +37,49 @@ export function plumeTheme(options: PlumeThemeOptions = {}): Theme {
plugins: getPlugins({ app, pluginOptions, hostname, cache }),
extendsBundlerOptions,
templateBuildRenderer,
extendsMarkdown: async (_, app) => {
const { autoFrontmatter } = await waitForConfigLoaded()
if ((autoFrontmatter ?? pluginOptions.frontmatter) !== false) {
await generateAutoFrontmatter(app)
// wait for autoFrontmatter generated
// i/o performance
await sleep(100)
}
},
extendsPage: async (page) => {
const { localeOptions } = getThemeConfig()
extendsPageData(page as Page<PlumeThemePageData>, localeOptions)
resolvePageHead(page, localeOptions)
},
onInitialized: async (app) => {
const { localeOptions } = await waitForConfigLoaded()
const { localeOptions } = getThemeConfig()
await setupPage(app, localeOptions)
},
onPrepared: async (app) => {
onConfigChange(async ({ localeOptions }) => {
await prepareThemeData(app, localeOptions)
await prepareData(app)
})
const { localeOptions } = await waitForConfigLoaded()
const { localeOptions } = getThemeConfig()
await prepareThemeData(app, localeOptions)
await prepareData(app)
},
onWatched: (app, watchers) => {
watchConfigFile(app, watchers)
watchPrepare(app, watchers)
watchConfigFile(app, watchers, async ({ localeOptions }) => {
await prepareThemeData(app, localeOptions)
await prepareData(app)
})
watchAutoFrontmatter(app, watchers, () => {
const autoFrontmatter = getResolvedThemeConfig().autoFrontmatter ?? pluginOptions.frontmatter
const autoFrontmatter = getThemeConfig().autoFrontmatter
?? pluginOptions.frontmatter
return autoFrontmatter !== false
})
watchPrepare(app, watchers)
},
extendsPage: async (page) => {
const { localeOptions, autoFrontmatter } = await waitForConfigLoaded()
if ((autoFrontmatter ?? pluginOptions.frontmatter) !== false) {
await waitForAutoFrontmatter()
}
extendsPageData(page as Page<PlumeThemePageData>, localeOptions)
resolvePageHead(page, localeOptions)
},
extendsBundlerOptions,
templateBuildRenderer,
}
}
}