From d23c0c06c380045370c2f117fd27424a459956ba Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Wed, 4 Aug 2021 08:27:22 +0200 Subject: [PATCH] PERF: reduces rendering time of local-dates (#13931) - prefers insertAdjacentHTML over innerHTML as it's much faster in this case (about 5x) - memoizes tz.guess() - memoizes list of timezones - inlines template - applies main element class in one pass All in all for a very edge case of about 80 dates it should be faster of about 15/20ms. --- .../initializers/discourse-local-dates.js.es6 | 32 ++++++++++--------- .../discourse-local-dates.js.es6 | 8 +++-- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/plugins/discourse-local-dates/assets/javascripts/initializers/discourse-local-dates.js.es6 b/plugins/discourse-local-dates/assets/javascripts/initializers/discourse-local-dates.js.es6 index c4633d1f85d..53d8d04dcc4 100644 --- a/plugins/discourse-local-dates/assets/javascripts/initializers/discourse-local-dates.js.es6 +++ b/plugins/discourse-local-dates/assets/javascripts/initializers/discourse-local-dates.js.es6 @@ -2,15 +2,6 @@ import LocalDateBuilder from "../lib/local-date-builder"; import showModal from "discourse/lib/show-modal"; import { withPluginApi } from "discourse/lib/plugin-api"; -const DATE_TEMPLATE = ` - - - - - - -`; - function initializeDiscourseLocalDates(api) { api.decorateCooked( ($elem) => $(".discourse-local-date", $elem).applyLocalDates(), @@ -45,6 +36,8 @@ export default { initialize(container) { const siteSettings = container.lookup("site-settings:main"); if (siteSettings.discourse_local_dates_enabled) { + const currentUserTZ = moment.tz.guess(); + $.fn.applyLocalDates = function () { return this.each(function () { const opts = {}; @@ -67,7 +60,7 @@ export default { const localDateBuilder = new LocalDateBuilder( opts, - moment.tz.guess() + currentUserTZ ).build(); const htmlPreviews = localDateBuilder.previews.map((preview) => { @@ -96,15 +89,24 @@ export default { previewsNode.appendChild(htmlPreview) ); - this.innerHTML = DATE_TEMPLATE; + this.innerText = ""; + this.insertAdjacentHTML( + "beforeend", + ` + + + + ${localDateBuilder.formated} + ` + ); this.setAttribute("aria-label", localDateBuilder.textPreview); this.dataset.htmlTooltip = previewsNode.outerHTML; - this.classList.add("cooked-date"); + + const classes = ["cooked-date"]; if (localDateBuilder.pastEvent) { - this.classList.add("past"); + classes.push("past"); } - const relativeTime = this.querySelector(".relative-time"); - relativeTime.innerText = localDateBuilder.formated; + this.classList.add(...classes); }); }; diff --git a/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6 b/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6 index 09eba6c2535..69ecd7f75a4 100644 --- a/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6 +++ b/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6 @@ -1,5 +1,7 @@ import { parseBBCodeTag } from "pretty-text/engines/discourse-markdown/bbcode-block"; +const timezoneNames = moment.tz.names(); + function addLocalDate(buffer, matches, state) { let token; @@ -77,7 +79,7 @@ function addLocalDate(buffer, matches, state) { if ( config.displayedTimezone && - moment.tz.names().includes(config.displayedTimezone) + timezoneNames.includes(config.displayedTimezone) ) { token.attrs.push([ "data-displayed-timezone", @@ -87,7 +89,7 @@ function addLocalDate(buffer, matches, state) { if (config.timezones) { const timezones = config.timezones.split("|").filter((timezone) => { - return moment.tz.names().includes(timezone); + return timezoneNames.includes(timezone); }); token.attrs.push([ @@ -96,7 +98,7 @@ function addLocalDate(buffer, matches, state) { ]); } - if (config.timezone && moment.tz.names().includes(config.timezone)) { + if (config.timezone && timezoneNames.includes(config.timezone)) { token.attrs.push([ "data-timezone", state.md.utils.escapeHtml(config.timezone),