Skip to content

Commit 1280214

Browse files
committed
perf: disable accent transition in safari
1 parent 113876f commit 1280214

File tree

2 files changed

+59
-8
lines changed

2 files changed

+59
-8
lines changed

src/components/widgets/post/PostMetaBar.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client'
22

3+
import { Fragment } from 'react'
34
import Link from 'next/link'
45
import type { PostModel } from '@mx-space/api-client'
56

@@ -70,7 +71,7 @@ export const PostMetaBar: Component<{
7071
const isLast = index === meta.tags!.length - 1
7172

7273
return (
73-
<>
74+
<Fragment key={tag}>
7475
<button
7576
className="shiro-link--underline"
7677
onClick={() =>
@@ -84,7 +85,7 @@ export const PostMetaBar: Component<{
8485
{tag}
8586
</button>
8687
{!isLast && <span>, </span>}
87-
</>
88+
</Fragment>
8889
)
8990
})}
9091
</>

src/providers/root/accent-color-provider.tsx

+56-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { useServerInsertedHTML } from 'next/navigation'
33
import type { AccentColor } from '~/app/config'
44
import type { PropsWithChildren } from 'react'
55

6+
import { useEventCallback } from '~/hooks/common/use-event-callback'
7+
import { debounce } from '~/lib/_'
68
import { generateTransitionColors, hexToHsl } from '~/lib/color'
79
import { noopObj } from '~/lib/noop'
810

@@ -27,8 +29,12 @@ const accentColorDark = [
2729
'#838BC6',
2830
]
2931

32+
const isSafari = () =>
33+
/^((?!chrome|android).)*safari/i.test(navigator.userAgent)
34+
3035
const STEP = 60
31-
const INTERVAL = 300
36+
const INTERVAL = 500
37+
3238
export const AccentColorProvider = ({ children }: PropsWithChildren) => {
3339
const { light, dark } =
3440
useAppConfigSelector((config) => config.color) || (noopObj as AccentColor)
@@ -42,7 +48,7 @@ export const AccentColorProvider = ({ children }: PropsWithChildren) => {
4248
const currentAccentColorDRef = useRef(darkColors[randomSeedRef.current])
4349

4450
const [u, update] = useState(0)
45-
useEffect(() => {
51+
const updateColorEvent = useEventCallback(() => {
4652
const $style = document.createElement('style')
4753

4854
const nextSeed = (randomSeedRef.current + 1) % Length
@@ -59,13 +65,17 @@ export const AccentColorProvider = ({ children }: PropsWithChildren) => {
5965
STEP,
6066
)
6167

62-
const timer = setTimeout(function updateAccent() {
68+
let timerDispose = setIdleTimeout(function updateAccent() {
6369
const colorD = colorsD.shift()
6470
const colorL = colorsL.shift()
6571
if (colorD && colorL) {
6672
currentAccentColorDRef.current = colorD
6773
currentAccentColorLRef.current = colorL
68-
setTimeout(updateAccent, INTERVAL)
74+
75+
try {
76+
timerDispose()
77+
} catch {}
78+
timerDispose = setIdleTimeout(updateAccent, INTERVAL)
6979
} else {
7080
randomSeedRef.current = nextSeed
7181
currentAccentColorDRef.current = nextColorD
@@ -92,13 +102,18 @@ export const AccentColorProvider = ({ children }: PropsWithChildren) => {
92102

93103
document.head.appendChild($style)
94104
return () => {
95-
clearTimeout(timer)
105+
timerDispose()
96106

97107
setTimeout(() => {
98108
document.head.removeChild($style)
99109
}, INTERVAL)
100110
}
101-
}, [Length, darkColors, lightColors, u])
111+
})
112+
useEffect(() => {
113+
// safari 性能不行
114+
if (isSafari()) return
115+
return updateColorEvent()
116+
}, [Length, darkColors, lightColors, u, updateColorEvent])
102117

103118
useServerInsertedHTML(() => {
104119
const lightHsl = hexToHsl(currentAccentColorLRef.current)
@@ -129,3 +144,38 @@ export const AccentColorProvider = ({ children }: PropsWithChildren) => {
129144

130145
return children
131146
}
147+
148+
function setIdleTimeout(onIdle: () => void, timeout: number): () => void {
149+
let timeoutId: number | undefined
150+
151+
const debounceReset = debounce(() => {
152+
clearTimeout(timeoutId)
153+
timeoutId = window.setTimeout(() => {
154+
onIdle()
155+
}, timeout)
156+
}, 100)
157+
158+
// 重置计时器的函数
159+
const resetTimer = () => {
160+
window.clearTimeout(timeoutId)
161+
debounceReset()
162+
}
163+
164+
// 监听浏览器的活动事件
165+
window.addEventListener('mousemove', resetTimer)
166+
window.addEventListener('keypress', resetTimer)
167+
window.addEventListener('touchstart', resetTimer)
168+
window.addEventListener('scroll', resetTimer)
169+
170+
// 启动计时器
171+
resetTimer()
172+
173+
// 提供取消功能
174+
return function cancel(): void {
175+
window.clearTimeout(timeoutId)
176+
window.removeEventListener('mousemove', resetTimer)
177+
window.removeEventListener('keypress', resetTimer)
178+
window.removeEventListener('touchstart', resetTimer)
179+
window.removeEventListener('scroll', resetTimer)
180+
}
181+
}

0 commit comments

Comments
 (0)