Skip to content

Commit

Permalink
perf(tag/helper): memoize (#4789)
Browse files Browse the repository at this point in the history
  • Loading branch information
SukkaW authored Oct 14, 2021
1 parent 2ec4f63 commit ed0f239
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 26 deletions.
6 changes: 5 additions & 1 deletion lib/plugins/helper/css.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const { htmlTag, url_for } = require('hexo-util');
const { default: moize } = require('moize');

const flatten = function(arr, result = []) {
for (const i in arr) {
Expand Down Expand Up @@ -35,4 +36,7 @@ function cssHelper(...args) {
return result;
}

module.exports = cssHelper;
module.exports = moize(cssHelper, {
maxSize: 10,
isDeepEqual: true
});
3 changes: 2 additions & 1 deletion lib/plugins/helper/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const moment = require('moment-timezone');
const { isMoment } = moment;
const { default: moize } = require('moize');

const isDate = value =>
typeof value === 'object' && value instanceof Date && !isNaN(value.getTime());
Expand Down Expand Up @@ -93,4 +94,4 @@ exports.full_date = fullDateHelper;
exports.relative_date = relativeDateHelper;
exports.time_tag = timeTagHelper;
exports.moment = moment;
exports.toMomentLocale = toMomentLocale;
exports.toMomentLocale = moize.shallow(toMomentLocale);
24 changes: 14 additions & 10 deletions lib/plugins/helper/feed_tag.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
'use strict';

const { url_for } = require('hexo-util');
const { default: moize } = require('moize');

const feedFn = (str = '') => {
if (str) return str.replace(/2$/, '');
return str;
};

function feedTagHelper(path, options = {}) {
const { config } = this;
const title = options.title || config.title;
function makeFeedTag(path, options = {}, configFeed, configTitle) {
const title = options.title || configTitle;

if (path) {
if (typeof path !== 'string') throw new TypeError('path must be a string!');
Expand All @@ -26,16 +26,15 @@ function feedTagHelper(path, options = {}) {
return `<link rel="alternate" href="${url_for.call(this, path)}" title="${title}" ${typeAttr}>`;
}

if (config.feed) {
const { feed } = config;
if (feed.type && feed.path) {
if (typeof feed.type === 'string') {
return `<link rel="alternate" href="${url_for.call(this, feed.path)}" title="${title}" type="application/${feedFn(feed.type)}+xml">`;
if (configFeed) {
if (configFeed.type && configFeed.path) {
if (typeof configFeed.type === 'string') {
return `<link rel="alternate" href="${url_for.call(this, configFeed.path)}" title="${title}" type="application/${feedFn(configFeed.type)}+xml">`;
}

let result = '';
for (const i in feed.type) {
result += `<link rel="alternate" href="${url_for.call(this, feed.path[i])}" title="${title}" type="application/${feedFn(feed.type[i])}+xml">`;
for (const i in configFeed.type) {
result += `<link rel="alternate" href="${url_for.call(this, configFeed.path[i])}" title="${title}" type="application/${feedFn(configFeed.type[i])}+xml">`;
}
return result;
}
Expand All @@ -44,4 +43,9 @@ function feedTagHelper(path, options = {}) {
return '';
}

function feedTagHelper(path, options = {}) {
const { config } = this;
return moize.deep(makeFeedTag.bind(this))(path, options, config.feed, config.title);
}

module.exports = feedTagHelper;
6 changes: 5 additions & 1 deletion lib/plugins/helper/js.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const { htmlTag, url_for } = require('hexo-util');
const { default: moize } = require('moize');

/* flatten() to be replaced by Array.flat()
after Node 10 has reached EOL */
Expand Down Expand Up @@ -37,4 +38,7 @@ function jsHelper(...args) {
return result;
}

module.exports = jsHelper;
module.exports = moize(jsHelper, {
maxSize: 10,
isDeepEqual: true
});
20 changes: 19 additions & 1 deletion lib/plugins/helper/list_tags.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const { url_for, escapeHTML } = require('hexo-util');
const { default: moize } = require('moize');

function listTagsHelper(tags, options) {
if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) {
Expand Down Expand Up @@ -92,4 +93,21 @@ function listTagsHelper(tags, options) {
return result;
}

module.exports = listTagsHelper;
function listTagsHelperFactory(tags, options) {
const transformArgs = () => {
if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) {
options = tags;
tags = this.site.tags;
}

return [tags.toArray(), options];
};

return moize(listTagsHelper.bind(this), {
maxSize: 5,
isDeepEqual: true,
transformArgs
}).call(this, tags, options);
}

module.exports = listTagsHelperFactory;
6 changes: 5 additions & 1 deletion lib/plugins/helper/mail_to.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const { htmlTag } = require('hexo-util');
const qs = require('querystring');
const { default: moize } = require('moize');

function mailToHelper(path, text, options = {}) {
if (Array.isArray(path)) path = path.join(',');
Expand Down Expand Up @@ -33,4 +34,7 @@ function mailToHelper(path, text, options = {}) {
return htmlTag('a', attrs, text);
}

module.exports = mailToHelper;
module.exports = moize(mailToHelper, {
maxSize: 10,
isDeepEqual: true
});
7 changes: 4 additions & 3 deletions lib/plugins/helper/open_graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

const { parse, resolve } = require('url');
const { isMoment, isDate } = require('moment');
const { encodeURL, prettyUrls, htmlTag, stripHTML, escapeHTML, Cache } = require('hexo-util');
const { encodeURL, prettyUrls, htmlTag, stripHTML, escapeHTML } = require('hexo-util');
const { default: moize } = require('moize');

const localeMap = {
'en': 'en_US',
Expand All @@ -20,8 +21,8 @@ const localeMap = {
'tr': 'tr_TR',
'vi': 'vi_VN'
};
const localeCache = new Cache();
const localeToTerritory = str => localeCache.apply(str, () => {

const localeToTerritory = moize.shallow(str => {
if (str.length === 2 && localeMap[str]) return localeMap[str];

if (str.length === 5) {
Expand Down
4 changes: 3 additions & 1 deletion lib/plugins/helper/search_form.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const { default: moize } = require('moize');

function searchFormHelper(options = {}) {
const { config } = this;
const className = options.class || 'search-form';
Expand All @@ -8,4 +10,4 @@ function searchFormHelper(options = {}) {
return `<form action="//google.com/search" method="get" accept-charset="UTF-8" class="${className}"><input type="search" name="q" class="${className}-input"${text ? ` placeholder="${text}"` : ''}>${button ? `<button type="submit" class="${className}-submit">${typeof button === 'string' ? button : text}</button>` : ''}<input type="hidden" name="sitesearch" value="${config.url}"></form>`;
}

module.exports = searchFormHelper;
module.exports = moize.deep(searchFormHelper);
20 changes: 19 additions & 1 deletion lib/plugins/helper/tagcloud.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const { Color, url_for } = require('hexo-util');
const { default: moize } = require('moize');

function tagcloudHelper(tags, options) {
if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) {
Expand Down Expand Up @@ -74,4 +75,21 @@ function tagcloudHelper(tags, options) {
return result.join(separator);
}

module.exports = tagcloudHelper;
function tagcloudHelperFactory(tags, options) {
const transformArgs = () => {
if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) {
options = tags;
tags = this.site.tags;
}

return [tags.toArray(), options];
};

return moize(tagcloudHelper.bind(this), {
maxSize: 5,
isDeepEqual: true,
transformArgs
}).call(this, tags, options);
}

module.exports = tagcloudHelperFactory;
24 changes: 24 additions & 0 deletions lib/plugins/tag/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const { default: moize } = require('moize');

module.exports = ctx => {
const { tag } = ctx.extend;

Expand Down Expand Up @@ -52,3 +54,25 @@ module.exports = ctx => {

tag.register('youtube', require('./youtube'));
};

// Use WeakMap to track different ctx (in case there is any)
const moized = new WeakMap();

module.exports.postFindOneFactory = function postFindOneFactory(ctx) {
if (moized.has(ctx)) {
return moized.get(ctx);
}

const moizedPostFindOne = moize(createPostFindOne(ctx), {
isDeepEqual: true,
maxSize: 20
});
moized.set(ctx, moizedPostFindOne);

return moizedPostFindOne;
};

function createPostFindOne(ctx) {
const Post = ctx.model('Post');
return Post.findOne.bind(Post);
}
5 changes: 2 additions & 3 deletions lib/plugins/tag/post_link.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const { encodeURL, escapeHTML } = require('hexo-util');
const { resolve } = require('url');
const { postFindOneFactory } = require('./');

/**
* Post link tag
Expand All @@ -10,8 +11,6 @@ const { resolve } = require('url');
* {% post_link slug [title] [escape] %}
*/
module.exports = ctx => {
const Post = ctx.model('Post');

return function postLinkTag(args) {
const error = `<a href="#">Post not found: ${args.join(' ') || 'Invalid post_link'}</a>`;
const slug = args.shift();
Expand All @@ -24,7 +23,7 @@ module.exports = ctx => {
escape = 'true';
}

const post = Post.findOne({slug});
const post = postFindOneFactory(ctx)({ slug });
if (!post) return error;

let title = args.length ? args.join(' ') : post.title;
Expand Down
5 changes: 2 additions & 3 deletions lib/plugins/tag/post_path.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const { resolve } = require('url');
const { encodeURL } = require('hexo-util');
const { postFindOneFactory } = require('./');

/**
* Post path tag
Expand All @@ -10,13 +11,11 @@ const { encodeURL } = require('hexo-util');
* {% post_path slug %}
*/
module.exports = ctx => {
const Post = ctx.model('Post');

return function postPathTag(args) {
const slug = args.shift();
if (!slug) return;

const post = Post.findOne({slug});
const post = postFindOneFactory(ctx)({ slug });
if (!post) return;

const link = encodeURL(resolve(ctx.config.root, post.path));
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"hexo-util": "^2.4.0",
"js-yaml": "^4.0.0",
"micromatch": "^4.0.2",
"moize": "^6.1.0",
"moment": "^2.22.2",
"moment-timezone": "^0.5.21",
"nanocolors": "^0.2.12",
Expand Down

0 comments on commit ed0f239

Please sign in to comment.