mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(router): Remove unnecessary runOutsideAngular in view transition helper (#61068)
This refactor removes the unnecessary `runOutsideAngular` call in the view transition helper. The resolved promise re-enters the zone in the transition, so that will trigger the Angular zone anyways. If it didn't do that, it risks activated the route outside the zone, which is a bigger risk. Regardless, this function is only run once per navigation, so even if it _did_ result in an extra promise/timeout inside the zone, this is not excessive. Using ZoneJS to trigger rendering is known to overreact to events. Using `OnPush` or zoneless is more effective at mitigating this issue. PR Close #61068
This commit is contained in:
committed by
Andrew Kushnir
parent
4b84de7399
commit
b8f80ab2dc
@@ -7,13 +7,7 @@
|
||||
*/
|
||||
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {
|
||||
afterNextRender,
|
||||
InjectionToken,
|
||||
Injector,
|
||||
NgZone,
|
||||
runInInjectionContext,
|
||||
} from '@angular/core';
|
||||
import {afterNextRender, InjectionToken, Injector, runInInjectionContext} from '@angular/core';
|
||||
|
||||
import {ActivatedRouteSnapshot} from '../router_state';
|
||||
|
||||
@@ -83,33 +77,31 @@ export function createViewTransition(
|
||||
const transitionOptions = injector.get(VIEW_TRANSITION_OPTIONS);
|
||||
const document = injector.get(DOCUMENT);
|
||||
// Create promises outside the Angular zone to avoid causing extra change detections
|
||||
return injector.get(NgZone).runOutsideAngular(() => {
|
||||
if (!document.startViewTransition || transitionOptions.skipNextTransition) {
|
||||
transitionOptions.skipNextTransition = false;
|
||||
// The timing of `startViewTransition` is closer to a macrotask. It won't be called
|
||||
// until the current event loop exits so we use a promise resolved in a timeout instead
|
||||
// of Promise.resolve().
|
||||
return new Promise((resolve) => setTimeout(resolve));
|
||||
}
|
||||
if (!document.startViewTransition || transitionOptions.skipNextTransition) {
|
||||
transitionOptions.skipNextTransition = false;
|
||||
// The timing of `startViewTransition` is closer to a macrotask. It won't be called
|
||||
// until the current event loop exits so we use a promise resolved in a timeout instead
|
||||
// of Promise.resolve().
|
||||
return new Promise((resolve) => setTimeout(resolve));
|
||||
}
|
||||
|
||||
let resolveViewTransitionStarted: () => void;
|
||||
const viewTransitionStarted = new Promise<void>((resolve) => {
|
||||
resolveViewTransitionStarted = resolve;
|
||||
});
|
||||
const transition = document.startViewTransition(() => {
|
||||
resolveViewTransitionStarted();
|
||||
// We don't actually update dom within the transition callback. The resolving of the above
|
||||
// promise unblocks the Router navigation, which synchronously activates and deactivates
|
||||
// routes (the DOM update). This view transition waits for the next change detection to
|
||||
// complete (below), which includes the update phase of the routed components.
|
||||
return createRenderPromise(injector);
|
||||
});
|
||||
const {onViewTransitionCreated} = transitionOptions;
|
||||
if (onViewTransitionCreated) {
|
||||
runInInjectionContext(injector, () => onViewTransitionCreated({transition, from, to}));
|
||||
}
|
||||
return viewTransitionStarted;
|
||||
let resolveViewTransitionStarted: () => void;
|
||||
const viewTransitionStarted = new Promise<void>((resolve) => {
|
||||
resolveViewTransitionStarted = resolve;
|
||||
});
|
||||
const transition = document.startViewTransition(() => {
|
||||
resolveViewTransitionStarted();
|
||||
// We don't actually update dom within the transition callback. The resolving of the above
|
||||
// promise unblocks the Router navigation, which synchronously activates and deactivates
|
||||
// routes (the DOM update). This view transition waits for the next change detection to
|
||||
// complete (below), which includes the update phase of the routed components.
|
||||
return createRenderPromise(injector);
|
||||
});
|
||||
const {onViewTransitionCreated} = transitionOptions;
|
||||
if (onViewTransitionCreated) {
|
||||
runInInjectionContext(injector, () => onViewTransitionCreated({transition, from, to}));
|
||||
}
|
||||
return viewTransitionStarted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user