From 980fb6ef41f44585da54a4a66ad2259620e3565c Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Wed, 15 Oct 2025 19:57:16 +0200 Subject: [PATCH] [Perf] Pause all CSS animations when in background --- src/components/App.tsx | 16 ++++++++++++---- src/components/common/DotAnimation.scss | 4 ++++ src/components/common/MediaSpoiler.module.scss | 8 ++++++-- src/components/common/Sparkles.module.scss | 12 ++++++++---- src/components/common/Sparkles.tsx | 11 +---------- src/components/common/spoiler/Spoiler.scss | 4 ++++ src/components/ui/Spinner.scss | 4 ++++ src/components/ui/placeholder/Skeleton.scss | 4 ++++ src/components/ui/placeholder/Skeleton.tsx | 5 +++-- 9 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index fdde35eca..df3066990 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -6,10 +6,8 @@ import type { GlobalState } from '../global/types'; import type { ThemeKey } from '../types'; import type { UiLoaderPage } from './common/UiLoader'; -import { - DARK_THEME_BG_COLOR, INACTIVE_MARKER, LIGHT_THEME_BG_COLOR, PAGE_TITLE, - PAGE_TITLE_TAURI, -} from '../config'; +import { DARK_THEME_BG_COLOR, INACTIVE_MARKER, LIGHT_THEME_BG_COLOR, PAGE_TITLE, PAGE_TITLE_TAURI } from '../config'; +import { forceMutation } from '../lib/fasterdom/stricterdom.ts'; import { selectTabState, selectTheme } from '../global/selectors'; import { IS_TAURI } from '../util/browser/globalEnvironment'; import { IS_INSTALL_PROMPT_SUPPORTED, PLATFORM_ENV } from '../util/browser/windowEnvironment'; @@ -24,6 +22,8 @@ import { updateSizes } from '../util/windowSize'; import useTauriDrag from '../hooks/tauri/useTauriDrag'; import useAppLayout from '../hooks/useAppLayout'; import usePrevious from '../hooks/usePrevious'; +import { useSignalEffect } from '../hooks/useSignalEffect.ts'; +import { getIsInBackground } from '../hooks/window/useBackgroundMode.ts'; // import Test from './test/TestLocale'; import Auth from './auth/Auth'; @@ -226,6 +226,14 @@ const App: FC = ({ ); }, [theme]); + const getIsInBackgroundLocal = getIsInBackground; + useSignalEffect(() => { + // Mutation forced to avoid RAF throttling in background + forceMutation(() => { + document.body.classList.toggle('in-background', getIsInBackgroundLocal()); + }, document.body); + }, [getIsInBackgroundLocal]); + return ( { const ref = useRef(); - const getIsInBackgroundLocal = getIsInBackground; - useEffect(() => { - (Array.from(ref.current!.children) as HTMLDivElement[]).forEach((sparkleEL) => { - sparkleEL.style.animationPlayState = getIsInBackgroundLocal() ? 'paused' : 'running'; - }); - }, [getIsInBackgroundLocal]); - if (presetSettings.preset === 'button') { return (
= ({ ); }; -export default Skeleton; +export default memo(Skeleton);