Next.js中Vanilla Extract暗黑模式切换卡顿问题排查
Next.js + Vanilla Extract 暗黑模式切换卡顿问题排查
我在Next.js中使用Vanilla Extract实现了暗黑模式,但切换时速度极慢,至少需要1.5秒,文章页面的情况更差。我已尝试移除SVGmorph组件,但卡顿问题仍未解决。
1. Layout 组件代码
/** layout.tsx */ export default function RootLayout({ children, }: { children: React.ReactNode; }) { const cookieStore = cookies(); const theme = cookieStore.get("theme"); return ( <html lang="ko-KR"> <link rel="icon" href="/favicon.ico" sizes="any" /> <body className={theme?.value === "light" ? ligthTheme : darkTheme}> <Topbar /> <div className={styles.mainContentContainer}> <main className={styles.mainContent}> {children} <Footer /> </main> </div> <BottomBar /> </body> </html> ); }
2. 主题定义代码
/** theme.css.ts */ import { createGlobalTheme, createThemeContract, createTheme, } from "@vanilla-extract/css"; import { white, grey } from "../colors.css"; const root = createGlobalTheme("#root", {}); const themeColor = createThemeContract({ fontColor: { textColor: null, accentColor: null, subColor: null, accentSubColor: null, middleAccentColor: null, }, buttonColor: { notActiveColor: null, activeColor: null, }, backgroundColor: { bodyColor: null, accentColor: null, navbarColor: null, textBoxColor: null, glassGradientColorTop: null, glassGradientColorBottom: null, }, boxColor: { notHoverColor: null, hoverColor: null, }, borderColor: { notHoverColor: null, hoverColor: null, }, }); export const ligthTheme = createTheme(themeColor, { fontColor: { textColor: grey[300], subColor: white[500], accentSubColor: white[500], middleAccentColor: grey[200], accentColor: "black", }, buttonColor: { notActiveColor: white[500], activeColor: "black", }, backgroundColor: { bodyColor: white[100], accentColor: white[200], navbarColor: "rgba(" + white[100] + ", 0.8)", glassGradientColorTop: `linear-gradient(to top, rgba(245,245,245,0) 0%, rgba(245,245,245,1) 100%)`, glassGradientColorBottom: `linear-gradient(to top, rgba(245,245,245,1) 0%, rgba(245,245,245,0) 100%)`, textBoxColor: white[300], }, boxColor: { notHoverColor: white[200], hoverColor: white[300], }, borderColor: { notHoverColor: white[400], hoverColor: grey[100], }, }); export const darkTheme = createTheme(themeColor, { fontColor: { textColor: white[100], subColor: grey[300], accentColor: "white", accentSubColor: grey[200], middleAccentColor: white[200], }, buttonColor: { notActiveColor: grey[100], activeColor: white[100], }, backgroundColor: { bodyColor: grey[500], accentColor: grey[400], navbarColor: "rgba(" + grey[500] + ", 0.8)", glassGradientColorTop: `linear-gradient(to top, rgba(16,16,16,0) 0%, rgba(16,16,16, 1) 100%)`, glassGradientColorBottom: `linear-gradient(to top, rgba(16,16,16,1) 0%, rgba(16,16,16,0) 100%)`, textBoxColor: grey[300], }, boxColor: { notHoverColor: grey[400], hoverColor: grey[100], }, borderColor: { notHoverColor: grey[200], hoverColor: white[300], }, }); import { keyframes } from "@vanilla-extract/css"; export const blink = keyframes({ "0%": { opacity: 0, }, "50%": { opacity: 0.7, }, "100%": { opacity: 0, }, }); export const vars = { ...root, themeColor, blink };
3. 主题切换按钮代码
/** ToggleBtn.tsx */ import { moon } from "../icon/moon"; import { sun } from "../icon/sun"; import { cookies } from "next/headers"; import { toggleBtn } from "./ToggleBtn.css"; import SVGmorph from "./SVGmorph"; export default function ToggleBtn() { const theme = cookies().get("theme"); const handleTheme = async () => { "use server"; if (theme?.value === "dark" || !theme?.value) { cookies().set("theme", "light"); } else { cookies().set("theme", "dark"); } }; return ( <form action={handleTheme}> <button className={toggleBtn}> <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" > <SVGmorph paths={[sun, moon, sun]} theme={theme?.value || "dark"} /> </svg> </button> </form> ); }
请问我的使用方式是否有误?代码中存在什么问题?
内容的提问来源于stack exchange,提问作者Joo
相关产品推荐
相关产品推荐

