From ec1e39f366aa8b5b37d823d8b3e970f6fc81d756 Mon Sep 17 00:00:00 2001 From: Sukka Date: Sat, 8 Aug 2020 14:53:09 +0800 Subject: [PATCH] perf(injector): shorthand optimization (#4462) * perf(injector): shorthand syntax * test(injector): add test cases for getSize() * refactor(injector): reduce exec() complexity --- lib/extend/injector.js | 77 +++++++++++++++++++++------------ test/scripts/extend/injector.js | 13 ++++++ 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/lib/extend/injector.js b/lib/extend/injector.js index 2cab5514a5..74689d3202 100644 --- a/lib/extend/injector.js +++ b/lib/extend/injector.js @@ -28,6 +28,10 @@ class Injector { return arr.join(''); } + getSize(entry) { + return this.cache.apply(`${entry}-size`, Object.keys(this.store[entry]).length); + } + register(entry, value, to = 'default') { if (!entry) throw new TypeError('entry is required'); if (typeof value === 'function') value = value(); @@ -38,41 +42,58 @@ class Injector { entryMap[to] = valueSet; } - exec(data, locals = { page: {} }) { + _getPageType(pageLocals) { let currentType = 'default'; - const { page } = locals; + if (pageLocals.__index) currentType = 'home'; + if (pageLocals.__post) currentType = 'post'; + if (pageLocals.__page) currentType = 'page'; + if (pageLocals.archive) currentType = 'archive'; + if (pageLocals.category) currentType = 'category'; + if (pageLocals.tag) currentType = 'tag'; + if (pageLocals.layout) currentType = pageLocals.layout; + + return currentType; + } - if (page.__index) currentType = 'home'; - if (page.__post) currentType = 'post'; - if (page.__page) currentType = 'page'; - if (page.archive) currentType = 'archive'; - if (page.category) currentType = 'category'; - if (page.tag) currentType = 'tag'; - if (page.layout) currentType = page.layout; + _injector(input, pattern, flag, isBegin = true, currentType) { + if (input.includes(`hexo injector ${flag}`)) return input; - const injector = (data, pattern, flag, isBegin = true) => { - if (data.includes(`hexo injector ${flag}`)) return data; + const code = this.cache.apply(`${flag}-${currentType}-code`, () => { + const content = currentType === 'default' ? this.getText(flag, 'default') : this.getText(flag, currentType) + this.getText(flag, 'default'); - const code = this.cache.apply(`${flag}-${currentType}-code`, () => { - const content = currentType === 'default' ? this.getText(flag, 'default') : this.getText(flag, currentType) + this.getText(flag, 'default'); + if (!content.length) return ''; + return '' + content + ''; + }); - if (!content.length) return ''; - return '' + content + ''; - }); + // avoid unnecessary replace() for better performance + if (!code.length) return input; - // avoid unnecessary replace() for better performance - if (!code.length) return data; - return data.replace(pattern, str => { return isBegin ? str + code : code + str; }); - }; + return input.replace(pattern, str => { return isBegin ? str + code : code + str; }); + } - // Inject head_begin - data = injector(data, //, 'head_begin', true); - // Inject head_end - data = injector(data, '', 'head_end', false); - // Inject body_begin - data = injector(data, //, 'body_begin', true); - // Inject body_end - data = injector(data, '', 'body_end', false); + exec(data, locals = { page: {} }) { + const { page } = locals; + const currentType = this._getPageType(page); + + if (this.getSize('head_begin') !== 0) { + // Inject head_begin + data = this._injector(data, //, 'head_begin', true, currentType); + } + + if (this.getSize('head_end') !== 0) { + // Inject head_end + data = this._injector(data, '', 'head_end', false, currentType); + } + + if (this.getSize('body_begin') !== 0) { + // Inject body_begin + data = this._injector(data, //, 'body_begin', true, currentType); + } + + if (this.getSize('body_end') !== 0) { + // Inject body_end + data = this._injector(data, '', 'body_end', false, currentType); + } return data; } diff --git a/test/scripts/extend/injector.js b/test/scripts/extend/injector.js index 900c331f8f..08ffc8110c 100644 --- a/test/scripts/extend/injector.js +++ b/test/scripts/extend/injector.js @@ -94,6 +94,19 @@ describe('Injector', () => { i.getText('body_end').should.eql(''); }); + it('getSize()', () => { + const i = new Injector(); + const str = ''; + + i.register('head_end', str); + i.register('body_end', str); + i.register('body_end', str, 'home'); + + i.getSize('head_begin').should.eql(0); + i.getSize('head_end').should.eql(1); + i.getSize('body_end').should.eql(2); + }); + it('exec() - default', () => { const i = new Injector(); const result = i.exec(content);