出处:掘金
原作者:金泽宸
性能优化不是“事后修补”,而是系统架构中每一个决策点的结果
“页面很卡”、“首屏很慢”、“加载太久”、“滚动掉帧”——这些都是前端性能问题的常见表现
一个高级架构师不仅要能定位问题、给出方案、落地优化,更要具备系统性思维:把性能优化融入构建、路由、组件、渲染、交互、网络、缓存、部署等全链路
本篇我们将给出一张“性能优化地图”,并通过实战落地多个优化点,包括:
[构建层]
├─ Tree-shaking、按需加载、压缩、缓存拆包
[渲染层]
├─ SSR/CSR/SPA 混合渲染、虚拟列表、分片渲染
[交互层]
├─ 节流、防抖、懒加载、骨架屏
[网络层]
├─ CDN、缓存策略、预加载、并发控制
[运行层]
├─ lazy import、空闲加载、缓存池、service worker
[监控层]
└─ FCP、LCP、TTFB、FPS、Error 捕获
| 指标 | 含义 | 建议范围 |
|---|---|---|
| FCP | First Contentful Paint | < 1s |
| LCP | Largest Contentful Paint | < 2.5s |
| TTFB | Time to First Byte | < 0.5s |
| TTI | Time to Interactive | < 3s |
| FPS | 每秒帧数 | > 55fps |
| CLS | 页面偏移稳定性 | < 0.1 |
const Page = defineAsyncComponent(() => import('./BigPage.vue'))unplugin-vue-components)vite-plugin-imagemin)<Skeleton v-if="loading" />
<RealContent v-else />
const Home = defineAsyncComponent(() => import('./pages/Home.vue'))
<link rel="preload" href="/fonts/roboto.woff2" as="font" />
或使用 Vite 配置 rollupOptions.output.manualChunks 进行分包。
使用虚拟滚动(如 vue-virtual-scroller):
<VirtualList :item-count="list.length">
<template #default="{ index }">
{{ list[index].name }}
</template>
</VirtualList>
手动分页 + 分块渲染:
const chunkedData = list.slice(startIndex, endIndex)
| 问题 | 优化方式 |
|---|---|
| 快速滚动卡顿 | 使用 requestAnimationFrame 包装回调 |
| 持续输入抖动 | 使用 useDebounceFn / lodash.debounce |
| 多次点击触发请求 | 使用 throttle 控制频率 |
| 动画卡顿 | 使用 transform + will-change 减少 reflow |
技术建议:
cache-control, ETag)数据缓存建议:
swr, react-query, vue-query)localStorage 缓存接口数据 + 版本号判断requestIdleCallback(() => import('./heavy.js'))<TabPane v-if="active === 'b'" />接入推荐:
import { getLCP, getFID, getCLS } from 'web-vitals'
getLCP(console.log)
getFID(console.log)
getCLS(console.log)
| 目标 | 建议 |
|---|---|
| 发现性能问题 | 接入 web-vitals / Sentry trace 分析 |
| 控制代码体积 | 配置体积阈值报警,使用 visualizer 检查大模块 |
| 组件规范 | 所有组件必须支持懒加载、分页、lazy 渲染 |
| 提效流程 | 接入自动构建时间、首屏测速、部署前分析报告 |
| 性能 review | PR 检查 checklist 中加入“性能影响项” |