Skip to content

Commit

Permalink
perf: improve prepare output
Browse files Browse the repository at this point in the history
  • Loading branch information
pengzhanbo committed Jun 26, 2024
1 parent 8e5d9a5 commit 6952ba9
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 17 deletions.
20 changes: 15 additions & 5 deletions plugins/plugin-blog-data/src/node/prepareBlogData.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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()
Expand Down Expand Up @@ -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')
}
9 changes: 7 additions & 2 deletions plugins/plugin-notes-data/src/node/prepareNotesData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 = {}
Expand All @@ -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(
Expand Down
6 changes: 6 additions & 0 deletions plugins/plugin-notes-data/src/node/utils.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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')
}
8 changes: 4 additions & 4 deletions theme/src/node/prepare/index.ts
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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)
}
61 changes: 55 additions & 6 deletions theme/src/node/prepare/prepareArticleTagColor.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
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
string, // hover color
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)'],
Expand Down Expand Up @@ -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>()

Expand All @@ -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 {
Expand All @@ -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)) {
Expand All @@ -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 ''
}
3 changes: 3 additions & 0 deletions theme/src/node/utils.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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() {
Expand Down

0 comments on commit 6952ba9

Please sign in to comment.