[Perf] Do not save cache during heavy animation

This commit is contained in:
Alexander Zinchuk 2021-08-04 02:35:22 +03:00
parent 4a7882e1ba
commit f13b1950ef
4 changed files with 73 additions and 32 deletions

View File

@ -5,10 +5,11 @@ import { getGlobal, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types'; import { GlobalActions } from '../../global/types';
import { ApiMessage } from '../../api/types'; import { ApiMessage } from '../../api/types';
import { LangCode } from '../../types';
import '../../modules/actions/all'; import '../../modules/actions/all';
import { import {
ANIMATION_END_DELAY, BASE_EMOJI_KEYWORD_LANG, DEBUG, INACTIVE_MARKER, PAGE_TITLE, BASE_EMOJI_KEYWORD_LANG, DEBUG, INACTIVE_MARKER, PAGE_TITLE,
} from '../../config'; } from '../../config';
import { pick } from '../../util/iteratees'; import { pick } from '../../util/iteratees';
import { import {
@ -20,9 +21,11 @@ import {
} from '../../modules/selectors'; } from '../../modules/selectors';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck'; import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { fastRaf } from '../../util/schedulers';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useBackgroundMode from '../../hooks/useBackgroundMode'; import useBackgroundMode from '../../hooks/useBackgroundMode';
import useBeforeUnload from '../../hooks/useBeforeUnload'; import useBeforeUnload from '../../hooks/useBeforeUnload';
import useOnChange from '../../hooks/useOnChange';
import LeftColumn from '../left/LeftColumn'; import LeftColumn from '../left/LeftColumn';
import MiddleColumn from '../middle/MiddleColumn'; import MiddleColumn from '../middle/MiddleColumn';
@ -36,7 +39,6 @@ import SafeLinkModal from './SafeLinkModal.async';
import HistoryCalendar from './HistoryCalendar.async'; import HistoryCalendar from './HistoryCalendar.async';
import './Main.scss'; import './Main.scss';
import { LangCode } from '../../types';
type StateProps = { type StateProps = {
animationLevel: number; animationLevel: number;
@ -59,10 +61,8 @@ type DispatchProps = Pick<GlobalActions, (
'loadTopInlineBots' | 'loadEmojiKeywords' 'loadTopInlineBots' | 'loadEmojiKeywords'
)>; )>;
const ANIMATION_DURATION = 350;
const NOTIFICATION_INTERVAL = 1000; const NOTIFICATION_INTERVAL = 1000;
let rightColumnAnimationTimeout: number | undefined;
let notificationInterval: number | undefined; let notificationInterval: number | undefined;
let DEBUG_isLogged = false; let DEBUG_isLogged = false;
@ -128,23 +128,53 @@ const Main: FC<StateProps & DispatchProps> = ({
shouldSkipHistoryAnimations && 'history-animation-disabled', shouldSkipHistoryAnimations && 'history-animation-disabled',
); );
// Add `body` classes when toggling right column // Dispatch heavy transition event when opening middle column
useEffect(() => { useOnChange(([prevIsLeftColumnShown]) => {
if (animationLevel > 0) { if (prevIsLeftColumnShown === undefined || animationLevel === 0) {
document.body.classList.add('animating-right-column'); return;
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY); }
if (rightColumnAnimationTimeout) { const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent();
clearTimeout(rightColumnAnimationTimeout); const middleColumnEl = document.getElementById('MiddleColumn')!;
rightColumnAnimationTimeout = undefined;
middleColumnEl.addEventListener('transitionend', function handleTransitionEnd(e: TransitionEvent) {
if (e.target !== e.currentTarget) {
return;
} }
rightColumnAnimationTimeout = window.setTimeout(() => { middleColumnEl.removeEventListener('transitionend', handleTransitionEnd);
document.body.classList.remove('animating-right-column');
rightColumnAnimationTimeout = undefined; dispatchHeavyAnimationEnd();
}, ANIMATION_DURATION + ANIMATION_END_DELAY); });
}, [isLeftColumnShown]);
// Dispatch heavy transition event and add body class when opening right column
useOnChange(([prevIsRightColumnShown]) => {
if (prevIsRightColumnShown === undefined || animationLevel === 0) {
return;
} }
}, [animationLevel, isRightColumnShown]);
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent();
const rightColumnEl = document.getElementById('RightColumn')!;
fastRaf(() => {
document.body.classList.add('animating-right-column');
});
rightColumnEl.addEventListener('transitionend', function handleTransitionEnd(e: TransitionEvent) {
if (e.target !== e.currentTarget) {
return;
}
rightColumnEl.removeEventListener('transitionend', handleTransitionEnd);
dispatchHeavyAnimationEnd();
fastRaf(() => {
document.body.classList.remove('animating-right-column');
});
});
}, [isRightColumnShown]);
const handleBlur = useCallback(() => { const handleBlur = useCallback(() => {
updateIsOnline(false); updateIsOnline(false);

View File

@ -173,18 +173,16 @@ const Transition: FC<OwnProps> = ({
}); });
} }
function handleAnimationEnd(e: AnimationEvent) {
if (e.target !== e.currentTarget) {
return;
}
toNode.removeEventListener('animationend', handleAnimationEnd as EventListener);
onAnimationEnd();
}
if (animationLevel > 0) { if (animationLevel > 0) {
toNode.addEventListener('animationend', handleAnimationEnd as EventListener); toNode.addEventListener('animationend', function handleAnimationEnd(e: AnimationEvent) {
if (e.target !== e.currentTarget) {
return;
}
toNode.removeEventListener('animationend', handleAnimationEnd as EventListener);
onAnimationEnd();
} as EventListener);
} else { } else {
onAnimationEnd(); onAnimationEnd();
} }

View File

@ -15,18 +15,22 @@ import {
GLOBAL_STATE_CACHE_USER_LIST_LIMIT, GLOBAL_STATE_CACHE_USER_LIST_LIMIT,
} from '../config'; } from '../config';
import { IS_SINGLE_COLUMN_LAYOUT } from '../util/environment'; import { IS_SINGLE_COLUMN_LAYOUT } from '../util/environment';
import { ANIMATION_END_EVENT, ANIMATION_START_EVENT } from '../hooks/useHeavyAnimationCheck';
import { pick } from '../util/iteratees'; import { pick } from '../util/iteratees';
import { INITIAL_STATE } from './initial';
import { selectCurrentMessageList } from '../modules/selectors'; import { selectCurrentMessageList } from '../modules/selectors';
import { hasStoredSession } from '../util/sessions'; import { hasStoredSession } from '../util/sessions';
import { INITIAL_STATE } from './initial';
const UPDATE_THROTTLE = 5000; const UPDATE_THROTTLE = 5000;
const updateCacheThrottled = throttle(() => onIdle(updateCache), UPDATE_THROTTLE, false); const updateCacheThrottled = throttle(() => onIdle(updateCache), UPDATE_THROTTLE, false);
let isCaching = false; let isCaching = false;
let isHeavyAnimating = false;
let unsubscribeFromBeforeUnload: NoneToVoidFunction | undefined; let unsubscribeFromBeforeUnload: NoneToVoidFunction | undefined;
setupHeavyAnimationListeners();
export function initCache() { export function initCache() {
if (GLOBAL_STATE_CACHE_DISABLED) { if (GLOBAL_STATE_CACHE_DISABLED) {
return; return;
@ -124,7 +128,7 @@ function readCache(initialState: GlobalState) {
} }
function updateCache() { function updateCache() {
if (!isCaching) { if (!isCaching || isHeavyAnimating) {
return; return;
} }
@ -258,3 +262,12 @@ function reduceChatFolders(global: GlobalState): GlobalState['chatFolders'] {
activeChatFolder: 0, activeChatFolder: 0,
}; };
} }
function setupHeavyAnimationListeners() {
document.addEventListener(ANIMATION_START_EVENT, () => {
isHeavyAnimating = true;
});
document.addEventListener(ANIMATION_END_EVENT, () => {
isHeavyAnimating = false;
});
}

View File

@ -1,7 +1,7 @@
import { useEffect } from '../lib/teact/teact'; import { useEffect } from '../lib/teact/teact';
const ANIMATION_START_EVENT = 'tt-event-heavy-animation-start'; export const ANIMATION_START_EVENT = 'tt-event-heavy-animation-start';
const ANIMATION_END_EVENT = 'tt-event-heavy-animation-end'; export const ANIMATION_END_EVENT = 'tt-event-heavy-animation-end';
let timeout: number | undefined; let timeout: number | undefined;
let isAnimating = false; let isAnimating = false;