From a3da0bbb849cb7425a2f0b94395f3ed5d0dabff3 Mon Sep 17 00:00:00 2001 From: Razvan Stoenescu Date: Wed, 11 Jan 2023 16:10:27 +0200 Subject: [PATCH] perf(QInfiniteScroll): (backport from Qv2) force stop all svg animations in the "loading" slot when slot is not on screen #15094 --- .../src/pages/components/infinite-scroll.vue | 8 ++-- .../infinite-scroll/QInfiniteScroll.js | 39 ++++++++++++++++++- ui/src/css/core/visibility.sass | 3 -- ui/src/css/core/visibility.styl | 3 -- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/ui/dev/src/pages/components/infinite-scroll.vue b/ui/dev/src/pages/components/infinite-scroll.vue index 3f7da73bcb9..00edfb4bf18 100644 --- a/ui/dev/src/pages/components/infinite-scroll.vue +++ b/ui/dev/src/pages/components/infinite-scroll.vue @@ -20,7 +20,7 @@
- +
@@ -38,7 +38,7 @@
- +
@@ -50,11 +50,11 @@ -
+
{{ itemsReverse.length - index }} diff --git a/ui/src/components/infinite-scroll/QInfiniteScroll.js b/ui/src/components/infinite-scroll/QInfiniteScroll.js index 486c925d146..fa2a5309f76 100644 --- a/ui/src/components/infinite-scroll/QInfiniteScroll.js +++ b/ui/src/components/infinite-scroll/QInfiniteScroll.js @@ -44,6 +44,12 @@ export default Vue.extend({ } }, + computed: { + renderLoadingSlot () { + return this.disable !== true && this.isWorking === true + } + }, + watch: { disable (val) { if (val === true) { this.stop() } @@ -62,6 +68,14 @@ export default Vue.extend({ debounce (val) { this.__setDebounce(val) + }, + + isFetching () { + this.__updateSvgAnimations() + }, + + renderLoadingSlot () { + this.__updateSvgAnimations() } }, @@ -183,14 +197,34 @@ export default Vue.extend({ this.__scrollTarget.addEventListener('scroll', this.poll, passive) } + }, + + __updateSvgAnimations (isRetry) { + if (this.renderLoadingSlot === true) { + const el = this.$refs.loading + + if (!el) { + isRetry !== true && this.$nextTick(() => { + this.__updateSvgAnimations(true) + }) + return + } + + // we need to pause svg animations (if any) when hiding + // otherwise the browser will keep on recalculating the style + const action = `${ this.isFetching === true ? 'un' : '' }pauseAnimations` + Array.from(el.getElementsByTagName('svg')).forEach(el => { + el[ action ]() + }) + } } }, mounted () { this.immediatePoll = this.poll this.__setDebounce(this.debounce) - this.updateScrollTarget() + this.isFetching === false && this.__updateSvgAnimations() }, activated () { @@ -212,9 +246,10 @@ export default Vue.extend({ render (h) { const child = uniqueSlot(this, 'default', []) - if (this.disable !== true && this.isWorking === true) { + if (this.renderLoadingSlot === true) { child[this.reverse === false ? 'push' : 'unshift']( h('div', { + ref: 'loading', staticClass: 'q-infinite-scroll__loading', class: this.isFetching === true ? '' : 'invisible' }, slot(this, 'loading')) diff --git a/ui/src/css/core/visibility.sass b/ui/src/css/core/visibility.sass index f6264defe7c..702433ce6ae 100644 --- a/ui/src/css/core/visibility.sass +++ b/ui/src/css/core/visibility.sass @@ -40,8 +40,6 @@ visibility: hidden !important transition: none !important animation: none !important -.invisible svg * - display: none .transparent background: transparent !important @@ -164,4 +162,3 @@ body.desktop .q-focusable:focus, .q-manual-focusable--focused > .q-focus-helper opacity: .22 - diff --git a/ui/src/css/core/visibility.styl b/ui/src/css/core/visibility.styl index e15428dd9fb..c711c830d50 100644 --- a/ui/src/css/core/visibility.styl +++ b/ui/src/css/core/visibility.styl @@ -40,8 +40,6 @@ visibility: hidden !important transition: none !important animation: none !important -.invisible svg * - display: none .transparent background: transparent !important @@ -163,4 +161,3 @@ body.desktop .q-focusable:focus, .q-manual-focusable--focused > .q-focus-helper opacity: .22 -