From 95153356ea4fda87d36ee1b207f39fb35314dd27 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 2 Jul 2020 11:04:19 +0100 Subject: [PATCH] PERF: Refactor lightbox decorator to use querySelectorAll (#10158) Previously we were using `$elem.find(...).not($elem.find(...))`. This took approximately 2ms on my machine with a test post. This commit switches to using a native querySelectorAll method, which takes less than 0.5ms on the same test post. --- .../app/components/image-uploader.js | 2 +- .../app/initializers/post-decorations.js | 2 +- .../javascripts/discourse/app/lib/lightbox.js | 148 +++++++++--------- 3 files changed, 75 insertions(+), 77 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/image-uploader.js b/app/assets/javascripts/discourse/app/components/image-uploader.js index 48a8855889a..5285d5bef51 100644 --- a/app/assets/javascripts/discourse/app/components/image-uploader.js +++ b/app/assets/javascripts/discourse/app/components/image-uploader.js @@ -86,7 +86,7 @@ export default Component.extend(UploadMixin, { }, _applyLightbox() { - if (this.imageUrl) next(() => lightbox($(this.element))); + if (this.imageUrl) next(() => lightbox(this.element)); }, actions: { diff --git a/app/assets/javascripts/discourse/app/initializers/post-decorations.js b/app/assets/javascripts/discourse/app/initializers/post-decorations.js index 35504de3bbe..7b7d543aa87 100644 --- a/app/assets/javascripts/discourse/app/initializers/post-decorations.js +++ b/app/assets/javascripts/discourse/app/initializers/post-decorations.js @@ -12,7 +12,7 @@ export default { api.decorateCooked(highlightSyntax, { id: "discourse-syntax-highlighting" }); - api.decorateCooked(lightbox, { id: "discourse-lightbox" }); + api.decorateCookedElement(lightbox, { id: "discourse-lightbox" }); if (siteSettings.support_mixed_text_direction) { api.decorateCooked(setTextDirections, { id: "discourse-text-direction" diff --git a/app/assets/javascripts/discourse/app/lib/lightbox.js b/app/assets/javascripts/discourse/app/lib/lightbox.js index 3f16b7f423f..a22b8fc429b 100644 --- a/app/assets/javascripts/discourse/app/lib/lightbox.js +++ b/app/assets/javascripts/discourse/app/lib/lightbox.js @@ -6,93 +6,91 @@ import { isAppWebview, postRNWebviewMessage } from "discourse/lib/utilities"; import { spinnerHTML } from "discourse/helpers/loading-spinner"; import User from "discourse/models/user"; -export default function($elem) { - if (!$elem) { +export default function(elem) { + if (!elem) { return; } loadScript("/javascripts/jquery.magnific-popup.min.js").then(function() { - const spoilers = $elem.find(".spoiler a.lightbox, .spoiled a.lightbox"); + const lightboxes = elem.querySelectorAll( + "*:not(.spoiler):not(.spoiled) a.lightbox" + ); + $(lightboxes).magnificPopup({ + type: "image", + closeOnContentClick: false, + removalDelay: 300, + mainClass: "mfp-zoom-in", + tClose: I18n.t("lightbox.close"), + tLoading: spinnerHTML, - $elem - .find("a.lightbox") - .not(spoilers) - .magnificPopup({ - type: "image", - closeOnContentClick: false, - removalDelay: 300, - mainClass: "mfp-zoom-in", - tClose: I18n.t("lightbox.close"), - tLoading: spinnerHTML, + gallery: { + enabled: true, + tPrev: I18n.t("lightbox.previous"), + tNext: I18n.t("lightbox.next"), + tCounter: I18n.t("lightbox.counter") + }, - gallery: { - enabled: true, - tPrev: I18n.t("lightbox.previous"), - tNext: I18n.t("lightbox.next"), - tCounter: I18n.t("lightbox.counter") - }, + ajax: { + tError: I18n.t("lightbox.content_load_error") + }, - ajax: { - tError: I18n.t("lightbox.content_load_error") - }, + callbacks: { + open() { + const wrap = this.wrap, + img = this.currItem.img, + maxHeight = img.css("max-height"); - callbacks: { - open() { - const wrap = this.wrap, - img = this.currItem.img, - maxHeight = img.css("max-height"); + wrap.on("click.pinhandler", "img", function() { + wrap.toggleClass("mfp-force-scrollbars"); + img.css( + "max-height", + wrap.hasClass("mfp-force-scrollbars") ? "none" : maxHeight + ); + }); - wrap.on("click.pinhandler", "img", function() { - wrap.toggleClass("mfp-force-scrollbars"); - img.css( - "max-height", - wrap.hasClass("mfp-force-scrollbars") ? "none" : maxHeight - ); - }); - - if (isAppWebview()) { - postRNWebviewMessage( - "headerBg", - $(".mfp-bg").css("background-color") - ); - } - }, - beforeClose() { - this.wrap.off("click.pinhandler"); - this.wrap.removeClass("mfp-force-scrollbars"); - if (isAppWebview()) { - postRNWebviewMessage( - "headerBg", - $(".d-header").css("background-color") - ); - } + if (isAppWebview()) { + postRNWebviewMessage( + "headerBg", + $(".mfp-bg").css("background-color") + ); } }, - - image: { - tError: I18n.t("lightbox.image_load_error"), - titleSrc(item) { - const href = item.el.data("download-href") || item.src; - let src = [ - escapeExpression(item.el.attr("title")), - $("span.informations", item.el).text() - ]; - if ( - !Discourse.SiteSettings.prevent_anons_from_downloading_files || - User.current() - ) { - src.push( - '' + - renderIcon("string", "download") + - I18n.t("lightbox.download") + - "" - ); - } - return src.join(" · "); + beforeClose() { + this.wrap.off("click.pinhandler"); + this.wrap.removeClass("mfp-force-scrollbars"); + if (isAppWebview()) { + postRNWebviewMessage( + "headerBg", + $(".d-header").css("background-color") + ); } } - }); + }, + + image: { + tError: I18n.t("lightbox.image_load_error"), + titleSrc(item) { + const href = item.el.data("download-href") || item.src; + let src = [ + escapeExpression(item.el.attr("title")), + $("span.informations", item.el).text() + ]; + if ( + !Discourse.SiteSettings.prevent_anons_from_downloading_files || + User.current() + ) { + src.push( + '' + + renderIcon("string", "download") + + I18n.t("lightbox.download") + + "" + ); + } + return src.join(" · "); + } + } + }); }); }