Skip to main content
Skill web app · Pelajaran 6 dari 11 · 14 menit

Dasar Core Web Vitals Next.js: next/image dan next/font

Pelajari dasar performa web di Next.js: LCP, CLS, dan INP, sizes dan srcset next/image, priority, serta next/font, dengan file nyata dari situs ini.

Oleh Matthews WongDitinjau pada

Poin utama

Core Web Vitals adalah tiga metrik lapangan dari Google untuk pengalaman halaman: LCP untuk pemuatan, INP untuk responsivitas, dan CLS untuk kestabilan visual. Di Next.js, next/image dan next/font menyasar yang pertama dan terakhir: keduanya mengatur ukuran, preload, dan self-hosting gambar serta font yang menentukan kapan konten utama muncul dan apakah ia bergeser.

Setelah pelajaran ini, Anda bisa

  • Menyebutkan tiga Core Web Vitals dan ambang batas yang dianggap baik.
  • Mengatur ukuran gambar dengan width, height, fill, dan sizes, serta memakai priority hanya di tempat yang membantu.
  • Memuat font dengan next/font agar tidak menambah request ke pihak ketiga dan tidak menggeser tata letak.
Lihat cara kerjanya

Ikuti diagramnya langkah demi langkah

Tekan Putar, atau melangkah dengan panah. Setiap langkah juga ditulis di bawah diagram.

Satu gambar hero, dari awal sampai tampil

HTML membawa sizes dan srcset, browser memilih satu lebar, pengoptimal gambar mengembalikan file yang sudah diubah ukurannya, dan priority serta ruang yang dipesan menjaga elemen terbesar tetap cepat dan diam.

Ditinjau pada 17 Oktober 2026

Langkah 1 dari 6. LCP adalah waktu render untuk gambar atau blok teks terbesar yang terlihat. Di banyak halaman itu adalah gambar hero, jadi jalur dari HTML ke piksel adalah jalur yang perlu dibenahi.

Tombol: ← → langkah · Home / End · K putar atau jeda

  1. LCP adalah waktu render untuk gambar atau blok teks terbesar yang terlihat. Di banyak halaman itu adalah gambar hero, jadi jalur dari HTML ke piksel adalah jalur yang perlu dibenahi.

  2. Halaman membawa srcset berisi lebar kandidat dan petunjuk sizes tentang selebar apa gambar ditampilkan. Browser memakai sizes untuk memilih kandidat yang paling sesuai.

    sizes="(max-width: 768px) calc(100vw - 2rem), 768px"Tebak langkah berikutnya Sebuah gambar memakai fill dan string sizes. Apa isi srcset yang dihasilkan? (Hanya 1x dan 2x · Daftar lebar lengkap seperti 640w dan 750w · Satu file tetap)
  3. Dengan sizes, Next.js menghasilkan srcset berisi daftar lebar lengkap. Tanpa sizes, set 1x dan 2x yang terbatas cocok untuk gambar berukuran tetap. Browser hanya mengunduh satu kandidat yang dipilihnya.

  4. Pengoptimal mengembalikan gambar pada lebar itu dalam format modern. Situs ini hanya mencantumkan WebP, pilihan sengaja yang dicatat di next.config.ts, agar origin mengenkode dengan cepat.

    Tebak langkah berikutnya Hero adalah elemen LCP. Bagaimana sebaiknya ia dimuat? (Lazy, untuk menghemat byte · Dipreload, tidak pernah lazy)
  5. priority memuat gambar lebih awal dan menonaktifkan lazy loading, yang menurut web.dev tidak boleh dikenakan pada gambar LCP. Pakai pada satu atau dua gambar di area atas, bukan di mana-mana.

    priority
  6. Width dan height memberi browser rasio aspek, sehingga ruang disiapkan sebelum byte tiba dan tidak ada yang melompat. Begitulah gambar terhindar dari Cumulative Layout Shift.

Apa tiga Core Web Vitals, dan apa yang dianggap baik?

Core Web Vitals adalah tiga metrik yang diukur pada kunjungan nyata. Largest Contentful Paint, LCP, mengukur pemuatan. Interaction to Next Paint, INP, mengukur responsivitas. Cumulative Layout Shift, CLS, mengukur kestabilan visual. web.dev mendefinisikan baik sebagai LCP dalam 2,5 detik sejak halaman mulai dimuat, INP 200 milidetik atau kurang, dan CLS 0,1 atau kurang, masing-masing dinilai pada persentil ke-75 pemuatan halaman.

