From ff0cfca3cfe5cd62c480e8f11dc23aa19570cf3a Mon Sep 17 00:00:00 2001 From: Yuxin Wu Date: Tue, 29 Mar 2022 20:07:40 -0700 Subject: [PATCH] Async rendering of tags within a post --- lib/hexo/post.js | 26 +++++++++++++++----------- package.json | 1 + test/scripts/hexo/post.js | 4 ++-- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/hexo/post.js b/lib/hexo/post.js index 7f0db61bbe..817173041b 100644 --- a/lib/hexo/post.js +++ b/lib/hexo/post.js @@ -2,6 +2,7 @@ const assert = require('assert'); const moment = require('moment'); +const parse5 = require('parse5'); const Promise = require('bluebird'); const { join, extname, basename } = require('path'); const { magenta } = require('picocolors'); @@ -414,18 +415,21 @@ class Post { text: data.content, path: source, engine: data.engine, - toString: true, - onRenderEnd(content) { - // Replace cache data with real contents - data.content = cacheObj.restoreAllSwigTags(content); - - // Return content after replace the placeholders - if (disableNunjucks) return data.content; - - // Render with Nunjucks - return tag.render(data.content, data); - } + toString: true }, options); + }).then(content => { + const doc = parse5.parseFragment(content); + // Indepedently render the tags in each top-level node + // asynchronously. This can significantly speed up rendering of slow tags + const results = doc.childNodes.map(async node => { + // Replace cache data with real contents + const content = cacheObj.restoreAllSwigTags(parse5.serializeOuter(node)); + // If disabled, return content after replacing the placeholders + if (disableNunjucks) return content; + // Render with Nunjucks + return await tag.render(content, data); + }); + return Promise.all(results).then(x => x.join('')); }).then(content => { data.content = cacheObj.restoreCodeBlocks(content); diff --git a/package.json b/package.json index f566b4e5e7..c0eca988fe 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "moment-timezone": "^0.5.34", "picocolors": "^1.0.0", "nunjucks": "^3.2.3", + "parse5": "^7.0.0", "pretty-hrtime": "^1.0.3", "resolve": "^1.22.0", "strip-ansi": "^6.0.0", diff --git a/test/scripts/hexo/post.js b/test/scripts/hexo/post.js index ccedb78a82..247204539d 100644 --- a/test/scripts/hexo/post.js +++ b/test/scripts/hexo/post.js @@ -3,7 +3,7 @@ const { join } = require('path'); const moment = require('moment'); const { readFile, mkdirs, unlink, rmdir, writeFile, exists, stat, listDir } = require('hexo-fs'); -const { highlight, escapeHTML } = require('hexo-util'); +const { highlight } = require('hexo-util'); const { spy, useFakeTimers } = require('sinon'); const { parse: yfm } = require('hexo-front-matter'); const fixture = require('../../fixtures/post_render'); @@ -1215,7 +1215,7 @@ describe('Post', () => { engine: 'markdown' }); - data.content.trim().should.contains(`
${escapeHTML('echo "Hi"')}\n
`); + data.content.trim().should.contains('
echo "Hi"\n
'); data.content.trim().should.contains(''); data.content.trim().should.contains(''); });