useBlysh

useBlysh

A lightweight NPM package for React that enables developers to add beautiful blurred image placeholders using visual hashing, improving UX and perceived performance.

React iconReactNPMTypeScript iconTypeScriptImage LoadingUXVisual HashingVite iconViteFrontend
Beautiful Blur Placeholders

useBlysh provides a lightweight, performant way to handle image loading by integrating beautiful blurred placeholders into your application.

useBlysh - 1
Thumbnail 1
Thumbnail 2
Thumbnail 3
Thumbnail 4

🖼️ Beautiful Blurred Placeholders (Overview)

useBlysh is a lightweight, high-performance image loading solution that brings visual hashing and beautiful blurred placeholders to web applications.

Images are typically the heaviest resources on modern websites. Loading them asynchronously often leads to jarring content layout shifts and abrupt "pop-ins," which degrade the user experience. useBlysh solves this problem by representing any image as a tiny, compact text string (a hash). This hash can be immediately decoded and rendered on the client as a beautiful, lightweight blurred canvas, acting as a placeholder while the full image loads in the background.

With dual-language implementations in TypeScript/React and Python, useBlysh allows developers to easily encode images on the backend or during build pipelines, and seamlessly render them on the frontend.


⚙️ The Hashing & Render Pipeline (How It Works)

Here is a visual flow showing how useBlysh encodes an image into a hash and decodes it back into a beautiful blur effect:

Rendering diagram...

1. The Encoder

  • Resolution Downsampling: The original image is resized to 32x32 pixels using high-quality Lanczos interpolation. This eliminates heavy high-frequency noise and focuses the visual signature on large color blocks.
  • sRGB to Linear Conversion: Human perception of light is non-linear. The encoder converts the colors to linear space to perform correct mathematical operations.
  • Discrete Cosine Transform (DCT): The encoder applies a 2D DCT to convert spatial pixel coordinates into frequency domain coefficients. The first factor (DC component) represents the average color, while subsequent factors (AC components) represent horizontal and vertical color changes.
  • Base83 Serialization: The factors are quantized and serialized using a custom Base83 character set (0-9, A-Z, a-z, and specific symbols) to yield a highly compact string (usually under 30 characters).

2. The Decoder

  • Intersection Observer: To prevent performance degradation when dealing with long pages or large grids of images, ImageHashCanvas uses an IntersectionObserver with a rootMargin of 200px. Decoding is completely deferred until the element is close to the viewport.
  • Thread Yielding: The actual DCT decoding math is computed inside a setTimeout(..., 0) block. This yields execution back to the browser's main thread, keeping layout operations and scroll physics (like Lenis) butter-smooth.
  • Canvas Upscaling: Once decoded, the low-resolution pixels are painted onto a 32x32 canvas. By using native browser styling (image-rendering: pixelated combined with object-fit: inherit), the browser automatically scales the canvas with hardware acceleration.

⚡ Core Functionality (Features)

  • Double-Layered Component: Simple <ImageHash> component out of the box that abstracts the entire lifecycle (lazy loading, canvas rendering, load state, and cross-fade).
  • Asynchronous & Non-Blocking: Yields to the main thread during heavy decoding calculations, avoiding frame stutters.
  • Smart Lazy Decoding: Intersection Observer prevents decoding images offscreen, saving CPU cycles.
  • Cross-Platform Parity: Includes a Python implementation (py-useblysh) that mirrors the TypeScript library, allowing backend image processing that fits frontend React rendering.
  • Hardware-Accelerated Fade: Native CSS transitions manage a smooth opacity transition (opacity 0.5s ease-in-out) between the placeholder and the final high-resolution image.

🛠️ The NPM Package Stack (Technologies)

  • React & TypeScript: Renders the frontend component library with complete type safety.
  • Python & NumPy: Multi-platform library supporting high-performance DCT computations on the backend (with Pillow for image reading).
  • Vite: High-speed development and bundling pipeline.
  • Vitest & PyTest: Comprehensive unit tests validating math parity between Python and JS implementations.

🛡️ Parity & Main Thread Optimization (Challenges)

  • Mathematical Parity: Achieving identical visual hashes between Python's NumPy/Pillow pipeline and JavaScript's Canvas API was challenging due to differing image resizing algorithms. Resizing images to a fixed 32x32 grid before applying the DCT step ensured consistent, cross-platform hash matches.
  • Viewport Optimization: Early versions decoded all hashes on mount, causing frame drops on page loads with heavy media. Introducing the IntersectionObserver combined with setTimeout yielding solved performance bottlenecks, reducing main thread blockages to <1ms.
  • CSS Upscaling vs. Multi-pass Blur: Rather than drawing a large blurred image onto a heavy, large-scale canvas, rendering onto a tiny 32x32 canvas and styling it with width: 100%; height: 100% offloads the interpolation and blur rendering entirely to the GPU, improving render performance.

🎯 Instant & Smooth Image Loading (Conclusion)

useBlysh bridges the gap between raw web performance and polished design aesthetics. By reducing perceived load times and eliminating layout shifts, it offers a premium, modern experience for users, making image loading feel instantaneous and smooth.

Loading endorsements...