perf: optimize memory usage during build time (#850)

This commit is contained in:
pengzhanbo 2026-02-12 21:11:01 +08:00 committed by GitHub
parent 8daddcac5d
commit 78a2859398
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 32 additions and 11 deletions

View File

@ -22,9 +22,9 @@ const indexByLocales = new Map<string, MiniSearch<IndexObject>>()
const indexCache = new Map<string, IndexObject[]>() const indexCache = new Map<string, IndexObject[]>()
function getIndexByLocale(locale: string, lang: string, options: SearchIndexOptions['searchOptions']) { function getIndexByLocale(locale: string, lang: string, options: SearchIndexOptions['searchOptions']) {
const segmenter = new Intl.Segmenter(lang, { granularity: 'word' })
let index = indexByLocales.get(locale) let index = indexByLocales.get(locale)
if (!index) { if (!index) {
const segmenter = new Intl.Segmenter(lang, { granularity: 'word' })
index = new MiniSearch<IndexObject>({ index = new MiniSearch<IndexObject>({
fields: ['title', 'titles', 'text'], fields: ['title', 'titles', 'text'],
storeFields: ['title', 'titles'], storeFields: ['title', 'titles'],
@ -62,6 +62,11 @@ export async function prepareSearchIndex({
}) })
await writeTemp(app) await writeTemp(app)
if (app.env.isBuild) {
indexByLocales.clear()
indexCache.clear()
}
if (app.env.isDebug) { if (app.env.isDebug) {
logger.info( logger.info(
`\n[${colors.green('@vuepress-plume/plugin-search')}] prepare search time spent: ${(performance.now() - start).toFixed(2)}ms`, `\n[${colors.green('@vuepress-plume/plugin-search')}] prepare search time spent: ${(performance.now() - start).toFixed(2)}ms`,

View File

@ -265,7 +265,7 @@ watch(
padding: 48px 32px 0; padding: 48px 32px 0;
} }
.vp-doc-container:not(.has-sidebar) .container, { .vp-doc-container:not(.has-sidebar) .container {
display: flex; display: flex;
justify-content: center; justify-content: center;
max-width: 992px; max-width: 992px;

View File

@ -106,7 +106,7 @@ function resolveFromSidebarItems(sidebarItems: NavItemWithLink[], currentPath: s
if (index === -1) if (index === -1)
return null return null
// eslint-disable-next-line no-cond-assign // eslint-disable-next-line no-cond-assign
while ((index += offset) >= 0) { while ((index += offset) >= 0 && index < sidebarItems.length) {
const targetItem = sidebarItems[index] const targetItem = sidebarItems[index]
if (targetItem?.link && !SEPARATOR_RE.test(targetItem.link)) { if (targetItem?.link && !SEPARATOR_RE.test(targetItem.link)) {
return targetItem return targetItem

View File

@ -26,7 +26,7 @@ async function getMarkdownInfo(relativePath: string, cwd: string): Promise<{
const raw = await fs.promises.readFile(filepath, 'utf-8') const raw = await fs.promises.readFile(filepath, 'utf-8')
const { data, content } = matter(raw) const { data, content } = matter(raw)
return { return {
data, data: data as AutoFrontmatterData,
context: { context: {
filepath, filepath,
relativePath, relativePath,

View File

@ -30,7 +30,7 @@ export const PRESET: TagsColorsItem[] = [
] ]
// { index: className } // { index: className }
const cache: Record<number, string> = {} let cache: Record<number, string> = {}
export async function prepareArticleTagColors(app: App): Promise<void> { export async function prepareArticleTagColors(app: App): Promise<void> {
perf.mark('prepare:tag-colors') perf.mark('prepare:tag-colors')
@ -39,6 +39,10 @@ export async function prepareArticleTagColors(app: App): Promise<void> {
await writeTemp(app, 'internal/articleTagColors.css', css) await writeTemp(app, 'internal/articleTagColors.css', css)
await writeTemp(app, 'internal/articleTagColors.js', js) await writeTemp(app, 'internal/articleTagColors.js', js)
if (app.env.isBuild) {
cache = {}
}
perf.log('prepare:tag-colors') perf.log('prepare:tag-colors')
} }

View File

@ -9,7 +9,7 @@ export async function prepareCollections(app: App): Promise<void> {
const { collections: fallback, locales } = getThemeConfig() const { collections: fallback, locales } = getThemeConfig()
const data: Record<string, ThemeCollectionItem[]> = {} let data: Record<string, ThemeCollectionItem[]> = {}
for (const [locale, opt] of Object.entries(locales || {})) { for (const [locale, opt] of Object.entries(locales || {})) {
let collections = opt.collections let collections = opt.collections
@ -32,5 +32,9 @@ export async function prepareCollections(app: App): Promise<void> {
const content = resolveContent(app, { name: 'collections', content: data }) const content = resolveContent(app, { name: 'collections', content: data })
await writeTemp(app, 'internal/collectionsData.js', content) await writeTemp(app, 'internal/collectionsData.js', content)
if (app.env.isBuild) {
data = {}
}
perf.log('prepare:collections') perf.log('prepare:collections')
} }

View File

@ -42,7 +42,7 @@ export async function prepareEncrypt(app: App): Promise<void> {
content: resolvedEncrypt, content: resolvedEncrypt,
})) }))
fsCache?.write([currentHash, resolvedEncrypt]) fsCache?.write([currentHash, resolvedEncrypt], app.env.isBuild)
perf.log('prepare:encrypt') perf.log('prepare:encrypt')
} }

View File

@ -40,7 +40,7 @@ let locate!: ((name: string) => any)
let fsCache: FsCache<IconDataMap> | null = null let fsCache: FsCache<IconDataMap> | null = null
// { iconName: { className, content } } // { iconName: { className, content } }
const cache: IconDataMap = {} let cache: IconDataMap = {}
// 旧版本内置图标别名,映射回 simple-icons 集合中的名称 // 旧版本内置图标别名,映射回 simple-icons 集合中的名称
const socialFallbacks: Record<string, string> = { const socialFallbacks: Record<string, string> = {
@ -135,7 +135,11 @@ export async function prepareIcons(app: App): Promise<void> {
})), })),
]) ])
fsCache?.write(cache) fsCache?.write(cache, app.env.isBuild)
if (app.env.isBuild) {
cache = {}
}
perf.log('prepare:icons:total') perf.log('prepare:icons:total')
} }

View File

@ -12,7 +12,7 @@ export interface FsCache<T> {
hash: string hash: string
data: T | null data: T | null
read: () => Promise<T | null> read: () => Promise<T | null>
write: (data: T) => Promise<void> write: (data: T, clear?: boolean) => Promise<void>
} }
const CACHE_BASE = 'markdown' const CACHE_BASE = 'markdown'
@ -37,7 +37,7 @@ export function createFsCache<T = any>(app: App, name: string): FsCache<T> {
} }
let timer: NodeJS.Timeout | null = null let timer: NodeJS.Timeout | null = null
const write = async (data: T) => { const write = async (data: T, clear?: boolean) => {
const currentHash = hash(data) const currentHash = hash(data)
if (cache.hash && currentHash === cache.hash) if (cache.hash && currentHash === cache.hash)
return return
@ -49,6 +49,10 @@ export function createFsCache<T = any>(app: App, name: string): FsCache<T> {
timer = setTimeout(async () => { timer = setTimeout(async () => {
await fs.mkdir(path.dirname(filepath), { recursive: true }) await fs.mkdir(path.dirname(filepath), { recursive: true })
await fs.writeFile(filepath, JSON.stringify(cache), 'utf-8') await fs.writeFile(filepath, JSON.stringify(cache), 'utf-8')
if (clear) {
cache.data = null
cache.hash = ''
}
}, 300) }, 300)
} }