Cara Marketer Indonesia Pasang Intersection Observer untuk Lazy Section di Next.js Tanpa Library 2026
TL;DR: Intersection Observer API native bisa dipakai di Next.js 15 untuk menunda render section berat sampai pengguna men-scroll mendekati area tersebut. Pola ini memangkas initial JavaScript, menurunkan blocking time, dan menjaga LCP tetap rendah di jaringan 3G dan 4G. Tidak perlu library tambahan seperti react-intersection-observer.
Dalam beberapa proyek client terakhir, saya melihat pola yang sama berulang. Tim marketing meminta menambahkan testimonial slider, peta lokasi, dan widget Instagram di halaman landing. Tiga blok itu jarang dilihat pengunjung yang langsung pantul, tapi tetap diunduh sejak load pertama. Akibatnya bundle JavaScript membengkak dan skor LCP di Lighthouse jatuh.
Solusi yang paling konsisten memberi dampak adalah menunda mount komponen sampai section-nya benar-benar masuk viewport. Tidak perlu menambah dependency, cukup pakai Intersection Observer yang sudah ada di semua browser modern.
Masalah yang Dipecahkan
Halaman landing dengan banyak section sering punya pola berikut:
- Hero terlihat duluan, conversion utama ada di sini
- Testimonial, peta, dan widget pihak ketiga ada di bawah
- Pengguna 3G mengunduh semua aset sebelum melihat hero pertama
- Skor INP jatuh karena banyak skrip ikut hydrate sekaligus
Goalnya: hero render cepat, section lain di-mount on-demand. Lazy load gambar saja tidak cukup, karena bottleneck-nya seringkali bukan gambar, melainkan komponen React yang berat.
Framework Implementasi
Pendekatan saya dibagi tiga lapis: hook reusable, wrapper component, integrasi page. Pola ini tetap DRY dan kompatibel dengan App Router.
| Layer | File | Fungsi |
|---|---|---|
| Hook | hooks/useInView.ts | Wrap Intersection Observer jadi state React |
| Wrapper | components/atoms/LazySection.tsx | Render placeholder lalu children saat masuk viewport |
| Page | app/page.tsx | Bungkus section berat dengan LazySection |
Contoh hook minimal:
'use client'
import { useEffect, useRef, useState } from 'react'
export function useInView<T extends Element>(rootMargin = '200px') {
const ref = useRef<T>(null)
const [inView, setInView] = useState(false)
useEffect(() => {
if (!ref.current || inView) return
const io = new IntersectionObserver(([e]) => {
if (e.isIntersecting) { setInView(true); io.disconnect() }
}, { rootMargin })
io.observe(ref.current)
return () => io.disconnect()
}, [inView, rootMargin])
return { ref, inView }
}
rootMargin: '200px' memberi waktu render sebelum elemen benar-benar terlihat. Setelah masuk viewport sekali, observer di-disconnect supaya tidak boros memori. Detail teknis Intersection Observer ada di dokumentasi resmi W3C.
Studi Kasus: Landing Atmo LMS
Saat membantu Atmo LMS merapikan halaman home, ada tiga section berat: kalkulator harga, peta cabang, dan embed YouTube. Initial JS sebelum optimasi: 312 KB. Setelah membungkus ketiga section dengan LazySection, initial JS turun ke 168 KB. LCP di Moto G Power throttled 3G turun dari 3,4 detik ke 1,9 detik. Skor Core Web Vitals di field data PSI naik dari Needs Improvement ke Good dalam 21 hari pemantauan.
Catatan penting: lazy section harus tetap punya placeholder dengan tinggi tetap. Tanpa placeholder, CLS akan jelek karena layout meloncat saat children di-mount.
Pertanyaan Umum
Apakah lazy section mempengaruhi SEO?
Tidak, selama HTML utama tetap dirender oleh server. Google bot mengeksekusi JavaScript, tapi untuk amannya konten penting (heading, paragraf utama) tetap di-server-render dan hanya widget interaktif yang lazy.
Apakah lebih baik pakai react-intersection-observer?
Untuk proyek besar dengan banyak observer, library memang menyederhanakan API. Untuk proyek kecil sampai menengah, hook native sudah cukup dan menghemat sekitar 3 KB dari bundle.
Bagaimana jika browser tidak support Intersection Observer?
Per 2026, dukungan browser sudah di atas 98 persen menurut data caniuse. Jika audiens Anda banyak memakai browser sangat lama, render semua section secara default sebagai fallback.
Penutup Aplikatif
Mulai dari satu section paling berat di halaman utama. Ukur initial JS dan LCP sebelum dan sesudah. Jika dampaknya jelas, replikasi pola ini ke widget pihak ketiga dan section bawah halaman lain. Konsistensi pola, bukan jumlah library, yang membuat skor Web Vitals tetap hijau.
Artikel Terkait
Website Bisnis
Cara Marketer Indonesia Pasang Save-Data Hint untuk Visitor 3G dan 4G Lemot Tanpa Bikin Versi Lite 2026
Header Save-Data memberi sinyal saat user nyalakan Data Saver. Pakai sinyal ini untuk turunkan resolusi gambar dan skip video autoplay, tanpa membangun mobile site terpisah.
Website Bisnis
Cara Marketer Indonesia Pasang Popover API Native di Next.js untuk Modal Promo Tanpa Library 2026
Popover API memangkas 8-15 KB bundle JavaScript dan menghilangkan bug z-index pecah. Panduan praktis untuk Next.js 15 dengan studi kasus dari Nalesha.
Website Bisnis
Cara Marketer Indonesia Pasang content-visibility di Listing Page untuk Pangkas Render Time 2026
Listing page e-commerce dan blog sering kena hit render time karena ratusan elemen di DOM. CSS content-visibility memangkas rendering tanpa migrasi framework. Berikut praktik aplikatifnya.
Butuh website yang benar-benar bekerja?
Hubungi Vito untuk konsultasi gratis 15 menit.
WhatsApp Sekarang