From b5298c11ab829cf9430237a91944e4fef1a1e8c8 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Mon, 18 May 2020 23:55:02 +0800 Subject: [PATCH 01/11] refactor(util/dom/getScrollParent): use cache --- src/_mixins/placeable.js | 3 +-- src/_utils/dom/getScrollParent.js | 41 ++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/_mixins/placeable.js b/src/_mixins/placeable.js index f579553ea..d130e331b 100644 --- a/src/_mixins/placeable.js +++ b/src/_mixins/placeable.js @@ -296,12 +296,11 @@ export default { resizeDelegate.registerHandler(this.updatePosition) }, registerScrollListeners () { - let currentElement = getParentNode(this._getTrackedElement()) + let currentElement = this._getTrackedElement() while (true) { currentElement = getScrollParent(currentElement) if (currentElement === null) break this.scrollListeners.push([currentElement, this.updatePosition]) - currentElement = getParentNode(currentElement) } for (const [el, handler] of this.scrollListeners) { scrollDelegate.registerHandler(el, handler) diff --git a/src/_utils/dom/getScrollParent.js b/src/_utils/dom/getScrollParent.js index feec6f500..aeac7f572 100644 --- a/src/_utils/dom/getScrollParent.js +++ b/src/_utils/dom/getScrollParent.js @@ -1,6 +1,31 @@ import getStyleComputedProperty from './getStyleComputedProperty' import getParentNode from './getParentNode' +const NOT_FOUND = 'NOT_FOUND' +const CACHE_DURATION = 3000 + +const scrollNodeCache = { + cache: new Map(), + read (node) { + if (this.cache.has(node)) { + return this.cache.get(node) + } else { + return NOT_FOUND + } + }, + remove (node) { + this.cache.delete(node) + }, + write (node, scrollParentNode) { + if (!this.cache.has(node)) { + this.cache.set(node, scrollParentNode) + window.setTimeout(() => { + this.remove(node) + }, CACHE_DURATION) + } + } +} + /** * Returns the scrolling parent of the given element * @method @@ -8,6 +33,17 @@ import getParentNode from './getParentNode' * @returns {Element|null} scroll parent */ export default function getScrollParent (element) { + const startElement = getParentNode(element) + return getScrollElementFrom(startElement) +} + +function getScrollElementFrom (element) { + const cachedNode = scrollNodeCache.read(element) + if (cachedNode !== NOT_FOUND) { + console.log('read from cache') + return cachedNode + } + // Return body, `getScroll` will take care to get the correct `scrollTop` from it if (!element) { return null @@ -24,8 +60,11 @@ export default function getScrollParent (element) { // Firefox want us to check `-x` and `-y` variations as well const { overflow, overflowX, overflowY } = getStyleComputedProperty(element) if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { + scrollNodeCache.write(element, element) return element } - return getScrollParent(getParentNode(element)) + const scrollElement = getScrollElementFrom(getParentNode(element)) + scrollNodeCache.write(element, scrollElement) + return scrollElement } From 0b07c0caf92b9fd80229d6437c705629265b5f84 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Mon, 18 May 2020 23:56:24 +0800 Subject: [PATCH 02/11] perf(button): add guard for clearTimeout in beforeDestroy hook --- src/Button/src/Button.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Button/src/Button.vue b/src/Button/src/Button.vue index 37d0444d6..1d9d2f4bb 100644 --- a/src/Button/src/Button.vue +++ b/src/Button/src/Button.vue @@ -301,7 +301,10 @@ export default { if (colorHash) { unmountColorStyle(colorHash) } - window.clearTimeout(this.rippleTimer) + const rippleTimer = this.rippleTimer + if (rippleTimer !== null) { + window.clearTimeout(rippleTimer) + } }, methods: { handleMouseDown (e) { From 61ea1063bbed88f72815c0b922d688c410ea1639 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Mon, 18 May 2020 23:57:12 +0800 Subject: [PATCH 03/11] perf(avatar): add guard for text adjusting --- src/Avatar/src/main.vue | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Avatar/src/main.vue b/src/Avatar/src/main.vue index 4c14993d3..455232b21 100644 --- a/src/Avatar/src/main.vue +++ b/src/Avatar/src/main.vue @@ -60,7 +60,8 @@ export default { }, data () { return { - ratio: 1 + ratio: 1, + memorizedTextHTML: null } }, computed: { @@ -90,14 +91,20 @@ export default { }, methods: { adjustText () { - if (this.$refs.text) { - const elWidth = this.$el.offsetWidth - const textWidth = this.$refs.text.offsetWidth - const elHeight = this.$el.offsetHeight - const textHeight = this.$refs.text.offsetHeight - const radix = (this.circle || this.round) ? 0.75 : 0.85 - const ratio = Math.min(elWidth / textWidth * radix, elHeight / textHeight * radix) - this.ratio = Math.min(1, ratio) + const textEl = this.$refs.text + if (textEl) { + const memorizedTextHTML = this.memorizedTextHTML + if (memorizedTextHTML === null || memorizedTextHTML !== textEl.innerHTML) { + this.memorizedTextHTML = textEl.innerHTML + const selfEl = this.$el + const elWidth = selfEl.offsetWidth + const textWidth = textEl.offsetWidth + const elHeight = selfEl.offsetHeight + const textHeight = textEl.offsetHeight + const radix = (this.circle || this.round) ? 0.75 : 0.85 + const ratio = Math.min(elWidth / textWidth * radix, elHeight / textHeight * radix) + this.ratio = Math.min(1, ratio) + } } } } From bd0584f319b54f2389ae26ca0b94a428e0235dfd Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Tue, 19 May 2020 00:10:51 +0800 Subject: [PATCH 04/11] perf(mixin/placeable): register listeners on demand --- src/_mixins/placeable.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/_mixins/placeable.js b/src/_mixins/placeable.js index d130e331b..b5d6839d3 100644 --- a/src/_mixins/placeable.js +++ b/src/_mixins/placeable.js @@ -1,6 +1,5 @@ import scrollDelegate from '../_utils/delegate/scrollDelegate' import resizeDelegate from '../_utils/delegate/resizeDelegate' -import getParentNode from '../_utils/dom/getParentNode' import getScrollParent from '../_utils/dom/getScrollParent' import { getAdjustedPlacementOfTrackingElement, @@ -169,6 +168,11 @@ export default { watch: { active (value) { if (value) { + if (this.listenersRegistered) { + this.registerScrollListeners() + this.registerResizeListener() + this.listenersRegistered = true + } this.$nextTick().then(this.updatePosition) } }, @@ -184,17 +188,23 @@ export default { trackingElement: null, trackedElement: null, scrollListeners: [], - adjustedPlacement: this.placement + adjustedPlacement: this.placement, + listenersRegistered: false } }, mounted () { - this.registerScrollListeners() - this.registerResizeListener() + if (this.active) { + this.registerScrollListeners() + this.registerResizeListener() + this.listenersRegistered = true + } this.updatePosition() }, beforeDestroy () { - this.unregisterScrollListeners() - this.unregisterResizeListener() + if (this.listenersRegistered) { + this.unregisterScrollListeners() + this.unregisterResizeListener() + } }, methods: { _getTrackingElement () { From 4f52a25308aaf45d68cdc3712cccd85c4ec14d7b Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Tue, 19 May 2020 00:13:17 +0800 Subject: [PATCH 05/11] chore: small fixes --- src/Anchor/src/BaseAnchor.vue | 4 ++-- src/_mixins/placeable.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Anchor/src/BaseAnchor.vue b/src/Anchor/src/BaseAnchor.vue index c13705ca5..ab9d2c20b 100644 --- a/src/Anchor/src/BaseAnchor.vue +++ b/src/Anchor/src/BaseAnchor.vue @@ -143,8 +143,8 @@ export default { slotEl.style.top = `${offsetTop}px` slotEl.style.height = `${offsetHeight}px` slotEl.style.maxWidth = `${offsetWidth + offsetLeft}px` - barEl.getBoundingClientRect() - slotEl.getBoundingClientRect() + void barEl.offsetHeight + void slotEl.offsetHeight if (!transition) { barEl.style.transition = null diff --git a/src/_mixins/placeable.js b/src/_mixins/placeable.js index b5d6839d3..bcc5be687 100644 --- a/src/_mixins/placeable.js +++ b/src/_mixins/placeable.js @@ -168,7 +168,7 @@ export default { watch: { active (value) { if (value) { - if (this.listenersRegistered) { + if (!this.listenersRegistered) { this.registerScrollListeners() this.registerResizeListener() this.listenersRegistered = true From 8f62d9bb3a761d2d29721e24a4a17624593be48e Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Tue, 19 May 2020 12:24:05 +0800 Subject: [PATCH 06/11] perf(anchor): avoid useless rerenders --- src/Anchor/src/Link.vue | 21 +++++++++++++++++---- src/Menu/src/MenuItem.vue | 4 ++-- src/_utils/dom/getScrollParent.js | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Anchor/src/Link.vue b/src/Anchor/src/Link.vue index badeeab57..c705e7725 100644 --- a/src/Anchor/src/Link.vue +++ b/src/Anchor/src/Link.vue @@ -19,6 +19,7 @@