From a8a31dac517a25141cc6f1b802ae26b573dfda04 Mon Sep 17 00:00:00 2001 From: Haoyu Xu Date: Thu, 2 Mar 2023 18:42:14 -0500 Subject: [PATCH] perf(directory): home.jsx performance optimization --- directory/src/routes/path/home.jsx | 197 +++++++++++++++++------------ directory/src/routes/root.jsx | 69 +++++----- directory/src/state/appbar.js | 10 ++ 3 files changed, 168 insertions(+), 108 deletions(-) create mode 100644 directory/src/state/appbar.js diff --git a/directory/src/routes/path/home.jsx b/directory/src/routes/path/home.jsx index 3296ce7..0a163fe 100644 --- a/directory/src/routes/path/home.jsx +++ b/directory/src/routes/path/home.jsx @@ -1,7 +1,8 @@ import { useState, useEffect, - useCallback + useCallback, + useMemo } from 'react' import { NavLink, @@ -13,8 +14,9 @@ import { useI18n } from '@/state/language' import { useHeader } from '@/state/header'; +import { useAppbar } from '@/state/appbar'; import { useAtom } from 'jotai' -import { atomWithStorage } from 'jotai/utils'; +import { atom } from 'jotai'; import CharIcon from '@/component/char_icon'; import MainBorder from '@/component/main_border'; import useUmami from '@parcellab/react-use-umami'; @@ -22,7 +24,38 @@ import Switch from '@/component/switch'; const audioEl = new Audio() let isPlaying = false -const voiceOnAtom = atomWithStorage('voiceOn', false) +let voiceOnState = false +const voiceOnStateAtom = atom(voiceOnState) +const voiceOnAtom = atom( + (get) => get(voiceOnStateAtom), + (get, set, newState) => { + voiceOnState = newState + set(voiceOnStateAtom, voiceOnState) + // you can set as many atoms as you want at the same time + } +) + +const playVoice = (link) => { + const audioUrl = `/${link}/assets/${JSON.parse(import.meta.env.VITE_VOICE_FOLDERS).main}/${import.meta.env.VITE_APP_VOICE_URL}` + if (!voiceOnState || (audioEl.src === (window.location.href.replace(/\/$/g, '') + audioUrl) && isPlaying)) return + audioEl.src = audioUrl + let startPlayPromise = audioEl.play() + if (startPlayPromise !== undefined) { + startPlayPromise + .then(() => { + isPlaying = true + const audioEndedFunc = () => { + audioEl.removeEventListener('ended', audioEndedFunc) + isPlaying = false + } + audioEl.addEventListener('ended', audioEndedFunc) + }) + .catch((e) => { + console.log(e) + return + }) + } +} export default function Home() { const _trackEvt = useUmami('/') @@ -30,14 +63,10 @@ export default function Home() { setTitle, setTabs, currentTab, - setAppbarExtraArea, setHeaderIcon } = useHeader() const { config } = useConfig() - const { textDefaultLang, language, alternateLang } = useLanguage() const [content, setContent] = useState([]) - const [voiceOn, setVoiceOn] = useAtom(voiceOnAtom) - const { i18n } = useI18n() useEffect(() => { setTitle('dynamic_compile') @@ -55,47 +84,8 @@ export default function Home() { setContent(config?.operators || []) }, [config]) - const toggleVoice = useCallback(() => { - setVoiceOn(!voiceOn) - }, [voiceOn]) - - useEffect(() => { - setAppbarExtraArea([ - ( - toggleVoice()} - /> - ) - ]) - }, [voiceOn, language]) - const isShown = useCallback((type) => currentTab === 'all' || currentTab === type, [currentTab]) - const playVoice = useCallback((link) => { - const audioUrl = `/${link}/assets/${JSON.parse(import.meta.env.VITE_VOICE_FOLDERS).main}/${import.meta.env.VITE_APP_VOICE_URL}` - if (!voiceOn || (audioEl.src === (window.location.href.replace(/\/$/g, '') + audioUrl) && isPlaying)) return - audioEl.src = audioUrl - let startPlayPromise = audioEl.play() - if (startPlayPromise !== undefined) { - startPlayPromise - .then(() => { - isPlaying = true - const audioEndedFunc = () => { - audioEl.removeEventListener('ended', audioEndedFunc) - isPlaying = false - } - audioEl.addEventListener('ended', audioEndedFunc) - }) - .catch((e) => { - console.log(e) - return - }) - } - }, [voiceOn]) - return (
{ @@ -106,40 +96,12 @@ export default function Home() {
{v.map(item => { return ( -