Baca selengkapnya (2)

INP menggantikan First Input Delay sebagai Core Web Vital yang stabil pada 2024, jadi tutorial lama yang mengajarkan FID sudah usang. INP melihat latensi semua klik, ketukan, dan penekanan tombol, dan latensi sebuah interaksi terdiri dari tiga bagian: input delay, processing duration, dan presentation delay.

LCP sendiri terbagi menjadi empat subbagian: time to first byte, resource load delay, resource load duration, dan element render delay. Mengetahui bagian mana yang lambat menunjukkan perbaikan mana yang dicoba. Pelajaran ini tidak menjanjikan berapa milidetik yang dihemat suatu perubahan; ukurlah halaman Anda sendiri.

Bagaimana width, height, dan priority melindungi LCP dan CLS?

width dan height pada next/image adalah ukuran intrinsik dalam piksel. Keduanya memungkinkan browser menyimpulkan rasio aspek dan memesan ruang, sehingga menghindari pergeseran tata letak saat gambar dimuat. Keduanya tidak menentukan ukuran tampilan; itu tugas CSS. Anda harus mengatur keduanya kecuali gambar diimpor secara statis atau memakai fill. web.dev memberi saran yang sama untuk HTML biasa: selalu sertakan width dan height pada gambar.

Baca selengkapnya (2)

fill membuat gambar mengisi elemen induknya, yang harus berposisi relative, fixed, atau absolute. Hero blog di situs ini melakukan persis itu di dalam pembungkus dengan rasio aspek tetap, sehingga kotaknya sudah ada sebelum gambarnya.

priority memuat gambar lebih awal dan mematikan lazy loading; defaultnya adalah lazy load. web.dev memperingatkan agar tidak pernah me-lazy-load gambar LCP, karena itu selalu menambah resource load delay, dan menyebut bahwa memberi prioritas tinggi pada lebih dari satu atau dua gambar membuatnya tidak lagi membantu. Karena itu hero blog memakai priority dan tidak ada gambar lain di halaman itu yang memakainya.

Apa fungsi sizes, dan mengapa fill bisa membengkakkan srcset?

Browser tidak tahu selebar apa gambar berukuran CSS ketika membaca HTML, jadi sizes yang memberitahunya. Jika sizes tidak ada, browser mengira gambar selebar viewport, yang bisa mengunduh file yang terlalu besar. Pakai sizes setiap kali gambar memakai fill atau CSS membuatnya responsif.

Baca selengkapnya (2)

sizes juga mengubah markup. Tanpanya, Next.js menulis srcset terbatas, misalnya 1x dan 2x, yang cocok untuk gambar berukuran tetap. Dengannya, Next.js menulis srcset lengkap berisi lebar seperti 640w dan 750w. Itu tepat untuk hero selebar layar, dan boros untuk ikon kecil.

Situs ini pernah mengalami kasus boros itu. Marquee sertifikasi menampilkan logo 44 piksel, dan komentar di carousel mencatat bahwa fill dengan sizes berbasis piksel mencantumkan setiap lebar terkonfigurasi di srcset, sekitar 1 KB HTML per tile. Perbaikannya adalah width dan height tetap, yang hanya menghasilkan 1x dan 2x. Cocokkan alat dengan bentuknya: fill dan sizes untuk gambar fluid, width dan height untuk gambar tetap.

Bagaimana next/font menghindari request tambahan dan pergeseran tata letak?

next/font melakukan self-hosting file font bersama aset statis lainnya, sehingga browser tidak mengirim request ke penyedia font. Untuk font Google, CSS dan file diunduh saat build. Dokumentasi menyebut ini memungkinkan memuat font web tanpa pergeseran tata letak. Ia juga mengatur display ke swap secara default dan memuat font lebih awal secara default.

Baca selengkapnya (2)

Bagian pergeseran tata letak berasal dari font cadangan. Font web dan cadangannya punya ukuran glif berbeda, sehingga teks bisa tersusun ulang saat font tiba. web.dev mencantumkan perbaikannya: size-adjust dan descriptor override agar cocok dengan cadangan, keluarga font cadangan generik, preload, atau font-display optional. next/font punya opsi adjustFontFallback untuk ini, aktif secara default untuk font Google.

