[Perf] TeactN: Check for heavy animations
This commit is contained in:
parent
9d58257319
commit
ebf20fa013
2
src/@types/global.d.ts
vendored
2
src/@types/global.d.ts
vendored
@ -65,7 +65,7 @@ interface IWebpWorker extends Worker {
|
||||
|
||||
interface Window {
|
||||
ClipboardItem?: any;
|
||||
requestIdleCallback: (cb: AnyToVoidFunction) => void;
|
||||
requestIdleCallback: (cb: AnyToVoidFunction, options:{ timeout?: number }) => void;
|
||||
}
|
||||
|
||||
interface Clipboard { write?: any }
|
||||
|
||||
@ -19,6 +19,7 @@ import {
|
||||
import captureKeyboardListeners from '../../../util/captureKeyboardListeners';
|
||||
import useLayoutEffectWithPrevDeps from '../../../hooks/useLayoutEffectWithPrevDeps';
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
import { isHeavyAnimating } from '../../../hooks/useHeavyAnimationCheck';
|
||||
import parseEmojiOnlyString from '../../common/helpers/parseEmojiOnlyString';
|
||||
import { isSelectionInsideInput } from './helpers/selection';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
@ -125,8 +126,7 @@ const MessageInput: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}, [html]);
|
||||
|
||||
const focusInput = useCallback(() => {
|
||||
// Avoid focusing during animation
|
||||
if (inputRef.current!.closest('.from, .to')) {
|
||||
if (isHeavyAnimating()) {
|
||||
setTimeout(focusInput, FOCUS_DELAY_MS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ import {
|
||||
DEFAULT_PLAYBACK_RATE,
|
||||
} from '../config';
|
||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../util/environment';
|
||||
import { ANIMATION_END_EVENT, ANIMATION_START_EVENT } from '../hooks/useHeavyAnimationCheck';
|
||||
import { isHeavyAnimating } from '../hooks/useHeavyAnimationCheck';
|
||||
import { pick } from '../util/iteratees';
|
||||
import { selectCurrentMessageList } from '../modules/selectors';
|
||||
import { hasStoredSession } from '../util/sessions';
|
||||
@ -31,11 +31,8 @@ const UPDATE_THROTTLE = 5000;
|
||||
const updateCacheThrottled = throttle(() => onIdle(updateCache), UPDATE_THROTTLE, false);
|
||||
|
||||
let isCaching = false;
|
||||
let isHeavyAnimating = false;
|
||||
let unsubscribeFromBeforeUnload: NoneToVoidFunction | undefined;
|
||||
|
||||
setupHeavyAnimationListeners();
|
||||
|
||||
export function initCache() {
|
||||
if (GLOBAL_STATE_CACHE_DISABLED) {
|
||||
return;
|
||||
@ -200,7 +197,7 @@ function migrateCache(cached: GlobalState, initialState: GlobalState) {
|
||||
}
|
||||
|
||||
function updateCache() {
|
||||
if (!isCaching || isHeavyAnimating) {
|
||||
if (!isCaching || isHeavyAnimating()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -344,12 +341,3 @@ function reduceGroupCalls(global: GlobalState): GlobalState['groupCalls'] {
|
||||
isFallbackConfirmOpen: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function setupHeavyAnimationListeners() {
|
||||
document.addEventListener(ANIMATION_START_EVENT, () => {
|
||||
isHeavyAnimating = true;
|
||||
});
|
||||
document.addEventListener(ANIMATION_END_EVENT, () => {
|
||||
isHeavyAnimating = false;
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,12 +1,35 @@
|
||||
import { useEffect } from '../lib/teact/teact';
|
||||
|
||||
export const ANIMATION_START_EVENT = 'tt-event-heavy-animation-start';
|
||||
export const ANIMATION_END_EVENT = 'tt-event-heavy-animation-end';
|
||||
const ANIMATION_START_EVENT = 'tt-event-heavy-animation-start';
|
||||
const ANIMATION_END_EVENT = 'tt-event-heavy-animation-end';
|
||||
|
||||
let timeout: number | undefined;
|
||||
let isAnimating = false;
|
||||
|
||||
export const dispatchHeavyAnimationEvent = (duration?: number) => {
|
||||
export default (
|
||||
handleAnimationStart: AnyToVoidFunction,
|
||||
handleAnimationEnd: AnyToVoidFunction,
|
||||
) => {
|
||||
useEffect(() => {
|
||||
if (isAnimating) {
|
||||
handleAnimationStart();
|
||||
}
|
||||
|
||||
document.addEventListener(ANIMATION_START_EVENT, handleAnimationStart);
|
||||
document.addEventListener(ANIMATION_END_EVENT, handleAnimationEnd);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener(ANIMATION_END_EVENT, handleAnimationEnd);
|
||||
document.removeEventListener(ANIMATION_START_EVENT, handleAnimationStart);
|
||||
};
|
||||
}, [handleAnimationEnd, handleAnimationStart]);
|
||||
};
|
||||
|
||||
export function isHeavyAnimating() {
|
||||
return isAnimating;
|
||||
}
|
||||
|
||||
export function dispatchHeavyAnimationEvent(duration?: number) {
|
||||
if (!isAnimating) {
|
||||
isAnimating = true;
|
||||
document.dispatchEvent(new Event(ANIMATION_START_EVENT));
|
||||
@ -29,23 +52,4 @@ export const dispatchHeavyAnimationEvent = (duration?: number) => {
|
||||
isAnimating = false;
|
||||
document.dispatchEvent(new Event(ANIMATION_END_EVENT));
|
||||
};
|
||||
};
|
||||
|
||||
export default (
|
||||
handleAnimationStart: AnyToVoidFunction,
|
||||
handleAnimationEnd: AnyToVoidFunction,
|
||||
) => {
|
||||
useEffect(() => {
|
||||
if (isAnimating) {
|
||||
handleAnimationStart();
|
||||
}
|
||||
|
||||
document.addEventListener(ANIMATION_START_EVENT, handleAnimationStart);
|
||||
document.addEventListener(ANIMATION_END_EVENT, handleAnimationEnd);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener(ANIMATION_END_EVENT, handleAnimationEnd);
|
||||
document.removeEventListener(ANIMATION_START_EVENT, handleAnimationStart);
|
||||
};
|
||||
}, [handleAnimationEnd, handleAnimationStart]);
|
||||
};
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import arePropsShallowEqual, { getUnequalProps } from '../../util/arePropsShallo
|
||||
import { orderBy } from '../../util/iteratees';
|
||||
import { GlobalState, GlobalActions, ActionTypes } from '../../global/types';
|
||||
import { handleError } from '../../util/handleError';
|
||||
import { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck';
|
||||
|
||||
export default React;
|
||||
|
||||
@ -40,12 +41,17 @@ const containers = new Map<string, {
|
||||
DEBUG_componentName: string;
|
||||
}>();
|
||||
|
||||
const runCallbacksThrottled = throttleWithRaf(runCallbacks);
|
||||
|
||||
function runCallbacks() {
|
||||
if (isHeavyAnimating()) {
|
||||
runCallbacksThrottled();
|
||||
return;
|
||||
}
|
||||
|
||||
callbacks.forEach((cb) => cb(currentGlobal));
|
||||
}
|
||||
|
||||
const runCallbacksThrottled = throttleWithRaf(runCallbacks);
|
||||
|
||||
// `noThrottle = true` is used as a workaround for iOS gesture history navigation
|
||||
export function setGlobal(newGlobal?: GlobalState, noThrottle = false) {
|
||||
if (typeof newGlobal === 'object' && newGlobal !== currentGlobal) {
|
||||
|
||||
@ -104,11 +104,11 @@ export function throttleWith<F extends AnyToVoidFunction>(schedulerFn: Scheduler
|
||||
};
|
||||
}
|
||||
|
||||
export function onIdle(cb: NoneToVoidFunction) {
|
||||
export function onIdle(cb: NoneToVoidFunction, timeout?: number) {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
if (self.requestIdleCallback) {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
self.requestIdleCallback(cb);
|
||||
self.requestIdleCallback(cb, { timeout });
|
||||
} else {
|
||||
onTickEnd(cb);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user