Network Image for React

Image component that adapts quality and loading strategy in real-time based on connection speed using the Network Information API.

Component

Network-responsive demo image
4G

Installation

 

Usage

Import the component

Add the NetworkImage import to your file.

import { NetworkImage } from "@/components/network-image";

Use with default props

Use with required src and alt. The component adapts automatically.

<NetworkImage
  src="https://example.com/image.jpg"
  alt="Description"
/>;

Customize with props

Provide quality tiers and show the connection badge for debugging.

<NetworkImage
  src="/full.jpg"
  mediumSrc="/medium.jpg"
  lowSrc="/thumb.jpg"
  alt="Adaptive"
  showBadge
/>;

Guidelines

  • Provide lowSrc and mediumSrc for best results on slow connections; otherwise the full src is used for all tiers.
  • Use showBadge during development to verify the component detects your connection correctly.
  • The Network Information API has limited browser support (Chromium); the component falls back to 4g behavior when unavailable.
  • Respect saveData: when the user has enabled reduced data usage, the component uses the low tier.

Props

All props are optional unless marked required. Use these to customize every aspect of the component.

PropTypeDefaultDescription
srcrequiredstring-Primary image URL. Used for 4g connections.
altrequiredstring-Accessible alt text for the image.
lowSrcstringundefinedLow-resolution URL for 2g/slow-2g. Falls back to mediumSrc or src if not provided.
mediumSrcstringundefinedMedium-resolution URL for 3g. Falls back to src if not provided.
widthnumberundefinedImage width in pixels.
heightnumberundefinedImage height in pixels.
classNamestringundefinedAdditional CSS classes for the wrapper.
imageClassNamestringundefinedClasses for the img element.
offlineClassNamestringundefinedClasses for the offline placeholder container.
badgeClassNamestringundefinedClasses for the connection badge overlay.
showBadgebooleanfalseShow a badge overlay with the detected connection type (4G, 3G, 2G, Offline).
loadingStrategy"auto" | "eager" | "lazy""auto"Loading strategy. 'auto' adapts by network; 'eager' or 'lazy' override.
networkOverridePartial<NetworkStatus>undefinedOverride network status for testing/demo. Not for production use.

Accessibility

  • The required alt prop is forwarded to the img element so screen readers describe the image, and there are no interactive or focusable controls to make keyboard operable.
  • The offline placeholder marks its decorative SVG with aria-hidden and pairs it with a visible text label so the offline state is conveyed without relying on the icon alone.
  • The optional connection badge is a plain div with no role or aria-live region, so real-time network tier changes are not announced to assistive technology and would benefit from a polite live region.
  • The image uses a transition-opacity fade that does not honour prefers-reduced-motion, so it should be guarded with a motion-reduce variant for users who request reduced motion.

Performance

  • The only animation is a 300ms opacity transition on the img, which is compositor-friendly and cheap since it does not trigger layout or paint.
  • useNetworkStatus attaches window online and offline listeners plus a connection change listener and removes all of them in the effect cleanup, so there are no leaked listeners.
  • Loading uses the native img loading attribute (lazy or eager) instead of an IntersectionObserver or requestAnimationFrame, keeping the JavaScript footprint minimal.
  • Selecting a lower image tier swaps imageSrc to a smaller asset on slow or save-data connections, reducing transferred bytes at the cost of an extra fetch when the network type changes.
  • There is no will-change hint or prefers-reduced-motion gating, so the opacity fade always runs regardless of user motion preferences.

Examples

Basic

Default usage. Uses full resolution on fast connections, adapts on slower ones.

Network-responsive demo image
4G
import { NetworkImage } from "@/components/network-image";

export function NetworkImageBasic() {
  return (
    <NetworkImage
      src="https://picsum.photos/800/400"
      alt="Adaptive image"
    />
  );
}

Quality tiers

Provide different image URLs for each connection tier.

Network-responsive demo image
4G
import { NetworkImage } from "@/components/network-image";

export function NetworkImageWithTiers() {
  return (
    <NetworkImage
      src="https://example.com/image-full.jpg"
      mediumSrc="https://example.com/image-medium.jpg"
      lowSrc="https://example.com/image-thumb.jpg"
      alt="Adaptive image with quality tiers"
    />
  );
}

With badge

Show a live badge indicating the detected connection type.

Network-responsive demo image
4G
import { NetworkImage } from "@/components/network-image";

export function NetworkImageWithBadge() {
  return (
    <NetworkImage
      src="https://picsum.photos/800/400"
      alt="Image with network badge"
      showBadge
    />
  );
}

Last updated on Jun 19

Made with ❤️ by Pulkit &

© 2026 Pulkit. All rights reserved

Last updated: