From df6fedfc39918855a2e96932bda4f623f540b615 Mon Sep 17 00:00:00 2001 From: zhongnan Date: Sat, 8 Aug 2020 23:18:45 +0800 Subject: [PATCH] refactor(transition): refactor requestAnimationFrame with selectorQuery to improve performance fix #3133, fix #3120, fix #2636, fix #3441, fix #3434, fix #3455 --- packages/common/utils.ts | 16 ++++++++ packages/mixins/transition.ts | 70 +++++++++++++++-------------------- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/packages/common/utils.ts b/packages/common/utils.ts index 404a23b5b..cb53ccfd6 100644 --- a/packages/common/utils.ts +++ b/packages/common/utils.ts @@ -38,3 +38,19 @@ export function addUnit(value?: string | number): string | undefined { value = String(value); return isNumber(value) ? `${value}px` : value; } + +export function requestAnimationFrame(cb: Function) { + const systemInfo = getSystemInfoSync(); + + if (systemInfo.platform === 'devtools') { + return nextTick(cb); + } + + return wx + .createSelectorQuery() + .selectViewport() + .boundingClientRect() + .exec(() => { + cb(); + }); +} diff --git a/packages/mixins/transition.ts b/packages/mixins/transition.ts index 00c3c7e48..edb79ad28 100644 --- a/packages/mixins/transition.ts +++ b/packages/mixins/transition.ts @@ -1,4 +1,4 @@ -import { isObj } from '../common/utils'; +import { isObj, requestAnimationFrame } from '../common/utils'; const getClassNames = (name: string) => ({ enter: `van-${name}-enter van-${name}-enter-active enter-class enter-active-class`, @@ -7,8 +7,6 @@ const getClassNames = (name: string) => ({ 'leave-to': `van-${name}-leave-to van-${name}-leave-active leave-to-class leave-active-class`, }); -const nextTick = () => new Promise((resolve) => setTimeout(resolve, 1000 / 30)); - export const transition = function (showDefaultValue: boolean) { return Behavior({ properties: { @@ -53,29 +51,24 @@ export const transition = function (showDefaultValue: boolean) { this.status = 'enter'; this.$emit('before-enter'); - Promise.resolve() - .then(nextTick) - .then(() => { - this.checkStatus('enter'); - this.$emit('enter'); - - this.setData({ - inited: true, - display: true, - classes: classNames.enter, - currentDuration, - }); - }) - .then(nextTick) - .then(() => { + requestAnimationFrame(() => { + this.checkStatus('enter'); + this.$emit('enter'); + + this.setData({ + inited: true, + display: true, + classes: classNames.enter, + currentDuration, + }); + + requestAnimationFrame(() => { this.checkStatus('enter'); this.transitionEnded = false; - this.setData({ - classes: classNames['enter-to'], - }); - }) - .catch(() => {}); + this.setData({ classes: classNames['enter-to'] }); + }); + }); }, leave() { @@ -90,28 +83,23 @@ export const transition = function (showDefaultValue: boolean) { this.status = 'leave'; this.$emit('before-leave'); - Promise.resolve() - .then(nextTick) - .then(() => { - this.checkStatus('leave'); - this.$emit('leave'); - - this.setData({ - classes: classNames.leave, - currentDuration, - }); - }) - .then(nextTick) - .then(() => { + requestAnimationFrame(() => { + this.checkStatus('leave'); + this.$emit('leave'); + + this.setData({ + classes: classNames.leave, + currentDuration, + }); + + requestAnimationFrame(() => { this.checkStatus('leave'); this.transitionEnded = false; setTimeout(() => this.onTransitionEnd(), currentDuration); - this.setData({ - classes: classNames['leave-to'], - }); - }) - .catch(() => {}); + this.setData({ classes: classNames['leave-to'] }); + }); + }); }, checkStatus(status: 'enter' | 'leave') {