Situs ini pindah dari next/font/google ke next/font/local. Build Docker di CI harus mengunduh font dari Google, dan ketika itu gagal seluruh deploy ikut gagal. Subset Latin dari font variabel kini ada di repo, satu file mencakup bobot 400 sampai 800, dan build tidak butuh jaringan untuk font. Muat font sekali di modul font dan impor di tempat yang perlu, karena setiap pemanggilan menghosting satu instance lagi.

Di mana posisi INP?

next/image dan next/font menyasar metrik pemuatan dan kestabilan. INP berbeda: ia menyangkut seberapa cepat halaman merespons setelah pengguna mengeklik, mengetuk, atau mengetik. Dari tiga bagiannya, processing duration adalah waktu yang dibutuhkan event handler Anda untuk berjalan, jadi pekerjaan berat di dalam handler adalah tempat pertama untuk diperiksa. Input delay dan presentation delay bergantung pada apa lagi yang dikerjakan browser sebelum dan sesudahnya.

Baca selengkapnya (1)

web.dev menilai INP di atas 500 milidetik sebagai buruk. Karena INP menghitung setiap interaksi dalam satu kunjungan, ia tidak bisa diperbaiki dengan satu pengaturan gambar; ia perlu diukur pada interaksi nyata.

Cara situs ini melakukannya

Konfigurasi nyata di balik pelajaran ini

Kutipan dari repositori yang membangun dan men-deploy situs ini, apa adanya.

app/fonts/jakarta.ts:20-27
export const jakarta = localFont({
  src: "./plus-jakarta-sans-latin.woff2",
  weight: "400 800",
  style: "normal",
  display: "swap",
  preload: true,
  variable: "--font-jakarta",
});

Satu file variabel, rentang bobot, display swap, dan variabel CSS. Menyebut display dan preload secara eksplisit mencatat keputusan meski keduanya sama dengan default, dan variabel itu memungkinkan Tailwind membaca font.

app/[locale]/(pages)/blog/[slug]/page.tsx:8316-8323
                <ImageWithSkeleton
                  src={meta.image}
                  alt={title}
                  fill
                  sizes="(max-width: 768px) calc(100vw - 2rem), 768px"
                  className="object-cover"
                  priority
                />

Hero mengisi pembungkus dengan rasio aspek tetap, sehingga ruang sudah dipesan. sizes menyatakan gambar selebar penuh dikurangi padding di ponsel dan 768 piksel di layar lain, dan priority diatur karena inilah gambar LCP.

app/components/home/CertificationsCarousel.tsx:55-68
            Eager, not lazy: the marquee holds most tiles off-screen and scrolls
            them in continuously, so lazy logos pop in blank mid-animation. All
            11 distinct marks together are ~45 KB at this size. Fixed 44x44
            rather than `fill`: with a px `sizes`, `fill` lists every
            configured width in srcset (~1 KB of HTML a tile); fixed
            dimensions give just 1x and 2x.
          */}
          <Image
            src={item.logo}
            alt=""
            width={44}
            height={44}
            loading="eager"
            className="h-full w-full object-contain p-1"
          />

Kebalikan dari hero. Logo kecil berukuran tetap memakai width dan height, bukan fill, sehingga srcset tetap 1x dan 2x. loading eager adalah pilihan terpisah, diambil karena logo lazy muncul kosong saat marquee berjalan.

next.config.ts:52-62
    // WebP only — AVIF is dropped deliberately. On the 1 vCPU / 512 MB VPS,
    // encoding one cover to AVIF measured 4–9 s (x-nextjs-cache MISS) versus
    // ~0.6 s for the same cover to WebP — a 7–16× penalty. Because Cloudflare
    // does not currently cache /_next/image/ (cf-cache-status: DYNAMIC), that
    // encode is paid on the origin far more often than once, so the fast
    // format wins outright. Re-enable AVIF ("image/avif" first) only after the
    // edge caches optimised variants, so the slow encode is amortised globally.
    formats: ["image/webp"] as Array<"image/avif" | "image/webp">,
    deviceSizes: [640, 750, 828, 1080, 1200, 1920],

