JavaScript的秘密生活:观察者

发布: (2026年3月10日 GMT+8 12:45)
3 分钟阅读
原文: Dev.to

Source: Dev.to

Timothy 靠在椅子上,听着笔记本风扇突然的、刺耳的嗡鸣。他刚刚为一个巨大的用户头像网格实现了懒加载功能。

“滚动非常流畅,” Timothy 边说边轻点屏幕。“我用了我们昨天讨论过的 { passive: true } 标记。合成线程完全没有被阻塞。但我的 CPU 使用率瞬间飙到 90%,笔记本的风扇好像要起飞了。”

Margaret 手里端着咖啡走了过来,瞄了一眼他副屏上的性能监视器。

“你成功解放了列车,” Margaret 点头看着屏幕说。“但你在折磨调度员。”


滚动轮询的问题

负责懒加载的代码直接绑定在 scroll 事件上:

const images = document.querySelectorAll('img[data-src]');

window.addEventListener('scroll', () => {
  images.forEach(img => {
    // Calculate exact geometry on every scroll tick
    const rect = img.getBoundingClientRect();

    // If the image enters the viewport, load it
    if (rect.top  {
  entries.forEach(entry => {
    // 2. Callback when the element intersects
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src; // Load the image

      // 3. Stop observing once the image has loaded
      observer.unobserve(img);
    }
  });
}, options);

// 4. Register all images with the observer
images.forEach(img => observer.observe(img));

浏览器现在在其优化的 C++ 引擎中完成所有空间计算。只有在真正需要加载图片时,JavaScript 才会被唤醒,并立即取消观察,以避免重复回调。

好处与结论

  • 降低 CPU 使用率 – 不再在每一次滚动时进行持续的布局计算。
  • 滚动更顺畅 – 主线程保持空闲,可用于渲染和用户交互。
  • 代码更简洁 – 观察者模式将加载逻辑封装在单一、作用域明确的回调中。

切换到 IntersectionObserver 后,Timothy 刷新页面并在巨大的网格中滚动。滚动依旧丝般顺滑,图片在进入视口前就已出现,笔记本风扇也显著安静下来。

0 浏览
Back to Blog

相关文章

阅读更多 »