前端性能优化指南——从加载到渲染的全面提速
作者: CaoZH
日期: 2025-04-15
本文为原创教程
前端性能优化是一个老生常谈但又永不过时的话题。2025 年,用户对页面加载速度的期望值更高了——超过 3 秒加载的页面,53% 的用户会选择离开。
本文按照「网络加载 → 资源优化 → 渲染优化 → 运行时优化」的路径,系统性地梳理前端性能优化的方法。
一、测量指标
核心 Web 指标(Core Web Vitals)
| 指标 |
全称 |
含义 |
理想值 |
| LCP |
Largest Contentful Paint |
最大内容绘制 |
< 2.5s |
| FID |
First Input Delay |
首次输入延迟 |
< 100ms |
| CLS |
Cumulative Layout Shift |
累计布局偏移 |
< 0.1 |
其他重要指标
1 2 3 4
| - FCP(First Contentful Paint):首次内容绘制 < 1.8s - TTFB(Time to First Byte):首字节时间 < 800ms - TBT(Total Blocking Time):总阻塞时间 < 200ms - SI(Speed Index):速度指数 < 3.4s
|
测量工具
1 2 3 4 5 6 7 8
| npx lighthouse https://your-site.com --view
|
二、网络层面优化
1. 启用 HTTP/2
1 2 3 4 5
| server { listen 443 ssl http2; }
|
HTTP/2 支持多路复用,一个连接并行请求,大幅减少连接开销。
2. 启用 Gzip / Brotli 压缩
1 2 3 4 5 6 7 8 9 10 11
| gzip on; gzip_types text/plain text/css application/json application/javascript image/svg+xml; gzip_min_length 1000; gzip_comp_level 6; gzip_vary on;
brotli on; brotli_types text/plain text/css application/json application/javascript; brotli_comp_level 6;
|
3. 使用 CDN
1 2 3
| - 静态资源(JS/CSS/图片)走 CDN - 推荐:Cloudflare(免费)、阿里云 CDN、AWS CloudFront - 效果:减少 TTFB,全球加速
|
4. 资源预加载
1 2 3 4 5 6 7 8 9 10 11
| <link rel="dns-prefetch" href="//api.example.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preload" href="font.woff2" as="font" crossorigin>
<link rel="prefetch" href="/next-page.html">
|
三、资源优化
1. 图片优化
1 2 3 4 5 6 7 8 9
| ## 格式选择 - 照片:WebP / AVIF(比 JPEG 小 30-50%) - 图标/Logo:SVG - 截图:WebP
## 工具 - Sharp(Node.js):npm install sharp - imagemin:npm install imagemin - squoosh.app:在线压缩
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { defineConfig } from 'vite' import imagemin from 'vite-plugin-imagemin'
export default defineConfig({ plugins: [ imagemin({ gifsicle: { optimizationLevel: 7 }, mozjpeg: { quality: 80 }, pngquant: { quality: [0.8, 0.9] }, webp: { quality: 80 } }) ] })
|
2. 代码分割
1 2 3 4 5 6 7 8
| const UserList = React.lazy(() => import('./UserList'));
const UserList = defineAsyncComponent(() => import('./UserList.vue'));
import( './admin.js')
|
3. Tree Shaking
1 2 3 4 5 6 7 8
| { "sideEffects": false }
|
四、渲染优化
1. 关键渲染路径
1 2 3 4 5 6 7 8 9 10
|
<style> .header { ... } .hero { ... } </style>
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
|
2. 虚拟滚动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!-- 长列表优化(1000+ 条数据) --> <script setup> import { VirtualScroller } from 'vue-virtual-scroller'
// 万级列表只渲染可见区域的 DOM,大幅减少渲染开销 </script>
<template> <VirtualScroller :items="list" :item-height="50" :buffer="200" > <template #default="{ item }"> <div class="item">{{ item.name }}</div> </template> </VirtualScroller> </template>
|
3. 避免布局抖动
1 2 3 4 5 6 7 8 9 10 11
| .image-container { width: 100%; aspect-ratio: 16 / 9; }
.animated { transition: transform 0.3s ease; }
|
五、运行时优化
1. 减少重渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <script setup> import { computed, shallowRef } from 'vue'
// 使用 computed 缓存计算结果 const totalPrice = computed(() => { return items.value.reduce((sum, item) => sum + item.price, 0) })
// 大数组使用 shallowRef const userList = shallowRef([])
// v-memo 避免不必要的渲染 </script>
<template> <div v-for="item in list" :key="item.id" v-memo="[item.name, item.price]"> {{ item.name }} - {{ item.price }} </div> </template>
|
2. Web Worker
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| self.onmessage = function(e) { const result = heavyCalculation(e.data) self.postMessage(result) }
function heavyCalculation(data) { return data.map(item => processItem(item)) }
const worker = new Worker('worker.js') worker.postMessage(largeData) worker.onmessage = (e) => { console.log('处理完成:', e.data) }
|
3. 防抖与节流
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script setup> import { debounce, throttle } from 'lodash-es'
// 搜索输入:用户停止输入后再请求 const search = debounce(async (keyword) => { const results = await api.search(keyword) searchResults.value = results }, 300)
// 滚动事件:限制触发频率 const handleScroll = throttle(() => { // 处理滚动 }, 100) </script>
|
六、构建工具配置
Vite 优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import { defineConfig } from 'vite'
export default defineConfig({ build: { target: 'es2020', minify: 'esbuild', cssMinify: 'lightningcss', rollupOptions: { output: { manualChunks: { vendor: ['vue', 'vue-router', 'pinia'], ui: ['ant-design-vue'], charts: ['echarts'] } } } } })
|
七、总结
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ## 优化的黄金法则
1. 先测量,后优化(用 Lighthouse 找到瓶颈) 2. 80% 的收益来自 20% 的工作(图片 + 代码分割 + 缓存) 3. 不要过度优化(代码可维护性 > 极致性能)
## 快速检查清单
□ 图片使用 WebP 格式 □ 启用 Gzip/Brotli 压缩 □ 关键 CSS 内联 □ 路由懒加载 □ 静态资源走 CDN □ 合理使用缓存策略 □ 虚拟滚动处理长列表 □ 减少不必要的重渲染
|
首发于 CaoZH 的笔记