当前位置: 首页 > news >正文

JavaScript 性能优化实战:从 3 秒到 300 ms 的压缩与缓存之旅 - 教程

JavaScript 性能优化实战:从 3 秒到 300 ms 的压缩与缓存之旅

首发于 CSDN · 2025 年 11 月
原创:yu779
转载请注明来源与作者


1. 背景:为什么又要聊性能?

过去两年,我们团队把「首屏时间」从 3 s 压到 300 ms,真实业务、真实数据、真实收益
本文不讲“拍脑袋”的数字,直接上可落地的 10 个策略,并给出源码级对比线上 A/B 报告
读完你可以:

  1. 用 DevTools 3 分钟定位瓶颈;
  2. 让 vendors 包体积立减 60 %;
  3. 让二次访问直接 0 网络请求(离线可用)。

2. 指标:先定义“快”

指标目标工具
FCP(First Contentful Paint)< 1.0 sLighthouse
LCP(Largest Contentful Paint)< 1.2 sWebPageTest
TTI(Time to Interactive)< 2.0 sChrome DevTools
包体积(gzipped)< 200 KBwebpack-bundle-analyzer

3. 诊断:一条命令定位“真凶”

npx lighthouse https://my-site.com --view --preset=desktop

重点关注:

  • Opportunities → 按“节省体积”排序;
  • Diagnostics → 看 Main-thread Blocking Time;
  • Passed Audits → 反向排除已优化项。

4. 实战 10 策

#策略收益成本源码片段
1Tree-Shaking + sideEffects-35 %5 min见 4.1
2SplitChunks 自动分包-20 %10 min见 4.2
3动态 import() 懒加载-40 %20 min见 4.3
4HTTP/2 + preload-0.3 s1 h见 4.4
5Brotli 替代 gzip-25 %30 min见 4.5
6Service Worker 缓存0 请求1 h见 4.6
7图片 WebP + 自适应尺寸-60 %40 min见 4.7
8减少 polyfill-15 %15 min见 4.8
9长列表虚拟滚动FPS 55→6030 min见 4.9
10Vite 预构建依赖HMR < 200 ms20 min见 4.10

4.1 Tree-Shaking:让“死”代码消失

背景:lodash 默认全量引入,体积 70 KB。
解决:改成按需 + 标记 sideEffects。

// webpack.config.js
module.exports = {
mode: 'production',
optimization: {
usedExports: true,      // 启用 Tree-Shaking
sideEffects: false,     // 告诉 webpack 可以安全删除
},
};

package.json

{
"sideEffects": ["*.css", "*.less"]
}

结果:lodash 从 70 KB → 24 KB(gz)。

4.2 SplitChunks:让 vendors 永不重复

// webpack.config.js
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10,
reuseExistingChunk: true,
},
},
},
},

收益:多页应用共用 vendors.xxx.js,二次访问直接 304。

4.3 懒加载:路由级 + 组件级

// React 路由示例
import { lazy, Suspense } from 'react';
const HeavyChart = lazy(() => import(/* webpackChunkName: "chart" */ '@/components/HeavyChart'));
<Suspense fallback={<Skeleton />}><HeavyChart /></Suspense>

实测:首屏减少 42 KB(gz),LCP −320 ms。

4.4 HTTP/2 + preload:让关键资源插队

<!-- 放在 <head> 顶部 --><link rel="preload" href="/fonts/Inter.var.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="/js/app.xxx.js" as="script">

注意:HTTP/1.1 时代合并,HTTP/2 时代拆细+多路复用收益更大。

4.5 Brotli:一行 Nginx 配置,体积再减 25 %

# /etc/nginx/conf.d/gzip.conf
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/javascript application/json image/svg+xml;

4.6 Service Worker:离线也能秒开

用 Workbox 零成本接入:

npm i workbox-webpack-plugin -D
// webpack.config.js
const { GenerateSW } = require('workbox-webpack-plugin');
plugins.push(
new GenerateSW({
runtimeCaching: [{
urlPattern: /^https:\/\/api\.mycdn\.com/,
handler: 'StaleWhileRevalidate',
options: { cacheName: 'api-cache', expiration: { maxEntries: 200 } },
}],
})
);

效果:二次访问 0 网络请求,TTI 从 1.8 s → 280 ms。

4.7 图片:WebP + 自适应尺寸

<picture><source srcset="/img/hero-800.webp" media="(max-width: 600px)" type="image/webp"><source srcset="/img/hero-1600.webp" media="(min-width: 601px)" type="image/webp"><img src="/img/hero-1600.jpg" alt="hero" loading="lazy" width="1600" height="600"></picture>

