Tips & Tricks

Claude Code के साथ Implement Lazy Loading Images कैसे करें

Claude Code का उपयोग करके implement lazy loading images सीखें। Practical code examples और step-by-step guidance शामिल है।

画像遅延読み込みのimportant性

Webpageの読み込み速度に最も影響するのは画像 है।ファーストビューबाहरの画像を遅延読み込みする बातで、初期display速度を大幅に改善でき है।Claude Code का उपयोग करके、ブラウザネイティブ का तरीका सेカスタムimplementation तक、最適な画像読み込み戦略 build किया जा सकता है。

ネイティブLazy Loadingのutilization

最もシンプルな方法はHTMLのloading属性 है।

> Next.jsのImagecomponentの तरहなoptimizationされた画像componentを作って。
> lazy loading、プレースホルダー、responsivesupportを含めて。
import { useState, useRef, useEffect } from 'react';

interface OptimizedImageProps {
  src: string;
  alt: string;
  width: number;
  height: number;
  placeholder?: 'blur' | 'skeleton' | 'none';
  blurDataURL?: string;
  sizes?: string;
  priority?: boolean;
  className?: string;
}

function OptimizedImage({
  src, alt, width, height, placeholder = 'skeleton',
  blurDataURL, sizes, priority = false, className = '',
}: OptimizedImageProps) {
  const [loaded, setLoaded] = useState(false);
  const [error, setError] = useState(false);
  const imgRef = useRef<HTMLImageElement>(null);

  // 高優先度画像はプリロード
  useEffect(() => {
    if (priority) {
      const link = document.createElement('link');
      link.rel = 'preload';
      link.as = 'image';
      link.href = src;
      document.head.appendChild(link);
      return () => { document.head.removeChild(link); };
    }
  }, [src, priority]);

  const aspectRatio = `${width} / ${height}`;

  return (
    <div
      className={`relative overflow-hidden ${className}`}
      style={{ aspectRatio }}
    >
      {/* プレースホルダー */}
      {!loaded && placeholder === 'blur' && blurDataURL && (
        <img
          src={blurDataURL}
          alt=""
          aria-hidden="true"
          className="absolute inset-0 w-full h-full object-cover blur-lg scale-110"
        />
      )}
      {!loaded && placeholder === 'skeleton' && (
        <div className="absolute inset-0 animate-pulse bg-gray-200 dark:bg-gray-700" />
      )}

      {/* メイン画像 */}
      <img
        ref={imgRef}
        src={src}
        alt={alt}
        width={width}
        height={height}
        sizes={sizes}
        loading={priority ? 'eager' : 'lazy'}
        decoding="async"
        onLoad={() => setLoaded(true)}
        onError={() => setError(true)}
        className={`w-full h-full object-cover transition-opacity duration-300 ${
          loaded ? 'opacity-100' : 'opacity-0'
        }`}
      />

      {error && (
        <div className="absolute inset-0 flex items-center justify-center bg-gray-100 text-gray-400">
          画像を読み込めません
        </div>
      )}
    </div>
  );
}

Intersection Observerによるカスタム遅延読み込み

function useLazyImage(threshold = 0.1) {
  const [isVisible, setIsVisible] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const element = ref.current;
    if (!element) return;

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setIsVisible(true);
          observer.unobserve(element);
        }
      },
      { threshold, rootMargin: '200px 0px' } // 200px手पहले से読み込み開始
    );

    observer.observe(element);
    return () => observer.disconnect();
  }, [threshold]);

  return { ref, isVisible };
}

// Usage example
function LazyImage({ src, alt, ...props }: ImgHTMLAttributes<HTMLImageElement>) {
  const { ref, isVisible } = useLazyImage();

  return (
    <div ref={ref}>
      {isVisible ? (
        <img src={src} alt={alt} {...props} />
      ) : (
        <div className="animate-pulse bg-gray-200" style={{ aspectRatio: '16/9' }} />
      )}
    </div>
  );
}

画像formatのoptimization

function ResponsiveImage({ src, alt, width, height }: ImageProps) {
  const baseName = src.replace(/\.[^.]+$/, '');

  return (
    <picture>
      <source srcSet={`${baseName}.avif`} type="image/avif" />
      <source srcSet={`${baseName}.webp`} type="image/webp" />
      <img
        src={src}
        alt={alt}
        width={width}
        height={height}
        loading="lazy"
        decoding="async"
        className="w-full h-auto"
      />
    </picture>
  );
}

ぼかしプレースホルダーのgenerate

// build時にぼかしプレースホルダー generate
import sharp from 'sharp';

async function generateBlurDataURL(imagePath: string): Promise<string> {
  const buffer = await sharp(imagePath)
    .resize(10, 10, { fit: 'inside' })
    .blur()
    .toBuffer();

  return `data:image/png;base64,${buffer.toString('base64')}`;
}

Summary

Claude Code का उपयोग करके、ネイティブLazy Loading सेIntersection Observer、画像formatoptimization तक包括的な画像読み込み戦略 build किया जा सकता है。スケルトンdisplayとのintegrationはスケルトンローディングを、画像processing全般は画像processingの記事をदेखें。

画像のoptimization手法के बारे मेंはweb.dev - Optimize imagesが参考になり है।

#Claude Code #遅延読み込み #image optimization #performance #React