動態主題切換的實現方式
1. 使用 CSS 變量(CSS Custom Properties)
CSS 變量是實現主題切換最直接的方式:
:root {--primary-color: #4285f4;--background-color: #ffffff;--text-color: #333333;
}[data-theme="dark"] {--primary-color: #8ab4f8;--background-color: #1a1a1a;--text-color: #f1f1f1;
}body {background-color: var(--background-color);color: var(--text-color);
}
JavaScript 切換主題:
function toggleTheme() {document.documentElement.setAttribute('data-theme', document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark');
}
2. CSS-in-JS 實現(以 styled-components 為例)
import styled, { ThemeProvider } from 'styled-components';const lightTheme = {primary: '#4285f4',background: '#ffffff',text: '#333333'
};const darkTheme = {primary: '#8ab4f8',background: '#1a1a1a',text: '#f1f1f1'
};const Button = styled.button`background: ${props => props.theme.primary};color: ${props => props.theme.text};
`;function App() {const [theme, setTheme] = useState(lightTheme);const toggleTheme = () => {setTheme(theme === lightTheme ? darkTheme : lightTheme);};return (<ThemeProvider theme={theme}><Button onClick={toggleTheme}>Toggle Theme</Button></ThemeProvider>);
}
提升首屏渲染效率的策略
1. 關鍵 CSS 提取
// 使用 styled-components 的 ServerStyleSheet 提取關鍵 CSS
import { ServerStyleSheet } from 'styled-components';const sheet = new ServerStyleSheet();
const html = renderToString(sheet.collectStyles(<App />));
const styleTags = sheet.getStyleTags(); // 插入到 HTML 的 head 中
2. 代碼分割與按需加載
import React, { lazy, Suspense } from 'react';
const HeavyComponent = lazy(() => import('./HeavyComponent'));function App() {return (<Suspense fallback={<div>Loading...</div>}><HeavyComponent /></Suspense>);
}
3. 使用 CSS 變量替代動態樣式
CSS 變量的性能優于 JavaScript 動態計算樣式:
// 不推薦 - 性能較差
const DynamicDiv = styled.div`color: ${props => props.color};
`;// 推薦 - 使用 CSS 變量
const DynamicDiv = styled.div`color: var(--dynamic-color);
`;
// 使用時
<DynamicDiv style={{ '--dynamic-color': props.color }} />
4. 避免不必要的重新渲染
// 使用 React.memo 避免不必要的重新渲染
const ThemedButton = React.memo(styled.button`background: ${props => props.theme.primary};
`);
CSS 變量如何解決這些問題
1. 主題切換性能優化
CSS 變量在瀏覽器層面實現樣式更新,避免了 JavaScript 的樣式計算和 DOM 操作:
// 只需改變根元素的變量值
document.documentElement.style.setProperty('--primary-color', newColor);
2. 首屏渲染優化
CSS 變量:
可以被預解析,瀏覽器可以更快地構建渲染樹
減少 CSS-in-JS 運行時生成的樣式表大小
支持服務器端渲染,不會產生樣式閃爍
3. 動態樣式與靜態樣式的分離
/* 靜態部分編譯時確定 */
.button {padding: 8px 16px;border-radius: 4px;/* 動態部分通過變量控制 */background: var(--button-bg, #eee);color: var(--button-color, #333);
}
4. 主題持久化示例
結合 localStorage 實現主題持久化:
// 初始化主題
const savedTheme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', savedTheme);// 切換主題并保存
function toggleTheme() {const newTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';document.documentElement.setAttribute('data-theme', newTheme);localStorage.setItem('theme', newTheme);
}
性能對比
方案 | 首屏渲染 | 主題切換 | 維護性 | SSR支持 |
---|---|---|---|---|
純 CSS-in-JS | 較慢 | 快 | 好 | 需要額外配置 |
CSS 變量 | 快 | 最快 | 一般 | 原生支持 |
混合方案 | 較快 | 快 | 最好 | 需要配置 |
最佳實踐推薦:使用 CSS 變量定義主題色,結合 CSS-in-JS 管理組件樣式,既能保證性能又能維護良好的開發體驗。