perf: improve prepare output

This commit is contained in:
pengzhanbo 2024-06-27 03:35:29 +08:00
parent 8e5d9a5e80
commit 6952ba94c3
6 changed files with 90 additions and 17 deletions

View File

@ -1,3 +1,4 @@
import { createHash } from 'node:crypto'
import type { App, Page } from 'vuepress/core'
import { colors, logger } from 'vuepress/utils'
import type { BlogPostData, BlogPostDataItem } from '../shared/index.js'
@ -20,11 +21,8 @@ if (import.meta.hot) {
const headingRe = /<h(\d)[^>]*>.*?<\/h\1>/gi
function getTimestamp(time: Date): number {
return new Date(time).getTime()
}
const EXCERPT_SPLIT = '<!-- more -->'
let contentHash: string | undefined
export async function preparedBlogData(app: App, pageFilter: (id: string) => boolean, options: PluginOption): Promise<void> {
const start = performance.now()
@ -84,8 +82,20 @@ export const blogPostData = JSON.parse(${JSON.stringify(
if (app.env.isDev)
content += HMR_CODE
await app.writeTemp('internal/blogData.js', content)
const currentHash = hash(content)
if (!contentHash || contentHash !== currentHash) {
contentHash = currentHash
await app.writeTemp('internal/blogData.js', content)
}
if (app.env.isDebug)
logger.info(`\n[${colors.green('@vuepress-plume/plugin-blog-data')}] prepare blog data time spent: ${(performance.now() - start).toFixed(2)}ms`)
}
function getTimestamp(time: Date): number {
return new Date(time).getTime()
}
function hash(content: string): string {
return createHash('md5').update(content).digest('hex')
}

View File

@ -9,7 +9,7 @@ import type {
NotesSidebar,
NotesSidebarItem,
} from '../shared/index.js'
import { ensureArray, normalizePath } from './utils.js'
import { ensureArray, hash, normalizePath } from './utils.js'
const HMR_CODE = `
if (import.meta.webpackHot) {
@ -65,6 +65,7 @@ function resolvedNotesData(app: App, options: NotesDataOptions, result: NotesDat
})
}
let contentHash: string | undefined
export async function prepareNotesData(app: App, options: NotesDataOptions | NotesDataOptions[]) {
const start = performance.now()
const notesData: NotesData = {}
@ -78,7 +79,11 @@ export const notesData = ${JSON.stringify(notesData, null, 2)}
if (app.env.isDev)
content += HMR_CODE
await app.writeTemp('internal/notesData.js', content)
const currentHash = hash(content)
if (!contentHash || contentHash !== currentHash) {
contentHash = currentHash
await app.writeTemp('internal/notesData.js', content)
}
if (app.env.isDebug) {
logger.info(

View File

@ -1,3 +1,5 @@
import { createHash } from 'node:crypto'
export function ensureArray<T>(thing: T | T[] | null | undefined): T[] {
if (Array.isArray(thing))
return thing
@ -13,3 +15,7 @@ export function normalizePath(str: string) {
export function wait(time: number) {
return new Promise(resolve => setTimeout(resolve, time))
}
export function hash(content: string): string {
return createHash('md5').update(content).digest('hex')
}

View File

@ -1,6 +1,6 @@
import type { App } from 'vuepress'
import { watch } from 'chokidar'
import { prepareArticleTagColors } from './prepareArticleTagColor.js'
import { prepareArticleTagColors, updateArticleTagColor } from './prepareArticleTagColor.js'
export async function setupPrepare(app: App): Promise<void> {
await prepareArticleTagColors(app)
@ -12,9 +12,9 @@ export function watchPrepare(app: App, watchers: any[]): void {
ignoreInitial: true,
})
watcher.on('change', () => prepareArticleTagColors(app))
watcher.on('add', () => prepareArticleTagColors(app))
watcher.on('unlink', () => prepareArticleTagColors(app))
watcher.on('change', () => updateArticleTagColor(app))
watcher.on('add', () => updateArticleTagColor(app))
watcher.on('unlink', () => updateArticleTagColor(app))
watchers.push(watcher)
}

View File

@ -1,6 +1,7 @@
import { toArray } from '@pengzhanbo/utils'
import type { App } from 'vuepress'
import { nanoid } from '../utils.js'
import { fs } from 'vuepress/utils'
import { hash, nanoid } from '../utils.js'
export type TagsColorsItem = readonly [
string, // normal color
@ -8,6 +9,9 @@ export type TagsColorsItem = readonly [
string, // background color
]
const TEMP_JS = 'internal/articleTagColors.js'
const TEMP_CSS = 'internal/articleTagColors.css'
export const PRESET: TagsColorsItem[] = [
['#6aa1b7', '#5086a1', 'rgba(131, 208, 218, 0.314)'],
['#299764', '#18794e', 'rgba(16, 185, 129, 0.14)'],
@ -46,8 +50,45 @@ if (import.meta.hot) {
// { index: className }
const cache: Record<number, string> = {}
const hashMap: {
js: string
css: string
} = { js: '', css: '' }
export async function prepareArticleTagColors(app: App): Promise<void> {
const [tempJS, tempCSS] = await Promise.all([
readFile(app.dir.temp(TEMP_JS)),
readFile(app.dir.temp(TEMP_CSS)),
])
if (tempJS) {
hashMap.js = hash(tempJS)
}
if (tempCSS) {
hashMap.css = hash(tempCSS)
}
await updateArticleTagColor(app)
}
export async function updateArticleTagColor(app: App): Promise<void> {
const { js, css } = genCode(app)
const cssHash = hash(css)
if (!css || hashMap.css !== cssHash) {
hashMap.css = cssHash
await app.writeTemp(TEMP_CSS, css)
}
const jsHash = hash(js)
if (hashMap.js !== jsHash) {
hashMap.js = jsHash
await app.writeTemp(TEMP_JS, js)
}
}
export function genCode(app: App): { js: string, css: string } {
const articleTagColors: Record<string, string> = {}
const tagList = new Set<string>()
@ -70,16 +111,16 @@ export async function prepareArticleTagColors(app: App): Promise<void> {
}
})
let code = `\
let js = `\
import './articleTagColors.css'
export const articleTagColors = ${JSON.stringify(articleTagColors)}
`
if (app.env.isDev) {
code += HMR_CODE
js += HMR_CODE
}
const css = genCSS()
await app.writeTemp('internal/articleTagColors.css', genTagColorsStyle())
await app.writeTemp('internal/articleTagColors.ts', code)
return { js, css }
}
function getTagCode(tag: string): number {
@ -91,7 +132,7 @@ function getTagCode(tag: string): number {
return code % PRESET.length
}
function genTagColorsStyle(): string {
function genCSS(): string {
let css = ''
for (const [code, className] of Object.entries(cache)) {
@ -109,3 +150,11 @@ function genTagColorsStyle(): string {
return css
}
async function readFile(filepath: string): Promise<string> {
try {
return await fs.readFile(filepath, 'utf-8')
}
catch {}
return ''
}

View File

@ -1,4 +1,5 @@
import process from 'node:process'
import { createHash } from 'node:crypto'
import { customAlphabet } from 'nanoid'
import { fs, getDirname, path } from 'vuepress/utils'
import { Logger, ensureEndingSlash, ensureLeadingSlash } from '@vuepress/helper'
@ -12,6 +13,8 @@ export const templates = (url: string) => resolve('../templates', url)
export const nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 8)
export const hash = (content: string) => createHash('md5').update(content).digest('hex')
export const logger = new Logger(THEME_NAME)
export function getPackage() {