From d73c00799bcb3d7cccf69e6ad6c16b9719da66cb Mon Sep 17 00:00:00 2001 From: Frederic <1665799+Finomosec@users.noreply.github.com> Date: Mon, 20 Jul 2026 23:03:53 +0200 Subject: [PATCH] chore(gui): lazy-render collapsed panels to reduce watcher count (#10772) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a `lazyCollapse` directive that renders panel body content only while expanded. Collapsed panels contribute zero watchers — content is added to the DOM on expand (`show.bs.collapse`) and removed after the collapse animation completes (`hidden.bs.collapse`). Signed-off-by: Finomosec <1665799+Finomosec@users.noreply.github.com> --- gui/default/index.html | 13 +++++----- .../syncthing/core/lazyCollapseDirective.js | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 gui/default/syncthing/core/lazyCollapseDirective.js diff --git a/gui/default/index.html b/gui/default/index.html index e3e573c9a..5cff97159 100644 --- a/gui/default/index.html +++ b/gui/default/index.html @@ -410,8 +410,8 @@ -
-
+
+
@@ -686,8 +686,8 @@
{{deviceName(deviceCfg)}}
-
-
+
+
@@ -805,8 +805,8 @@
{{deviceName(deviceCfg)}}
-
-
+
+
@@ -1083,6 +1083,7 @@ + diff --git a/gui/default/syncthing/core/lazyCollapseDirective.js b/gui/default/syncthing/core/lazyCollapseDirective.js new file mode 100644 index 000000000..56a81a256 --- /dev/null +++ b/gui/default/syncthing/core/lazyCollapseDirective.js @@ -0,0 +1,25 @@ +angular.module('syncthing.core') + .directive('lazyCollapse', function () { + return { + restrict: 'A', + link: function (scope, element) { + // Render panel content only while expanded. Collapsed panels + // contribute zero watchers. Bootstrap's show/hidden events + // fire before/after the animation, so the DOM is present + // during the transition. + scope.lazyReady = element.hasClass('in'); + + $(element).on('show.bs.collapse', function () { + scope.$apply(function () { + scope.lazyReady = true; + }); + }); + + $(element).on('hidden.bs.collapse', function () { + scope.$apply(function () { + scope.lazyReady = false; + }); + }); + } + }; + });