Skip to content

Commit

Permalink
feat($markdown): cache parser (#1359)
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma authored and ulivz committed Feb 27, 2019
1 parent 8f83a17 commit f04adbf
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 18 deletions.
22 changes: 6 additions & 16 deletions packages/@vuepress/markdown-loader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@

const { EventEmitter } = require('events')
const { getOptions } = require('loader-utils')
const { fs, path, hash, parseFrontmatter, inferTitle, extractHeaders } = require('@vuepress/shared-utils')
const { fs, path, parseFrontmatter, inferTitle, extractHeaders } = require('@vuepress/shared-utils')
const LRU = require('lru-cache')
const md = require('@vuepress/markdown')

const cache = new LRU({ max: 1000 })
const devCache = new LRU({ max: 1000 })

/**
Expand All @@ -32,26 +31,18 @@ module.exports = function (src) {
// vue-loader, and will be applied on the same file multiple times when
// selecting the individual blocks.
const file = this.resourcePath
const key = hash(file + src)
const cached = cache.get(key)
if (cached && (isProd || /\?vue/.test(this.resourceQuery))) {
return cached
}

const frontmatter = parseFrontmatter(src)
const content = frontmatter.content
const { content, data } = parseFrontmatter(src)

if (!isProd && !isServer) {
const inferredTitle = inferTitle(frontmatter.data, frontmatter.content)
const inferredTitle = inferTitle(data, content)
const headers = extractHeaders(content, ['h2', 'h3'], markdown)
delete frontmatter.content

// diff frontmatter and title, since they are not going to be part of the
// returned component, changes in frontmatter do not trigger proper updates
const cachedData = devCache.get(file)
if (cachedData && (
cachedData.inferredTitle !== inferredTitle
|| JSON.stringify(cachedData.frontmatterData) !== JSON.stringify(frontmatter.data)
|| JSON.stringify(cachedData.frontmatterData) !== JSON.stringify(data)
|| headersChanged(cachedData.headers, headers)
)) {
// frontmatter changed... need to do a full reload
Expand All @@ -60,7 +51,7 @@ module.exports = function (src) {

devCache.set(file, {
headers,
frontmatterData: frontmatter.data,
frontmatterData: data,
inferredTitle
})
}
Expand All @@ -73,7 +64,7 @@ module.exports = function (src) {
dataBlockString
} = markdown.render(content, {
loader,
frontmatter: frontmatter.data,
frontmatter: data,
relPath: path.relative(sourceDir, file)
})

Expand Down Expand Up @@ -114,7 +105,6 @@ module.exports = function (src) {
+ (hoistedTags || []).join('\n')
+ `\n${dataBlockString}\n`
)
cache.set(key, res)
return res
}

Expand Down
3 changes: 2 additions & 1 deletion packages/@vuepress/markdown-loader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
],
"dependencies": {
"@vuepress/markdown": "^1.0.0-alpha.39",
"loader-utils": "^1.1.0"
"loader-utils": "^1.1.0",
"lru-cache": "^5.1.1"
},
"author": "Evan You",
"maintainers": [
Expand Down
18 changes: 17 additions & 1 deletion packages/@vuepress/markdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

const Config = require('markdown-it-chain')
const LRUCache = require('lru-cache')
const highlight = require('./lib/highlight')
const { PLUGINS, REQUIRED_PLUGINS } = require('./lib/constant')
const highlightLinesPlugin = require('./lib/highlightLines')
Expand All @@ -19,7 +20,7 @@ const snippetPlugin = require('./lib/snippet')
const emojiPlugin = require('markdown-it-emoji')
const anchorPlugin = require('markdown-it-anchor')
const tocPlugin = require('markdown-it-table-of-contents')
const { parseHeaders, slugify: _slugify, logger, chalk } = require('@vuepress/shared-utils')
const { parseHeaders, slugify: _slugify, logger, chalk, hash } = require('@vuepress/shared-utils')

/**
* Create markdown by config.
Expand Down Expand Up @@ -115,6 +116,21 @@ module.exports = (markdown = {}) => {

afterInstantiate && afterInstantiate(md)

// override parse to allow cache
const parse = md.parse
const cache = new LRUCache({ max: 1000 })
md.parse = (src, env) => {
const key = hash(src + env.relPath)
const cached = cache.get(key)
if (cached) {
return cached
} else {
const tokens = parse.call(md, src, env)
cache.set(key, tokens)
return tokens
}
}

module.exports.dataReturnable(md)

// expose slugify
Expand Down
1 change: 1 addition & 0 deletions packages/@vuepress/markdown/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
],
"dependencies": {
"@vuepress/shared-utils": "^1.0.0-alpha.39",
"lru-cache": "^5.1.1",
"markdown-it": "^8.4.1",
"markdown-it-anchor": "^5.0.2",
"markdown-it-chain": "^1.3.0",
Expand Down

0 comments on commit f04adbf

Please sign in to comment.