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

JavaScript 性能优化实战(易懂版)

JavaScript 性能优化实战(易懂版)

适用对象:前端与全栈工程师。原则:先测量、再优化、可回归。

目录

  • TL;DR 快速清单
    1. 度量与预算
    1. 网络与缓存优化
    1. 构建与代码分割
    1. 运行时与调度
    1. DOM 渲染优化
    1. 内存与泄漏
    1. 并行与重活卸载
    1. Node.js 端优化
    1. 诊断剧本
  • 附录:工具与参考

TL;DR 快速清单

  • 指标:LCP < 2.5s,INP < 200ms,CLS < 0.1
  • 传输:HTTP/2/3 + CDN + Brotli;预连接/预加载关键资源
  • 缓存:静态资源指纹 + immutable;HTML 短缓存 + ETag
  • 包体:首屏 JS ≤ 150–200KB gzip;路由级代码分割;移除大依赖
  • 渲染:transform/opacity 动画;列表虚拟化;被动事件 + 节流/防抖
  • 调度:rAF/Idle/切片;避免长任务阻塞主线程
  • 内存:清理监听/计时器;WeakMap;LRU 缓存
  • 并行:Web Worker + Transferable;OffscreenCanvas
  • 回归:web-vitals RUM + Lighthouse CI + Bundle 预算

1. 度量与预算

核心指标与采集(RUM)

// 使用 web-vitals/attribution 采集 LCP/INP/CLS(含归因)
import { onLCP, onINP, onCLS } from 'web-vitals/attribution';const send = (m) => {navigator.sendBeacon('/vitals', JSON.stringify({name: m.name, value: m.value, id: m.id,path: location.pathname, ts: Date.now(),attribution: m.attribution}));
};onLCP(send, { reportAllChanges: true });
onINP(send, { reportAllChanges: true });
onCLS(send, { reportAllChanges: true });

性能预算建议

  • 首屏 JS(可执行)≤ 150–200KB gzip
  • LCP 资源(图/字体)≤ 100KB;关键请求数 ≤ 6
  • CI 设置:Lighthouse 得分门槛 + bundle 体积上限

2. 网络与缓存优化

HTML 预连接/预加载与图片懒加载

<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<link rel="preload" as="style" href="/styles.css">
<link rel="preload" as="script" href="/entry.js" crossorigin>
<img src="hero.avif" srcset="hero@2x.avif 2x" alt="hero" loading="lazy" decoding="async">

按用户意图预取

// 悬停时预取下一步页面资源
const prefetch = (href, as) => {const l = document.createElement('link');l.rel = 'prefetch'; l.href = href; if (as) l.as = as;document.head.appendChild(l);
};
document.addEventListener('mouseover', e => {const more = e.target.closest('#more');if (more) prefetch('/page/product.js', 'script');
}, { passive: true });

Service Worker:静态 Cache First + API Stale-While-Revalidate

// sw.js
const STATIC = 'static-v1';
self.addEventListener('install', e => {e.waitUntil(caches.open(STATIC).then(c => c.addAll(['/', '/index.html', '/styles.css', '/entry.js'])));self.skipWaiting();
});
self.addEventListener('activate', e => {e.waitUntil(caches.keys().then(keys => Promise.all(keys.filter(k => k !== STATIC).map(k => caches.delete(k)))).then(() => self.clients.claim()));
});
self.addEventListener('fetch', e => {const req = e.request; if (req.method 
http://www.dtcms.com/a/340972.html

相关文章:

  • InfluxDB 查询性能优化实战(一)
  • 【PSINS工具箱】平面上的组合导航,观测量为位置、速度、航向角。附完整的MATLAB代码
  • sqli-labs通关笔记-第58关 GET字符型报错注入(单引号闭合 限制5次探测机会)
  • 六大缓存(Caching)策略揭秘:延迟与复杂性的完美平衡
  • git-git submodule和git subtree的使用方式
  • 大规模IP轮换对网站的影响(服务器压力、风控)
  • CISP-PTE之路--05文
  • 企业微信2025年发布会新功能解读:企业微信AI——2025年企业协作的「最优解」是如何炼成的?
  • 跨境电商独立站搭建多少钱?响应式设计 + 全球 CDN 加速服务
  • IBMS系统集成平台具备哪些管理优势?核心价值体现在哪里?
  • HTTP/1.1 与 HTTP/2 全面对比:性能革命的深度解析
  • 工控PID控制器学习总结
  • [element-plus] el-tree 拖拽到其他地方,不拖拽到树上
  • 怎么确定mongodb是不是链接上了?
  • 疏老师-python训练营-day51复习日+退款开始
  • AP数学课程AB和BC怎么选?AP数学课程培训机构推荐哪家?
  • Git 新手完全指南(一):从零开始掌握版本控制
  • .gitignore 文件 记录
  • git报错解决:ssh: connect to host github.com port 22: Connection refused
  • 阶跃星辰 StepFun 入驻 GitCode 平台,带来工业级 AI 体验
  • macos 多个版本的jdk
  • 版本软件下载电脑适配说明
  • 【数据类型】
  • UE5 PCG 笔记(二) Difference 节点
  • 从天线到芯片封装,CST如何赋能高频设计全流程
  • MySQL程序和选项文件配置
  • 【Coze】Windows 环境下使用 Docker 部署 Coze Studio 的详细指南
  • 力扣面试150(61/100)
  • Leetcode 深度优先搜索 (11)
  • AI +金融 = 七大核心维度+ 落地典型困难