#用这 9 个浏览器 API,我把页面从“卡成 PPT”救回到 90+(每个都有能直接抄的例子)

你有没有遇到过这种场景:

  • 首屏 3 秒起步,用户一滑就掉帧
  • 列表一长就发烫,点个按钮都要"思考人生"
  • QA 一句"你这页面怎么这么卡",直接把你送进性能优化地狱

我后来发现一个很反直觉的真相:性能优化不是靠"少写点代码",而是靠"把重活交给浏览器做"。

现代浏览器给了我们一堆"外挂级 API",用对地方,提升肉眼可见。

下面这 9 个 API,就是我最常用的一套"性能急救包"。每个都给你通俗解释 + 直接可用的例子。内容参考了原文的核心结构与示例。


01|IntersectionObserver:懒加载别再 scroll 监听了(真的会卡)

人话解释:

以前你监听 scroll,每滚一下就算一堆位置,主线程很容易被打爆。
IntersectionObserver 直接让浏览器告诉你: "这个元素进视口了没?" ------ 省心还省性能。

最常用:图片懒加载

ini 复制代码
// 观察器:当元素进入视口就触发
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;     // 真正开始加载
      observer.unobserve(img);       // 用完就取消观察,避免重复触发
    }
  });
});

// 让所有 img[data-src] 都被观察
document.querySelectorAll("img[data-src]").forEach((img) => {
  observer.observe(img);
});

小技巧:

  • 别忘了 unobserve,不然一直观察也会有开销。

02|requestIdleCallback:把"非关键任务"放到浏览器空闲时做

人话解释:

埋点上报、预加载、缓存清理这些事很重要,但不急。
requestIdleCallback 的意思就是: "你先让用户操作顺滑,空了我再做这些杂活。"

例子:空闲时上报 + 预加载

scss 复制代码
requestIdleCallback(() => {
  sendAnalytics();        // 埋点上报
  preloadNextPage();      // 预加载下一页资源/数据
});

注意:

  • 它是"尽量空闲就做",不是"保证立刻执行",关键逻辑别放这里。

03|requestAnimationFrame:动画就该跟着屏幕刷新走

人话解释:
setTimeout 做动画很容易掉帧、抖动。
requestAnimationFrame(简称 rAF)会在浏览器下一帧渲染前回调,天然顺滑。页面切后台还会自动降速/暂停。

例子:从 0 移动到 200

ini 复制代码
let x = 0;
function animate() {
  x += 2;
  element.style.transform = `translateX(${x}px)`;

  if (x < 200) {
    requestAnimationFrame(animate);
  }
}

requestAnimationFrame(animate);

04|ResizeObserver:监听"某个元素"尺寸变化(不是只能监听窗口)

人话解释:

你想监听一个容器变宽变窄(比如图表容器、拖拽面板),用 window.resize 不靠谱。
ResizeObserver 可以监听任意元素的尺寸变化。

例子:容器变化就重绘图表

javascript 复制代码
const ro = new ResizeObserver((entries) => {
  entries.forEach((entry) => {
    const { width, height } = entry.contentRect;
    console.log("新尺寸:", width, height);
    // chart.resize(width, height); // 你的图表重绘逻辑
  });
});

ro.observe(document.getElementById("chart-container"));

05|performance.now():别用 Date.now 测性能了(不够准)

人话解释:

性能优化最怕"我感觉快了"。
performance.now() 是高精度计时(更准),适合测函数耗时。

例子:测一段重逻辑执行时间

ini 复制代码
const start = performance.now();

heavyCalculation(); // 你的耗时逻辑

const end = performance.now();
console.log(`耗时:${end - start}ms`);

06|preload & prefetch:资源加载顺序,决定首屏生死

人话解释:

很多页面慢不是因为 JS 慢,而是关键资源没优先加载

  • preload:这个资源很关键,现在就优先拉
  • prefetch:这个资源以后可能用,有空再偷偷下

例子:preload 首屏关键 CSS / 字体

ini 复制代码
<link rel="preload" href="/styles/critical.css" as="style">
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>

例子:prefetch 下一页可能用到的 JS

ini 复制代码
<link rel="prefetch" href="/chunks/profile-page.js">

07|Cache API + Service Worker:二次访问快到离谱,甚至离线可用

人话解释:

第一次访问走网络,第二次直接走缓存,体验会"突然变快"。

Service Worker 可以拦截请求,Cache API 负责存/取缓存。

例子:优先缓存命中,否则走网络(最常见)

csharp 复制代码
// service-worker.js
self.addEventListener("fetch", (event) => {
  event.respondWith(
    caches.match(event.request).then((cached) => {
      return cached || fetch(event.request);
    })
  );
});

补一句重点:

  • 真上线要做版本管理,否则会出现"怎么还在用旧资源"。

08|Web Worker:主线程别硬扛大计算(卡死就靠它救)

人话解释:

页面卡死,最常见原因就是:主线程在算大数据/做重逻辑

Worker 可以把计算放到后台线程,主线程继续流畅响应点击/滚动。

例子:主线程发数据 → Worker 处理 → 回传结果

main.js(主线程)

ini 复制代码
const worker = new Worker("worker.js");

worker.postMessage(hugeData);

worker.onmessage = (e) => {
  console.log("处理完成:", e.data);
};

worker.js(后台线程)

ini 复制代码
self.onmessage = (e) => {
  const result = heavyProcess(e.data); // 大计算
  self.postMessage(result);
};

09|document.visibilityState:页面切后台,就别浪费资源了

人话解释:

用户切到别的标签页,你的页面还在轮询接口、跑动画、刷新数据------这就是"暗地里烧钱"。
visibilityState 能告诉你页面是否在前台:后台就停,回来再恢复。

例子:后台暂停轮询/视频,前台恢复

scss 复制代码
document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "hidden") {
    stopPolling();   // 停止轮询
    stopVideo();     // 暂停视频/动画
  } else {
    resumePolling(); // 恢复轮询
    resumeVideo();   // 恢复视频/动画
  }
});

最后:照这个顺序上手,最快见效

如果你想"今天改一点,今天就变快",推荐顺序:

  1. IntersectionObserver(懒加载先做对)
  2. preload / prefetch(首屏关键资源优先)
  3. visibilityState(后台节流,省电省钱)
  4. requestAnimationFrame(动画丝滑)
  5. Web Worker(大计算别卡主线程)
  6. Service Worker + Cache(二次访问起飞)

相关推荐
zzjyr2 小时前
@umijs/max 中导出的 request 方法,如何实现 GET/POST/PUT/DELETE 这四种核心请求
前端
zzjyr2 小时前
基于 @umijs/max 的 request 补充常见错误统一处理、请求取消、重复请求防抖的完整方案
前端
拖拉斯旋风2 小时前
深入浅出 RAG:从网页爬取到智能问答的完整链路解析
前端
Mintopia2 小时前
Vite 发展现状与回顾:从“极致开发体验”到生态基础设施
前端
前端双越老师2 小时前
前端面试常见的 10 个场景题
前端·面试·求职
孟祥_成都3 小时前
【全网最通俗!新手到AI全栈开发必读】 AI 是如何进化到大模型的
前端·人工智能·全栈
牛奶4 小时前
AI辅助开发的基础概念
前端·人工智能·ai编程
摸鱼的春哥4 小时前
Agent教程15:认识LangChain,Agent框架的王(上)
前端·javascript·后端
明月_清风5 小时前
自定义右键菜单:在项目里实现“选中文字即刻生成新提示”
前端·javascript