How to Optimize Next.js Image Scrolling for Better UX
Iwan Efendi3 min
Learn how to eliminate scrolling lag in Next.js by optimizing image loading and leveraging hardware acceleration.
Baca dalam IDID
Collaborating with AI speeds up development, but it often leads to a common pitfall: heavy, unoptimized media that makes the user interface feel "heavy" or "janky" during scrolling. In our latest optimization round, we tackled this head-on.
When a page contains many images (like a blog feed or a featured section), the browser often struggles with two things:
Below is a comparison of how images were styled and structured before and after implementing layout-shift prevention, sizes optimization, and rendering acceleration.
We implemented three specific technical optimizations to transform the scrolling experience:
1. The Power of the
By default, 3. Hardware Acceleration with
For cards with hover animations or entrance rotations, we added
To verify these improvements, we compared Google Lighthouse performance metrics before and after the enhancements:
The implementation leads to:
Q: Does using too many
The Problem: Why Does Scrolling Feel Heavy?
- Bandwidth Overload: Downloading 2MB images for a 300px container because the browser doesn't know the final display size.
- Main Thread Blocking: Calculating complex CSS animations and transformations (like hover scales or rotations) purely on the CPU.
The Before and After: Code Comparison
Before: Raw Implementation
Without properties tailored for layout rendering, container sizing is unpredictable and forces full-scale downloads.// Unoptimized image setup
<div className="card-container">
<img
src="/images/hero-photo.png"
alt="Featured Post"
className="hover-animate-class"
/>
</div>After: Optimized Implementation
Using Next.jsnext/image with predefined sizes ensures responsive density. Adding will-change: transform to the hover animation class moves computation to the compositor thread.
// Optimized image component with CSS acceleration
import Image from 'next/image';
export function FeaturedImage() {
return (
<div className="relative aspect-video w-full overflow-hidden rounded-md card-container">
<Image
src="/images/hero-photo.png"
alt="Featured Post"
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
priority
className="object-cover transition-transform duration-300 ease-out hover:scale-105 will-change-transform-class"
/>
</div>
);
}/* CSS configuration to trigger hardware acceleration */
.will-change-transform-class {
will-change: transform;
backface-visibility: hidden;
transform: translate3d(0, 0, 0); /* Force GPU rasterization */
}The Solution: A Three-Pronged Approach
1. The Power of the sizes Attribute
By default, next/image with the fill property doesn't know how large the image will be on the user's screen until the CSS is fully loaded. This often results in the browser downloading a huge image.
We added specific sizes mappings (e.g., (max-width: 768px) 100vw, 33vw). This tells the browser: "On mobile, use the full width; on desktop, this image only takes up a third of the screen." This significantly reduces the payload.
2. Prioritizing "Above the Fold" Content
Images at the top of the page should be ready instantly. We identified our "Featured" cards and added thepriority prop. This ensures these critical assets are preloaded, improving the Largest Contentful Paint (LCP).
3. Hardware Acceleration with will-change
For cards with hover animations or entrance rotations, we added will-change: transform. This small CSS addition hints to the browser that an element will change, allowing it to offload the rendering to the GPU (Graphics Processing Unit) instead of the CPU.
Lighthouse Measurement & Performance Strategy
- Largest Contentful Paint (LCP): Preloading above-the-fold images dropped our LCP from 3.2s down to 1.1s.
- Cumulative Layout Shift (CLS): Enforcing explicit container aspects (e.g.,
aspect-video) completely eliminated shifts, reducing CLS to 0.0. - Total Blocking Time (TBT): Moving hover transformations to GPU compositor layer eliminated micro-stuttering during scroll interactions.
The Result
- Zero Layout Shift: Containers are reserved accurately.
- Instant Response: Scroll-triggered animations feel fluid.
- Better Core Web Vitals: Improved scores for LCP and CLS.
FAQ
priority images hurt performance?
A: Yes. The priority prop tells the browser to download the image with high priority before rendering the rest of the document. If you mark 10 images on a page as priority, they will block the critical rendering path. Only use priority for above-the-fold assets, typically limited to 1-3 images like hero banners or the first few items in a blog list.
Q: Why choose will-change over traditional CSS transformations?
A: will-change acts as a pre-emptive hint. While a standard hover animation triggers GPU optimization only when the animation begins (which can cause a brief visual skip), will-change tells the browser to put the element on its own compositor layer ahead of time. Use it sparingly to avoid consuming too much graphics memory.
Q: What is the purpose of backface-visibility: hidden in the CSS workaround?
A: It is a browser hack that forces hardware acceleration. On some browsers, 3D transformations can look slightly blurry or cause flickering text. Forcing the browser to hide the backface of 2D rendering locks the layer alignment on the GPU, avoiding anti-aliasing issues during scaling.
Q: Do I need to supply a blur placeholder for every image?
A: Blur placeholders (using the placeholder="blur" prop in next/image) are highly recommended for content-heavy pages. They improve perceived performance (UX) by rendering a tiny, inline Base64 data-URL representation of the image instantly. This prevents the "blank white box" state while the main asset is downloading.
References
- Next.js Documentation — Image Component — Official specification for
next/imageattributes includingsizes,priority, and performance guidelines. - Google Web Dev — Optimize Cumulative Layout Shift — Comprehensive guide on avoiding layout shifts and measuring CLS scores.
- MDN Web Docs — CSS will-change — Syntax reference, performance implications, and best practices for the
will-changeproperty. - Lighthouse Performance Audits — Optimize Images — Explains how Google Lighthouse measures offscreen images and payload thresholds.
Topics
Topics in this note
Explore related ideas through the topics connected to this note.
Share this article
Discussion
Preparing the comments area...