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 {DOCUMENT} from '@angular/common';
|
||||||
import {
|
import {afterNextRender, InjectionToken, Injector, runInInjectionContext} from '@angular/core';
|
||||||
afterNextRender,
|
|
||||||
InjectionToken,
|
|
||||||
Injector,
|
|
||||||
NgZone,
|
|
||||||
runInInjectionContext,
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import {ActivatedRouteSnapshot} from '../router_state';
|
import {ActivatedRouteSnapshot} from '../router_state';
|
||||||
|
|
||||||
@@ -83,33 +77,31 @@ export function createViewTransition(
|
|||||||
const transitionOptions = injector.get(VIEW_TRANSITION_OPTIONS);
|
const transitionOptions = injector.get(VIEW_TRANSITION_OPTIONS);
|
||||||
const document = injector.get(DOCUMENT);
|
const document = injector.get(DOCUMENT);
|
||||||
// Create promises outside the Angular zone to avoid causing extra change detections
|
// Create promises outside the Angular zone to avoid causing extra change detections
|
||||||
return injector.get(NgZone).runOutsideAngular(() => {
|
if (!document.startViewTransition || transitionOptions.skipNextTransition) {
|
||||||
if (!document.startViewTransition || transitionOptions.skipNextTransition) {
|
transitionOptions.skipNextTransition = false;
|
||||||
transitionOptions.skipNextTransition = false;
|
// The timing of `startViewTransition` is closer to a macrotask. It won't be called
|
||||||
// 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
|
||||||
// until the current event loop exits so we use a promise resolved in a timeout instead
|
// of Promise.resolve().
|
||||||
// of Promise.resolve().
|
return new Promise((resolve) => setTimeout(resolve));
|
||||||
return new Promise((resolve) => setTimeout(resolve));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let resolveViewTransitionStarted: () => void;
|
let resolveViewTransitionStarted: () => void;
|
||||||
const viewTransitionStarted = new Promise<void>((resolve) => {
|
const viewTransitionStarted = new Promise<void>((resolve) => {
|
||||||
resolveViewTransitionStarted = 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;
|
|
||||||
});
|
});
|
||||||
|
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