mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 10:01:59 +08:00
perf(many): reduce delay when performing overlay or page transitions (#26189)
resolves #24346
This commit is contained in:
@ -271,7 +271,6 @@ export class StackController {
|
||||
|
||||
if ((containerEl as any).commit) {
|
||||
return containerEl.commit(enteringEl, leavingEl, {
|
||||
deepWait: true,
|
||||
duration: direction === undefined ? 0 : undefined,
|
||||
direction,
|
||||
showGoBack,
|
||||
|
@ -17,7 +17,7 @@ import type {
|
||||
} from '../../interface';
|
||||
import { findIonContent, printIonContentErrorMsg } from '../../utils/content';
|
||||
import { CoreDelegate, attachComponent, detachComponent } from '../../utils/framework-delegate';
|
||||
import { raf, inheritAttributes } from '../../utils/helpers';
|
||||
import { raf, inheritAttributes, hasLazyBuild } from '../../utils/helpers';
|
||||
import type { Attributes } from '../../utils/helpers';
|
||||
import { KEYBOARD_DID_OPEN } from '../../utils/keyboard/keyboard';
|
||||
import { printIonWarning } from '../../utils/logging';
|
||||
@ -436,7 +436,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
return;
|
||||
}
|
||||
|
||||
const { presentingElement } = this;
|
||||
const { presentingElement, el } = this;
|
||||
|
||||
/**
|
||||
* When using an inline modal
|
||||
@ -462,9 +462,8 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
};
|
||||
|
||||
const { inline, delegate } = this.getDelegate(true);
|
||||
this.usersElement = await attachComponent(delegate, this.el, this.component, ['ion-page'], data, inline);
|
||||
|
||||
await deepReady(this.usersElement);
|
||||
this.usersElement = await attachComponent(delegate, el, this.component, ['ion-page'], data, inline);
|
||||
hasLazyBuild(el) && (await deepReady(this.usersElement));
|
||||
|
||||
writeTask(() => this.el.classList.add('show-modal'));
|
||||
|
||||
|
@ -16,7 +16,7 @@ import type {
|
||||
TriggerAction,
|
||||
} from '../../interface';
|
||||
import { CoreDelegate, attachComponent, detachComponent } from '../../utils/framework-delegate';
|
||||
import { addEventListener, raf } from '../../utils/helpers';
|
||||
import { addEventListener, raf, hasLazyBuild } from '../../utils/helpers';
|
||||
import { BACKDROP, dismiss, eventMethod, focusFirstDescendant, prepareOverlay, present } from '../../utils/overlays';
|
||||
import { isPlatform } from '../../utils/platform';
|
||||
import { getClassMap } from '../../utils/theme';
|
||||
@ -431,14 +431,16 @@ export class Popover implements ComponentInterface, PopoverInterface {
|
||||
await this.currentTransition;
|
||||
}
|
||||
|
||||
const { el } = this;
|
||||
|
||||
const data = {
|
||||
...this.componentProps,
|
||||
popover: this.el,
|
||||
};
|
||||
|
||||
const { inline, delegate } = this.getDelegate(true);
|
||||
this.usersElement = await attachComponent(delegate, this.el, this.component, ['popover-viewport'], data, inline);
|
||||
await deepReady(this.usersElement);
|
||||
this.usersElement = await attachComponent(delegate, el, this.component, ['popover-viewport'], data, inline);
|
||||
hasLazyBuild(el) && (await deepReady(this.usersElement));
|
||||
|
||||
if (!this.keyboardEvents) {
|
||||
this.configureKeyboardInteraction();
|
||||
|
@ -19,7 +19,7 @@ import type {
|
||||
} from '../../interface';
|
||||
import { getTimeGivenProgression } from '../../utils/animation/cubic-bezier';
|
||||
import { attachComponent, detachComponent } from '../../utils/framework-delegate';
|
||||
import { shallowEqualStringMap } from '../../utils/helpers';
|
||||
import { shallowEqualStringMap, hasLazyBuild } from '../../utils/helpers';
|
||||
import { transition } from '../../utils/transition';
|
||||
|
||||
@Component({
|
||||
@ -238,6 +238,13 @@ export class RouterOutlet implements ComponentInterface, NavOutlet {
|
||||
enteringEl,
|
||||
leavingEl,
|
||||
baseEl: el,
|
||||
|
||||
/**
|
||||
* We need to wait for all Stencil components
|
||||
* to be ready only when using the lazy
|
||||
* loaded bundle.
|
||||
*/
|
||||
deepWait: hasLazyBuild(el),
|
||||
progressCallback: opts.progressAnimation
|
||||
? (ani) => {
|
||||
/**
|
||||
|
@ -76,6 +76,15 @@ export const componentOnReady = (el: any, callback: any) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This functions checks if a Stencil component is using
|
||||
* the lazy loaded build of Stencil. Returns `true` if
|
||||
* the component is lazy loaded. Returns `false` otherwise.
|
||||
*/
|
||||
export const hasLazyBuild = (stencilEl: HTMLElement) => {
|
||||
return (stencilEl as any).componentOnReady !== undefined;
|
||||
};
|
||||
|
||||
export type Attributes = { [key: string]: any };
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
LIFECYCLE_WILL_LEAVE,
|
||||
} from '../../components/nav/constants';
|
||||
import type { Animation, AnimationBuilder, NavDirection, NavOptions } from '../../interface';
|
||||
import { componentOnReady, raf } from '../helpers';
|
||||
import { raf } from '../helpers';
|
||||
|
||||
const iosTransitionAnimation = () => import('./ios.transition');
|
||||
const mdTransitionAnimation = () => import('./md.transition');
|
||||
@ -135,11 +135,11 @@ const noAnimation = async (opts: TransitionOptions): Promise<TransitionResult> =
|
||||
|
||||
const waitForReady = async (opts: TransitionOptions, defaultDeep: boolean) => {
|
||||
const deep = opts.deepWait !== undefined ? opts.deepWait : defaultDeep;
|
||||
const promises = deep
|
||||
? [deepReady(opts.enteringEl), deepReady(opts.leavingEl)]
|
||||
: [shallowReady(opts.enteringEl), shallowReady(opts.leavingEl)];
|
||||
|
||||
await Promise.all(promises);
|
||||
if (deep) {
|
||||
await Promise.all([deepReady(opts.enteringEl), deepReady(opts.leavingEl)]);
|
||||
}
|
||||
|
||||
await notifyViewReady(opts.viewIsReady, opts.enteringEl);
|
||||
};
|
||||
|
||||
@ -195,13 +195,6 @@ export const lifecycle = (el: HTMLElement | undefined, eventName: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
const shallowReady = (el: Element | undefined): Promise<any> => {
|
||||
if (el) {
|
||||
return new Promise((resolve) => componentOnReady(el, resolve));
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const deepReady = async (el: any | undefined): Promise<void> => {
|
||||
const element = el as any;
|
||||
if (element) {
|
||||
|
@ -365,7 +365,6 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
}
|
||||
|
||||
await routerOutlet.commit(enteringEl, leavingEl, {
|
||||
deepWait: true,
|
||||
duration: skipTransition || directionToUse === undefined ? 0 : undefined,
|
||||
direction: directionToUse,
|
||||
showGoBack: !!routeInfo.pushedByRoute,
|
||||
|
@ -195,7 +195,7 @@ export const IonRouterOutlet = /*@__PURE__*/ defineComponent({
|
||||
}
|
||||
});
|
||||
|
||||
const transition = (
|
||||
const transition = async (
|
||||
enteringEl: HTMLElement,
|
||||
leavingEl: HTMLElement,
|
||||
direction: any, // TODO types
|
||||
@ -203,23 +203,19 @@ export const IonRouterOutlet = /*@__PURE__*/ defineComponent({
|
||||
progressAnimation: boolean,
|
||||
animationBuilder?: AnimationBuilder
|
||||
) => {
|
||||
return new Promise(resolve => {
|
||||
if (skipTransition) {
|
||||
skipTransition = false;
|
||||
return resolve(false);
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
if (enteringEl === leavingEl) {
|
||||
return resolve(false);
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(async () => {
|
||||
enteringEl.classList.add('ion-page-invisible');
|
||||
|
||||
const hasRootDirection = direction === undefined || direction === 'root' || direction === 'none';
|
||||
const result = await ionRouterOutlet.value.commit(enteringEl, leavingEl, {
|
||||
deepWait: true,
|
||||
/**
|
||||
* replace operations result in a direction of none.
|
||||
* These typically do not have need animations, so we set
|
||||
@ -235,10 +231,7 @@ export const IonRouterOutlet = /*@__PURE__*/ defineComponent({
|
||||
animationBuilder
|
||||
});
|
||||
|
||||
return resolve(result);
|
||||
});
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
const handlePageTransition = async () => {
|
||||
|
Reference in New Issue
Block a user