浏览器已经是超级计算机。只要你问一下。

发布: (2026年3月20日 GMT+8 01:17)
6 分钟阅读
原文: Dev.to

Source: Dev.to

开发者花费数小时配置构建工具、审计依赖并争论 bundle 大小——结果却是把已经内置在浏览器中、完整构建、完全免费且随时可用的功能直接交付。无需 npm install。无需从 CDN 导入。无需第三方信任。

下面列出其中的十项功能。每一项都已准备好用于生产,得到广泛支持,且足够强大,能够取代你今天可能会去寻找的库。

1. Fetch + Streams API

fetch 是 HTTP 请求的标准。结合 Streams API,你可以在数据到达时进行处理——这正是 AI token 流式传输的工作方式。

2. Web Workers

JavaScript 在单线程上运行。Web Workers 为你提供第二条线程,让繁重的任务(解析、加密、数据处理)在后台运行,而不会冻结 UI。

// Worker code must live in its own scope — use a Blob URL to inline it
const code = `
  self.onmessage = ({ data }) => {
    const result = data.map(n => n * 2);
    self.postMessage(result);
  };
`;

const blob = new Blob([code], { type: 'application/javascript' });
const worker = new Worker(URL.createObjectURL(blob));

worker.postMessage([1, 2, 3, 4, 5]);
worker.onmessage = e => console.log('Done:', e.data); // [2, 4, 6, 8, 10]

3. IntersectionObserver

当元素进入或离开视口时触发回调。处理懒加载和滚动动画的正确方式——无需滚动事件监听器。

const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.2 });

document.querySelectorAll('.card').forEach(el => observer.observe(el));

4. IndexedDB

浏览器中的完整异步数据库。可存储结构化数据、二进制大对象(blob)和文件——远超 localStorage 的能力。

const request = indexedDB.open('AppDB', 1);

request.onupgradeneeded = e => {
  e.target.result.createObjectStore('notes', { autoIncrement: true });
};

request.onsuccess = e => {
  const db = e.target.result;
  const tx = db.transaction('notes', 'readwrite');
  tx.objectStore('notes').add({ text: 'Hello', date: Date.now() });
};

5. WebSocket

一种在浏览器和服务器之间持久的双向连接。任一方都可以随时发送消息——非常适用于聊天、实时仪表盘和多人游戏。

const ws = new WebSocket('wss://your-server.com/socket');

ws.onopen    = () => ws.send(JSON.stringify({ type: 'hello' }));
ws.onmessage = e => console.log(JSON.parse(e.data));
ws.onclose   = () => console.log('Disconnected');

6. 文件系统访问 API

读取和写入用户磁盘上的真实文件(需获得权限)。使能够在浏览器中完整运行的桌面级编辑器和工具成为可能。

async function openAndSave() {
  const [handle] = await window.showOpenFilePicker();
  const file = await handle.getFile();
  const text = await file.text();

  const edited = text + '\n// edited';
  const writable = await handle.createWritable();
  await writable.write(edited);
  await writable.close();
}

// Call the function, e.g. on a button click
// openAndSave();

7. Canvas 与 OffscreenCanvas

Canvas 为你提供像素级别的绘图。OffscreenCanvas 将渲染移到 Worker 中进行,从而使图形渲染永不与主线程竞争。

const ctx = document.getElementById('c').getContext('2d');

function draw(t) {
  ctx.clearRect(0, 0, 400, 200);
  ctx.fillStyle = '#c8f542';
  ctx.beginPath();
  ctx.arc(200 + Math.sin(t / 500) * 150, 100, 20, 0, Math.PI * 2);
  ctx.fill();
  requestAnimationFrame(draw);
}

requestAnimationFrame(draw);

8. MediaDevices & MediaRecorder

访问摄像头、麦克风或屏幕,并记录所有传入的内容——无需第三方 SDK。

const audio = document.getElementById('playback');
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const recorder = new MediaRecorder(stream);
const chunks = [];

recorder.ondataavailable = e => chunks.push(e.data);
recorder.onstop = () => {
  const blob = new Blob(chunks, { type: 'audio/webm' });
  audio.src = URL.createObjectURL(blob);
};

recorder.start();
setTimeout(() => recorder.stop(), 5000); // record for 5 seconds

9. requestAnimationFrame + Performance API

requestAnimationFrame 将你的代码与屏幕刷新率同步。Performance API 以亚毫秒精度测量经过的时间。两者结合可实现平滑、精准的动画。

const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
let x = 0;
let last = 0;

function loop(timestamp) {
  const delta = timestamp - last;
  last = timestamp;

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  x = (x + 200 * (delta / 1000)) % canvas.width;

  ctx.beginPath();
  ctx.arc(x, canvas.height / 2, 16, 0, Math.PI * 2);
  ctx.fillStyle = '#c8f542';
  ctx.fill();

  requestAnimationFrame(loop);
}

requestAnimationFrame(loop);

10. BroadcastChannel

让同源的标签页、窗口和 worker 能够即时通信。同步认证状态、共享缓存更新,或在多个打开的标签页之间协调 UI——无需服务器。

const channel = new BroadcastChannel('app');

// Send from any tab
channel.postMessage({ type: 'logout' });

// Receive in every other tab
channel.onmessage = ({ data }) => {
  if (data.type === 'logout') redirectToLogin();
};

要点

这些 API 都不需要 npm、添加到你的 bundle 中,也不依赖第三方代码。它们已经内置在所有现代浏览器中多年——因此你可以更快发布,保持 bundle 体积小,并且完全掌控你的应用。

在寻找库之前,值得先问问平台是否已经提供了你需要的功能。通常情况下,它们已经有了。

今天你学到了有价值的东西吗?

Muhammad Usman
Developer’s Journey – 展示你的支持。

0 浏览
Back to Blog

相关文章

阅读更多 »