From 261754f18b8a5e6e6eedf39d6f6b143a752b0588 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 1 Apr 2019 23:35:12 +0200 Subject: list: do not use IntersectionObserver to reduce CPU usage Switch back to a custom spinner detection, as the IntersectionObserver is eating a lot of CPU resources on idle. This should also take care of #2250 properly: the previous `onDestroyed()` was removing the resize and scroll callbacks, but they were not unique enough, and they were shared across swimlanes. So if a list had 2 swimlanes with spinners, when one was removed, the other was not triggering its callbacks anymore. Related: #2294 --- client/components/lists/listBody.js | 50 ++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 112b6379..43619890 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -615,40 +615,50 @@ BlazeComponent.extendComponent({ BlazeComponent.extendComponent({ onCreated() { - this.spinnerShown = false; this.cardlimit = this.parentComponent().cardlimit; + + this.listId = this.parentComponent().data()._id; + this.swimlaneId = ''; + + const boardView = Meteor.user().profile.boardView; + if (boardView === 'board-view-swimlanes') + this.swimlaneId = this.parentComponent().parentComponent().parentComponent().data()._id; }, onRendered() { - const spinner = this.find('.sk-spinner-list'); - - if (spinner) { - const options = { - root: null, // we check if the spinner is on the current viewport - rootMargin: '0px', - threshold: 0.25, - }; - - this.observer = new IntersectionObserver((entries) => { - entries.forEach((entry) => { - this.spinnerShown = entry.isIntersecting; - this.updateList(); - }); - }, options); + this.spinner = this.find('.sk-spinner-list'); + this.container = this.$(this.spinner).parents('.js-perfect-scrollbar')[0]; - this.observer.observe(spinner); - } + $(this.container).on(`scroll.spinner_${this.swimlaneId}_${this.listId}`, () => this.updateList()); + $(window).on(`resize.spinner_${this.swimlaneId}_${this.listId}`, () => this.updateList()); + + this.updateList(); }, onDestroyed() { - this.observer.disconnect(); + $(this.container).off(`scroll.spinner_${this.swimlaneId}_${this.listId}`); + $(window).off(`resize.spinner_${this.swimlaneId}_${this.listId}`); }, updateList() { - if (this.spinnerShown) { + if (this.spinnerInView()) { this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter); window.requestIdleCallback(() => this.updateList()); } }, + spinnerInView() { + const parentViewHeight = this.container.clientHeight; + const bottomViewPosition = this.container.scrollTop + parentViewHeight; + + const threshold = this.spinner.offsetTop; + + // spinner deleted + if (!this.spinner.offsetTop) { + return false; + } + + return bottomViewPosition > threshold; + }, + }).register('spinnerList'); -- cgit v1.2.3-1-g7c22