PERF: Cache PrettyText instance for rendering composer preview (#9987)

Previously we were building pretty-text from scratch on every keypress
This commit is contained in:
David Taylor 2020-06-08 10:42:59 +01:00 committed by GitHub
parent 4ce618e55b
commit 833b5d89e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 3 deletions

View File

@ -9,7 +9,7 @@ import discourseComputed, {
} from "discourse-common/utils/decorators";
import { categoryHashtagTriggerRule } from "discourse/lib/category-hashtags";
import { search as searchCategoryTag } from "discourse/lib/category-tag-search";
import { cookAsync } from "discourse/lib/text";
import { generateCookFunction } from "discourse/lib/text";
import { getRegister } from "discourse-common/lib/get-owner";
import { findRawTemplate } from "discourse-common/lib/raw-templates";
import { siteDir } from "discourse/lib/text-direction";
@ -344,15 +344,26 @@ export default Component.extend({
return toolbar;
},
cachedCookAsync(text) {
if (this._cachedCookFunction) {
return Promise.resolve(this._cachedCookFunction(text));
}
const markdownOptions = this.markdownOptions || {};
return generateCookFunction(markdownOptions).then(cook => {
this._cachedCookFunction = cook;
return cook(text);
});
},
_updatePreview() {
if (this._state !== "inDOM") {
return;
}
const value = this.value;
const markdownOptions = this.markdownOptions || {};
cookAsync(value, markdownOptions).then(cooked => {
this.cachedCookAsync(value).then(cooked => {
if (this.isDestroyed) {
return;
}

View File

@ -38,6 +38,15 @@ export function cookAsync(text, options) {
return loadMarkdownIt().then(() => cook(text, options));
}
// Warm up pretty text with a set of options and return a function
// which can be used to cook without rebuilding prettytext every time
export function generateCookFunction(options) {
return loadMarkdownIt().then(() => {
const prettyText = createPrettyText(options);
return text => prettyText.cook(text);
});
}
export function sanitize(text, options) {
return textSanitize(text, new WhiteLister(options));
}