Pengoptimal gambar adalah sebuah server, dan pengaturannya adalah keputusan biaya. deviceSizes adalah daftar lebar yang menjadi sumber srcset, dan formats dipangkas ke WebP karena mengenkode AVIF yang lebih kecil terlalu lambat di host ini.

Yang sering rusak

Kesalahan yang benar-benar membuang waktu

  • priority pada setiap gambar

    Memuat banyak gambar lebih awal membuat mereka bersaing, dan web.dev menyebut prioritas tinggi pada lebih dari satu atau dua gambar tidak lagi membantu LCP. Tandai hanya gambar yang menjadi elemen LCP.

  • Hero yang di-lazy-load

    next/image melakukan lazy load secara default. Jika dibiarkan pada gambar LCP, ia menunggu layout sebelum mulai mengunduh. Tambahkan priority pada hero.

  • fill dengan sizes piksel kecil membengkakkan srcset

    Setiap lebar terkonfigurasi masuk ke HTML untuk tiap gambar kecil, yang menumpuk di seluruh grid. Pakai width dan height tetap untuk gambar berukuran tetap agar mendapat 1x dan 2x.

  • sizes yang hilang pada gambar responsif

    Tanpa sizes, browser mengira gambar selebar viewport dan bisa mengunduh jauh lebih banyak dari yang diperlukan. Jelaskan lebar tata letak yang sebenarnya di sizes.

  • Build font membutuhkan jaringan

    next/font/google mengunduh saat build. Ketika build Docker di CI tidak bisa menjangkau penyedia, build gagal. Situs ini melakukan self-hosting font dengan next/font/local sehingga tidak butuh panggilan jaringan.

fill dengan sizes versus width dan height tetap
fill dan sizesDaftar lebar lengkapGambar fluid seperti hero atau sampul kartu
width dan height, tanpa sizes1x dan 2xGambar berukuran tetap seperti logo atau avatar
Coba sendiri

Lakukan di komputer Anda sendiri

Periksa HTML yang benar-benar dikirim sebuah halaman. Jalankan ini terhadap server produksi lokal.

  1. Ambil sebuah halaman dan daftar atribut sizes-nya. Gambar dengan fill harus menampilkan string sizes Anda.

    curl -s http://localhost:3000/en | grep -o 'sizes="[^"]*"' | head
  2. Ubah gambar kecil dari fill ke width dan height tetap, build ulang, dan bandingkan panjang srcset-nya.

  3. Beri hero priority dan tidak ada yang lain, lalu periksa head untuk link preload bagi gambar itu.

    curl -s http://localhost:3000/en | grep -o 'rel="preload"[^>]*' | head
  4. Baca modul font Anda. Pastikan font dimuat sekali dan display serta variabel CSS diatur dengan sengaja.

Kuis singkat

Tiga pertanyaan sebelum lanjut

Pilih jawaban untuk melihat kenapa benar atau salah. Tidak ada yang disimpan atau dinilai, jadi tebak saja dengan bebas.

  1. 1.Pasangan mana yang disebut web.dev baik untuk LCP dan CLS?
  2. 2.Sebuah gambar memakai fill dan string sizes. Apa yang dihasilkan next/image?
  3. 3.Pengaturan mana yang cocok untuk satu gambar hero yang menjadi elemen LCP?
Pikirkan dulu

Jawab dalam hati, lalu cek

  1. 1.Mengapa marquee logo memakai width dan height, bukan fill?Lihat jawabannya

    Jawaban:fill dengan sizes piksel mencantumkan setiap lebar terkonfigurasi di srcset untuk tiap tile kecil; dimensi tetap hanya memberi 1x dan 2x.

  2. 2.Sebutkan dua cara next/font membantu CLS dan jaringan.Lihat jawabannya

    Jawaban:Ia melakukan self-hosting font sehingga browser tidak mengirim request ke penyedia font, dan ia dapat menyesuaikan font cadangan untuk mengurangi pergeseran tata letak.

  3. 3.Core Web Vital mana yang menggantikan First Input Delay?Lihat jawabannya

    Jawaban:Interaction to Next Paint, INP, yang menjadi Core Web Vital stabil pada 2024.

Pelajari lebih dalam

Bahasan mendalam terkait di situs ini