PERF: Refactor lightbox decorator to use querySelectorAll (#10158)

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.

diff --git a/app/assets/javascripts/discourse/app/components/image-uploader.js b/app/assets/javascripts/discourse/app/components/image-uploader.js
index 48a8855..5285d5b 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 35504de..7b7d543 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 3f16b7f..a22b8fc 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")
+            );
           }
         },
+        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(
-                '<a class="image-source-link" href="' +
-                  href +
-                  '">' +
-                  renderIcon("string", "download") +
-                  I18n.t("lightbox.download") +
-                  "</a>"
-              );
-            }
-            return src.join(" &middot; ");
+      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(
+              '<a class="image-source-link" href="' +
+                href +
+                '">' +
+                renderIcon("string", "download") +
+                I18n.t("lightbox.download") +
+                "</a>"
+            );
           }
+          return src.join(" &middot; ");
         }
-      });
+      }
+    });
   });
 }

GitHub sha: 95153356

This commit appears in #10158 which was approved by ZogStriP. It was merged by davidtaylorhq.