前端性能优化

代码分割

// 动态导入 (React) const HeavyChart = React.lazy(() => import('./HeavyChart')); function App() { return ( <React.Suspense fallback={<Spinner />}> {showChart && <HeavyChart />} </React.Suspense> ); } // 基于路由的分割 (React Router) const Dashboard = React.lazy(() => import('./pages/Dashboard')); // Vite 动态导入 const { default: module } = await import('./heavy-module.js');

渲染性能

// 避免布局抖动——批量读写 DOM // 不好的做法:交替读写 el1.style.width = el2.offsetWidth + 'px'; // 触发重排 el3.style.height = el4.offsetHeight + 'px'; // 再次触发 // 好的做法:先批量读,再批量写 const w = el2.offsetWidth; // 读 const h = el4.offsetHeight; // 读 el1.style.width = w + 'px'; // 写 el3.style.height = h + 'px'; // 写 // 动画使用 requestAnimationFrame function animate() { element.style.transform = `translateX(${pos}px)`; pos += 1; requestAnimationFrame(animate); } // 使用 CSS transform/opacity(GPU 合成) // 好: transform, opacity, filter // 差: top, left, width, height(触发布局)

打包优化

// Vite 手动分块 export default { build: { rollupOptions: { output: { manualChunks: { vendor: ['react', 'react-dom'], charts: ['recharts'], utils: ['lodash-es', 'date-fns'] } } } } } // 按需导入 import { debounce } from 'lodash-es'; // 支持 tree-shaking // 不要: import _ from 'lodash';

性能指标参考

指标目标值工具
LCP< 2.5sLighthouse、CrUX
INP< 200msLighthouse、CrUX
CLS< 0.1Lighthouse、CrUX
TTFB< 200msWebPageTest
JS 包大小< 170KB(gzip)Bundlesize
页面总体积< 1MBChrome DevTools、GTmetrix