Progressive Image

Let me get my glasses real quick
Includes a Ruby component and corresponding Rails helper
Ruby
Includes a Stimulus controller
Stimulus
This is a paid-only premium component
Premium

Progressive Image component provides smooth image loading experiences with blur-to-sharp transitions. Perfect for displaying ActiveStorage attachments with automatic placeholder generation, responsive sizing, and optimized loading performance.

Basic Example

Mario Kart 8Mario Kart 8
<%= nk_progressive_image(attachment: @game.box_art, alt: @game.title) %>

Different Sizes

Choose from predefined sizes or specify custom dimensions for optimal image delivery.

Small

Mario Kart 8Mario Kart 8

Medium

Mario Kart 8Mario Kart 8

Large

Mario Kart 8Mario Kart 8

Custom Size (500px)

Mario Kart 8Mario Kart 8
<%= nk_progressive_image(attachment: @game.box_art, size: :small, alt: @game.title) %>
<%= nk_progressive_image(attachment: @game.box_art, size: :medium, alt: @game.title) %>
<%= nk_progressive_image(attachment: @game.box_art, size: :large, alt: @game.title) %>

<!-- Custom size -->
<%= nk_progressive_image(attachment: @game.box_art, size: 500, alt: @game.title) %>

Handling Missing Images

Component gracefully handles cases where no image is attached with a placeholder div.

<!-- When attachment is nil or not attached -->
<%= nk_progressive_image(attachment: nil, alt: "Missing image") %>

Install

Premium

Set up Nitro Kit then

bin/rails app:template \
  LOCATION="https://nitrokit.dev/t/premium/progressive_image?license=LICENSE-KEY"

Usage

nk_progressive_image(attachment:, alt: nil, size: :medium, **attrs)
PropertyDefaultDescription
attachmentActiveStorage::Attached::One The ActiveStorage attachment to display. Component handles nil/unattached gracefully.
altString Alt text for accessibility. Highly recommended for all images.
size:small, :medium, :large, or Integer Controls image variant resolution (:small=250px, :medium=720px, :large=1800px). Component grows to fill container width.
**attrsHTML attributes for <div> element

Helper Method

nk_progressive_image(attachment:, alt: nil, size: :medium, **attrs)
PropertyDefaultDescription
attachmentActiveStorage::Attached::One The ActiveStorage attachment to display progressively.
altString Alt text for the image. Essential for accessibility.
size:small, :medium, :large, or Integer Controls image variant resolution, not display size. Component fills its container width.
**attrsHTML attributes for <div> element

How It Works

The Progressive Image component creates a smooth loading experience through these steps:

  • Placeholder Generation: Creates a tiny (50x50px), low-quality version as a blurred background
  • Full Image Loading: Loads the full-resolution image with proper srcset for high-DPI displays
  • Smooth Transition: Uses CSS opacity transition to fade from blur to sharp image
  • Responsive Images: Automatically generates 1x and 2x variants for different screen densities
  • Lazy Loading: Images load only when they enter the viewport
  • Error Handling: JavaScript controller gracefully handles loading failures
💡 ActiveStorage Analysis Recommended

For proper aspect ratio styling, ActiveStorage attachments should be analyzed to extract image dimensions. Analysis happens automatically when attachments are created, but you can ensure it with:

attachment.analyze unless attachment.analyzed?

Or add a callback to your model for automatic analysis:

class Post < ApplicationRecord
  has_one_attached :image
  
  after_commit :analyze_image, on: [:create, :update]
  
  private
  
  def analyze_image
    image.analyze_later if image.attached? && !image.analyzed?
  end
end

Performance Benefits

  • Perceived Performance: Users see content immediately with blur placeholder
  • Bandwidth Optimization: Loads appropriately sized images based on display requirements
  • Layout Stability: Maintains proper aspect ratios to prevent content shifts
  • Modern Web Standards: Uses native lazy loading and responsive images