收益:同画质下体积 −60 %;Lighthouse「Serve images in next-gen formats」直接满分。

4.8 减少 polyfill:core-js 按需 + browserslist

// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage',
corejs: 3,
targets: { browsers: ['>0.2%', 'not dead', 'not op_mini all'] },
}],
],
};

结果:core-js 从 35 KB → 8 KB(gz)。

4.9 长列表虚拟滚动:react-window 示例

import { FixedSizeList } from 'react-window';
<FixedSizeList height={600} itemCount={10000} itemSize={50}>{({ index, style }) => <div style={style}>Row {index}</div>}</FixedSizeList>

FPS:从 38 提升到 60,卡顿消失。

4.10 Vite 预构建:让依赖秒级更新

Vite 默认把 node_modules 预构建成 ESM + HTTP 缓存,HMR 200 ms 内。
技巧:把稳定依赖锁定到 optimizeDeps.include,避免重复扫描。

// vite.config.ts
export default {
optimizeDeps: {
include: ['lodash-es', 'axios', 'dayjs'],
},
};

5. 监控:把“快”变成常态

  1. Lighthouse CI 接入 GitHub Actions,MR 阶段自动跑分;
  2. Web-Vitals 上报到 Prometheus + Grafana,告警阈值:LCP > 1.5 s;
  3. Bundle-Analyzer 每次构建后输出 diff,体积增长 > 5 % 自动评论提醒。

6. 结果:数据说话

版本包体积(gz)FCPLCPTTI离线可用
v1.0487 KB2.1 s2.8 s3.0 s×
v2.0192 KB0.8 s1.0 s1.2 s

注:同一页面、同一服务器、同一时间段 A/B 测试,样本 20 k PV。

7. 常见误区 Top 3

  1. “一把梭”上 HTTP/3 → 先确认内核、CDN、证书链全支持,否则反而 2-RTT 握手退化;
  2. “迷信压缩比” → Brotli 11 级压缩耗时 800 ms,得不偿失,6 级是甜点;
  3. “SW 缓存越多越好” → 缓存策略不清会导致用户永远拿不到新版,版本号 + 主动清理是关键。

总结:性能是“减”出来的

优化不是加东西,而是敢删、会删、删得安全。
把本文 10 策做成 checklist,下次发版前跑一遍,90 分钟换 3 倍性能提升,不香吗?

http://www.jsqmd.com/news/94858/

相关文章:

  • Git tag标记Qwen-Image-Edit-2509重要版本里程碑
  • 【数据库】MySQL的安装与卸载 - 实践
  • 【Dify解惑】如何在 Dify 中实现“来源可追溯”:回答里自动附带引用文档和段落?
  • GTN损伤模型在金属成型中的实战改造手记
  • 【问题】--Todesk相关问题
  • 江苏 AI 营销讲师领航者汤羽:以数智之力,赋能品牌破局增长 - 资讯焦点
  • 江苏 AI 营销讲师领航者汤羽:以数智之力,赋能品牌破局增长 - 资讯焦点
  • 从关系型数据库到时序数据库的思维转变
  • C#字典操作与类对象全解析
  • jwt简介
  • 重生归来,我要成功 Python 高手--day44 迁移学习 Fasttext 文本分类 词向量
  • 3D 创作工具 Cinema4D 2025官方下载安装教程(含核心功能+入门实操+常见问题)
  • C#+VisionMaster联合开发控件篇(七)_参数配置带渲染控件
  • 直播回放 | IDMP 无问智推技术详解
  • 看到有人说,不要有新的编程语言了
  • 人工智能数据投毒风险上升:企业必须重视的 AI 安全隐患 - 资讯焦点
  • 高压直流输电Matlab仿真模型:LCC-HVDC 500kv与800kv电压等级下的控制切换仿真
  • 网络安全论坛、会议
  • mysql —— Ubuntu —— 第一次登入,如何设置密码
  • C#+VisionMaster联合开发控件篇(六)_参数配置控件
  • Linux系统编程——进程进阶:exec 族、system 与工作路径操作
  • 2025年北京优质deepseek优化服务商全景指南:助力企业抢占AI流量新赛道 - 品牌2025
  • C#+VisionMaster联合开发控件篇(五)_全局相机控件
  • ROS2核心概念之参数
  • 小程序商城工具挑选指南:功能、生态与商家需求解析
  • 2025年主流GEO服务商全景指南:助力企业抢占AI平台流量红利 - 品牌2025
  • 【第57套】一天两套,继续冲刺!
  • 异常机制
  • P3629 [APIO2010] 巡逻
  • AI 时代 GEO 营销先锋盘点:五大服务商助力 ToB 企业精准获客 - 品牌2025