哈喽大家好,我是你们爱折腾工具的 效率喵!🐾
平时大家在前端群里经常能看到这样的名场面:“救命!上线后包体积炸了!”、“谁偷偷引了整个 lodash 没配按需加载?!”
很多团队做性能优化,就像消防员灭火——页面卡了才去开 Chrome DevTools 抓 Performance,Lighthouse 跑分变红了才通宵排查。但在效率控眼里,被动救火永远是最低效的!
今天本喵就来给大家安利一套 「前端工程化·性能防御体系」。核心逻辑就是 Shift Left(左移防御):把性能隐患扼杀在敲代码和 PR 阶段,直接让 CI 机器人帮你当守门员!
防线 01:代码提交期 —— 给体积装上“红外报警器”
优化必须从本地提交抓起。很多时候体积失控,就是手滑引了个几十 KB 的工具库。这时候就需要我们的神器:Size Limit!
🛠️ 工具安利:size-limit + husky
size-limit 是专门用来防止打包体积膨胀的 CLI 工具。它不仅算 gzip 体积,还能算出 JS 在中端手机上的预估执行时间!
在 package.json 里配置:
{
"size-limit": [
{
"path": "dist/assets/index-*.js",
"limit": "150 kB"
},
{
"name": "首屏关键 CSS",
"path": "dist/assets/index-*.css",
"limit": "30 kB"
}
],
"scripts": {
"size": "size-limit"
}
}
配合 lint-staged 和 husky,在 git commit 时直接做卡点校验:
# 如果超过了 150 kB,直接报错中断提交!
npx size-limit
喵的体验测评:对比过手写脚本计算
stat.size,size-limit最爽的一点是它自带依赖归因(结合--why参数),直接可视化告诉你到底是哪个 NPM 包把体积顶爆了,排查体验极佳。
防线 02:本地构建期 —— 编译时“透视眼”与规范约束
写代码时手不能抖,很多性能隐患(比如未命中的 Tree-shaking)完全可以用 Lint 和插件前置拦截。
1. ESLint 规则防御:别把无用代码带进包里
安利安装 eslint-plugin-import 和 eslint-plugin-lodash:
// .eslintrc.cjs
module.exports = {
rules: {
// 强制阻止全量引入 lodash
'lodash/import-scope': ['error', 'method'],
// 限制重复导出与无用模块
'import/no-duplicates': 'error',
'import/no-cycle': 'error', // 循环依赖会导致 Tree-shaking 失效
}
};
2. 打包分析插件常态化
不要等包大了再去临时安插件!推荐在 vite.config.ts 里直接接上 rollup-plugin-visualizer:
// vite.config.ts
import { defineConfig } from 'vite';
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
visualizer({
open: false, // 别每次 build 都弹窗打扰思路
filename: 'dist/stats.html',
gzipSize: true,
brotliSize: true,
}),
],
});
把 stats.html 加进 .gitignore,每次跑构建本地留底,随时双击看模块占比,心里有数。
防线 03:CI / CD 阶段 —— 让 GitHub Actions 成为无情守门人
单靠程序员自觉是不靠谱的,性能防御的王牌一定是 CI 自动化门禁。
🛠️ 神器推荐:Lighthouse CI (@lhci/cli)
把 Google Lighthouse 搬进 GitHub Actions,如果 PR 让分数掉下预警线,直接 Block Merge(禁止合入)!
在根目录配置 .lighthouserc.json:
{
"ci": {
"collect": {
"startServerCommand": "npm run preview",
"url": ["http://localhost:4173/"],
"numberOfRuns": 3
},
"assert": {
"assertions": {
"categories:performance": ["error", { "minScore": 0.85 }],
"first-contentful-paint": ["warn", { "maxNumericValue": 2000 }],
"interactive": ["error", { "maxNumericValue": 3500 }],
"uses-responsive-images": "warn"
}
},
"upload": {
"target": "temporary-public-storage"
}
}
}
配合 GitHub Actions 工作流(.github/workflows/perf-ci.yml):
name: Performance Guard
on: [pull_request]
jobs:
lhci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install & Build
run: |
npm ci
npm run build
- name: Run Lighthouse CI
run: |
npm install -g @lhci/cli@0.13.x
lhci autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
效果拔群:提 PR 的时候,机器人会自动跑 3 次取平均值并在 PR 下面留言,性能下降直接红标报错,产品经理和 Reviewer 看得清清楚楚!
防线 04:线上运行时 —— 真实指标埋点(RUM 防御)
前面都是合成测试(Lab Data),真实用户的网络千奇百怪,所以最后一步是 真实用户监控(RUM)。
Google 官方的 web-vitals 库极其轻量(只有 1-2 KB),无痛注入全套 Core Web Vitals 指标:
// src/monitor/perf.ts
import { onLCP, onINP, onCLS } from 'web-vitals';
interface MetricPayload {
name: string;
value: number;
rating: 'good' | 'needs-improvement' | 'poor';
}
function sendToAnalytics(metric: MetricPayload) {
const body = JSON.stringify({
metricName: metric.name,
metricValue: Math.round(metric.value),
rating: metric.rating,
path: window.location.pathname,
});
// 使用 sendBeacon 保证在页面卸载时也能可靠发送,不阻塞主线程
if (navigator.sendBeacon) {
navigator.sendBeacon('/api/perf-metric', body);
} else {
fetch('/api/perf-metric', { body, method: 'POST', keepalive: true });
}
}
// 监听三大核心指标:最大内容绘制、交互延迟、累积布局偏移
export function initPerformanceDefense() {
onLCP(sendToAnalytics);
onINP(sendToAnalytics); // 替代了 FID 的全新交互性能指标!
onCLS(sendToAnalytics);
}
配合 Grafana 或自建看板,如果某次发版后 INP 或 CLS 突增,立刻告警触发回滚,根本不用等用户来发工单骂街。
效率喵的装配清单 (Summary Checklist)
最后照例给大家拉一个 开箱即用清单,建议直接收进你们团队的 Engineering Guidelines:
- Git 提交层:配置
size-limit,把入口包体积上限钉死。 - 代码规范层:开启循环依赖检测与按需加载 Lint 插件。
- 构建产物层:常驻打包体积可视化脚本,监控 Chunk 分割效果。
- CI 流水线层:配置 Lighthouse CI,分数不达标一律 Reject PR。
- 线上观测层:轻量接入
web-vitals,用sendBeacon悄悄上报真实指标。
把性能做成自动化流水线,才是前端打工人摸鱼...啊不对,高效开发的真正奥义!大家目前团队里都有配哪些性能防御工具?欢迎在评论区和喵一起交流踩坑经验喵~ 🐾
License: CC BY-NC 4.0
Updated 13 hours ago
Was this article helpful? Give it a like.
0 comments


