JavaScript + IntersectionObserver 实现高性能图片懒加载

182 阅读2分钟

一、前言

在 Web 开发中,图片懒加载是一种常见的优化手段,尤其在长列表页面中,按需加载图片可以显著提升页面性能。本篇文章将通过 JavaScript 和 Intersection Observer,实现一个带有卡片样式的高性能图片懒加载示例。

image.png

二、样式布局

以下是卡片列表的样式,采用了 CSS Grid 布局,支持响应式排列,并为图片卡片添加了缩放动画效果:

body {
  background-color: #f5f6f7;
}

.card-list {
  --ap-gap: 16px; /* 列表项的间距 */
  --ap-min-width: 300px; /* 列表项的最小宽度 */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--ap-min-width), 1fr));
  gap: var(--ap-gap);
  padding: 16px;
}

.card-list .item {
  cursor: pointer;
  height: 497px;
  border-radius: 10px;
  box-shadow: 0 0 6px #000;
  overflow: hidden;
}

.card-list .item:hover img {
  transform: scale(1.5);
}

.card-list .item img {
  display: block;
  width: 100%;
  height: 100%;
  transition: all 0.32s;
}

上述样式不仅定义了图片卡片的基本外观,还支持鼠标悬停时的动态缩放效果,提升了用户体验。

三、HTML 结构

页面结构简单明了,通过 JavaScript 动态生成卡片列表:

<div class="card-list"></div>

四、实现逻辑

1、配置项与生成图片卡片

通过以下代码,动态生成 99 张图片卡片,使用默认占位图提高页面加载速度:

const TOTAL_ITEMS = 99;
const DEFAULT_IMG = './img/default.jpg';
const IMG_URL_TEMPLATE = (index) => `https://picsum.photos/400/600?r=${index}`;

const cardList = document.querySelector('.card-list');

function generateItems() {
  const fragment = document.createDocumentFragment();
  for (let i = 0; i < TOTAL_ITEMS; i++) {
    const div = document.createElement('div');
    div.classList.add('item');
    const img = document.createElement('img');
    img.src = DEFAULT_IMG;
    img.dataset.src = IMG_URL_TEMPLATE(i);
    img.alt = `Image ${i + 1}`;
    div.appendChild(img);
    fragment.appendChild(div);
  }
  cardList.appendChild(fragment);
}
generateItems();

2、使用 Intersection Observer 实现懒加载

通过 Intersection Observer,可以高效检测图片是否进入视口,并在合适的时机加载真实图片:

function initLazyLoad() {
  const observer = new IntersectionObserver(
    (entries, observer) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting) return;
        const img = entry.target;
        img.src = img.dataset.src;
        observer.unobserve(img);
      });
    },
    { threshold: 0.01 }
  );

  document.querySelectorAll('img[data-src]').forEach((img) => observer.observe(img));
}
initLazyLoad();

本文通过样式优化和 Intersection Observer,有效提升了图片懒加载的性能,同时保持了良好的用户体验。这种实现方式不仅适用于图片懒加载,也可以扩展到其它按需加载场景,如视频或组件加载。

完整源码