[Perf] Teact: Postpone rendering and effects during blocking animation (#4928)
This commit is contained in:
parent
e731712b74
commit
8e5236d102
@ -13,6 +13,7 @@ import {
|
|||||||
SCROLL_MAX_DURATION,
|
SCROLL_MAX_DURATION,
|
||||||
SERVICE_NOTIFICATIONS_USER_ID,
|
SERVICE_NOTIFICATIONS_USER_ID,
|
||||||
} from '../../../config';
|
} from '../../../config';
|
||||||
|
import { cancelScrollBlockingAnimation, isAnimatingScroll } from '../../../util/animateScroll';
|
||||||
import { copyHtmlToClipboard } from '../../../util/clipboard';
|
import { copyHtmlToClipboard } from '../../../util/clipboard';
|
||||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||||
import { compact, findLast } from '../../../util/iteratees';
|
import { compact, findLast } from '../../../util/iteratees';
|
||||||
@ -489,6 +490,10 @@ addActionHandler('focusMessage', (global, actions, payload): ActionReturnType =>
|
|||||||
global = updateFocusDirection(global, direction, tabId);
|
global = updateFocusDirection(global, direction, tabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isAnimatingScroll()) {
|
||||||
|
cancelScrollBlockingAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
setGlobal(global, { forceOnHeavyAnimation: true });
|
setGlobal(global, { forceOnHeavyAnimation: true });
|
||||||
|
|
||||||
actions.openThread({
|
actions.openThread({
|
||||||
|
|||||||
@ -5,18 +5,29 @@ import { requestMeasure } from '../fasterdom/fasterdom';
|
|||||||
const AUTO_END_TIMEOUT = 1000;
|
const AUTO_END_TIMEOUT = 1000;
|
||||||
|
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
let counterBlocking = 0;
|
||||||
|
|
||||||
const [getIsAnimating, setIsAnimating] = createSignal(false);
|
const [getIsAnimating, setIsAnimating] = createSignal(false);
|
||||||
|
const [getIsBlockingAnimating, setIsBlockingAnimating] = createSignal(false);
|
||||||
|
|
||||||
export const getIsHeavyAnimating = getIsAnimating;
|
export const getIsHeavyAnimating = getIsAnimating;
|
||||||
|
export { getIsBlockingAnimating };
|
||||||
|
|
||||||
export function beginHeavyAnimation(duration = AUTO_END_TIMEOUT) {
|
export function beginHeavyAnimation(duration = AUTO_END_TIMEOUT, isBlocking = false) {
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
if (counter === 1) {
|
if (counter === 1) {
|
||||||
setIsAnimating(true);
|
setIsAnimating(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isBlocking) {
|
||||||
|
counterBlocking++;
|
||||||
|
|
||||||
|
if (counterBlocking === 1) {
|
||||||
|
setIsBlockingAnimating(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const timeout = window.setTimeout(onEnd, duration);
|
const timeout = window.setTimeout(onEnd, duration);
|
||||||
|
|
||||||
let hasEnded = false;
|
let hasEnded = false;
|
||||||
@ -32,6 +43,14 @@ export function beginHeavyAnimation(duration = AUTO_END_TIMEOUT) {
|
|||||||
if (counter === 0) {
|
if (counter === 0) {
|
||||||
setIsAnimating(false);
|
setIsAnimating(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isBlocking) {
|
||||||
|
counterBlocking--;
|
||||||
|
|
||||||
|
if (counterBlocking === 0) {
|
||||||
|
setIsBlockingAnimating(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return onEnd;
|
return onEnd;
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import safeExec from '../../util/safeExec';
|
|||||||
import { throttleWith } from '../../util/schedulers';
|
import { throttleWith } from '../../util/schedulers';
|
||||||
import { createSignal, isSignal, type Signal } from '../../util/signals';
|
import { createSignal, isSignal, type Signal } from '../../util/signals';
|
||||||
import { requestMeasure, requestMutation } from '../fasterdom/fasterdom';
|
import { requestMeasure, requestMutation } from '../fasterdom/fasterdom';
|
||||||
|
import { getIsBlockingAnimating } from './heavyAnimation';
|
||||||
|
|
||||||
export { getIsHeavyAnimating, beginHeavyAnimation, onFullyIdle } from './heavyAnimation';
|
export { getIsHeavyAnimating, beginHeavyAnimation, onFullyIdle } from './heavyAnimation';
|
||||||
|
|
||||||
@ -329,6 +330,11 @@ let areImmediateEffectsCaptured = false;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const runUpdatePassOnRaf = throttleWith(requestMeasure, () => {
|
const runUpdatePassOnRaf = throttleWith(requestMeasure, () => {
|
||||||
|
if (getIsBlockingAnimating()) {
|
||||||
|
getIsBlockingAnimating.once(runUpdatePassOnRaf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const runImmediateEffects = captureImmediateEffects();
|
const runImmediateEffects = captureImmediateEffects();
|
||||||
|
|
||||||
idsToExcludeFromUpdate = new Set();
|
idsToExcludeFromUpdate = new Set();
|
||||||
|
|||||||
@ -127,7 +127,7 @@ function createMutateFunction(
|
|||||||
isAnimating = true;
|
isAnimating = true;
|
||||||
|
|
||||||
const prevOnHeavyAnimationEnd = onHeavyAnimationEnd;
|
const prevOnHeavyAnimationEnd = onHeavyAnimationEnd;
|
||||||
onHeavyAnimationEnd = beginHeavyAnimation();
|
onHeavyAnimationEnd = beginHeavyAnimation(undefined, true);
|
||||||
prevOnHeavyAnimationEnd?.();
|
prevOnHeavyAnimationEnd?.();
|
||||||
|
|
||||||
animateSingle(() => {
|
animateSingle(() => {
|
||||||
@ -142,7 +142,7 @@ function createMutateFunction(
|
|||||||
if (!isAnimating) {
|
if (!isAnimating) {
|
||||||
currentArgs = undefined;
|
currentArgs = undefined;
|
||||||
|
|
||||||
onHeavyAnimationEnd!();
|
onHeavyAnimationEnd?.();
|
||||||
onHeavyAnimationEnd = undefined;
|
onHeavyAnimationEnd = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +155,11 @@ export function isAnimatingScroll() {
|
|||||||
return isAnimating;
|
return isAnimating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function cancelScrollBlockingAnimation() {
|
||||||
|
onHeavyAnimationEnd!();
|
||||||
|
onHeavyAnimationEnd = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function calculateScrollFrom(
|
function calculateScrollFrom(
|
||||||
container: HTMLElement,
|
container: HTMLElement,
|
||||||
scrollTo: number,
|
scrollTo: number,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user