一、网络层优化(减少加载时间)
1. 减少 HTTP 请求
- 合并文件:将小图标合并为雪碧图(CSS Sprites)或使用 SVG Symbols
- 代码拆分:使用 Webpack 的 SplitChunksPlugin 拆分公共代码
- 内联关键资源:关键 CSS/JS 直接内联到 HTML
2. 压缩资源
- Gzip/Brotli 压缩:服务器开启压缩(节省 60%+ 体积)
# Nginx 配置 gzip on; gzip_types text/css application/javascript;
- 图片优化:
- 使用 WebP 格式(比 JPEG/PNG 小 30%)
- 工具:imagemin-webpack-plugin(或其他工具) 自动压缩
- 代码压缩:
- Webpack / vite 生产模式自动压缩 JS/CSS
- 使用 TerserPlugin 移除 console
3. 缓存策略
- 强缓存(Cache-Control):
- 协商缓存(ETag/Last-Modified)
- Service Worker:实现离线缓存(PWA)
4. CDN 加速
- 静态资源(JS/CSS/图片)部署到 CDN
- 使用 HTTP/2 多路复用降低延迟
二、渲染层优化(提升交互流畅度)
1. 关键渲染路径优化
-
优化 CSS 加载:
<!-- 阻塞渲染的CSS --> <link rel="stylesheet" href="critical.css" media="all" /> <!-- 非关键CSS异步加载 --> <link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'" />
-
JS 异步/延迟加载:
<script defer src="main.js"></script> <!-- 延迟执行 --> <script async src="analytics.js"></script> <!-- 异步加载 -->
2. 减少重排(Reflow)与重绘(Repaint)
-
避免频繁操作 DOM:
// ❌ 糟糕写法(触发多次重排) for (let i = 0; i < 100; i++) { element.style.width = i + 'px'; } // ✅ 使用 requestAnimationFrame 或 CSS3 动画 function animate() { element.style.transform = `translateX(${pos}px)`; pos++; requestAnimationFrame(animate); }
-
使用 transform 和 opacity(触发 GPU 加速,跳过重排)
3. 虚拟列表优化长列表
// React 示例:react-window
import { FixedSizeList } from 'react-window';
<List height={400} itemCount={1000} itemSize={50}>
{({ index, style }) => <div style={style}>Item {index}</div>}
</List>
4. 代码分割与懒加载
-
路由级懒加载(React/Vue):
// React const Home = React.lazy(() => import('./Home')); // Vue const Home = () => import('./Home.vue');
-
图片懒加载:
<img data-src="image.jpg" class="lazyload" /> <script> const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.src = entry.target.dataset.src; observer.unobserve(entry.target); } }); }); document.querySelectorAll('.lazyload').forEach(img => observer.observe(img)); </script>
三、JavaScript 执行效率优化
1. 防抖(Debounce)与节流(Throttle)
// 防抖(连续触发只执行最后一次)
function debounce(fn, delay) {
let timer;
return () => {
clearTimeout(timer);
timer = setTimeout(fn, delay);
};
}
// 节流(固定时间执行一次)
function throttle(fn, interval) {
let lastTime = 0;
return () => {
const now = Date.now();
if (now - lastTime >= interval) {
fn();
lastTime = now;
}
};
}
2. Web Worker 处理 CPU 密集型任务
// 主线程
const worker = new Worker('worker.js');
worker.postMessage({ data: largeArray });
worker.onmessage = (e) => console.log(e.data);
// worker.js
self.onmessage = (e) => {
const result = heavyCalculation(e.data);
self.postMessage(result);
};
3. 避免内存泄漏
- 未移除的事件监听器
DOM元素绑定事件后未在组件销毁或页面切换时解绑,导致持续占用内存。 - 未清理的定时器/异步任务
setInterval或setTimeout未及时清除,回调函数持续运行。 - 闭包保留外部引用 (相关示例及解决)
闭包中引用的变量未被释放,导致关联对象无法回收。 - DOM元素残留引用
已移除的DOM元素仍被JavaScript变量引用,无法被垃圾回收。 - 全局变量滥用
意外创建的全局变量(如未声明变量、this指向全局)长期占用内存。 - 框架组件未正确卸载
React/Vue组件未在unmount阶段清理副作用(如事件、订阅)。
四、工具链优化
1. 打包优化(Webpack/Vite)
- Tree Shaking:移除未使用的代码(需 ES Module 语法)
- 按需加载第三方库
- 代码分割:
// Webpack 配置 optimization: { splitChunks: { chunks: 'all', }, }
- 预编译依赖:
# 将 vue/react 等不常变的库单独打包 npm install --save-dev dll-plugin
2. 性能监控
-
Lighthouse 评分(Chrome DevTools)
-
Web Vitals 核心指标:
-
LCP (Largest Contentful Paint):最大内容渲染时间
-
FID (First Input Delay):首次输入延迟
-
CLS (Cumulative Layout Shift):布局偏移量
-
五、进阶优化
1. 服务端渲染(SSR)
-
Next.js (React) / Nuxt.js (Vue) 提升首屏速度
-
流式 SSR:逐步发送 HTML 片段
2. 预加载关键资源
<!-- 提前加载字体、关键路由 -->
<link rel="preload" href="font.woff2" as="font" crossorigin>
<link rel="prefetch" href="/next-page.js" as="script">
3. WebAssembly 加速计算
// 调用 WASM 模块
const wasmModule = await WebAssembly.instantiateStreaming(
fetch('compute.wasm')
);
wasmModule.exports.heavyTask();
总结
从网络、渲染、js执行、工具链、性能监控,五方面进行性能调整
做到先测量再优化(用 Lighthouse 定位瓶颈),优先解决关键瓶颈(如 LCP > 2.5s),保持持续监控(接入 Sentry/自建监控)