Topik wawancara representatif

Wawancara Frontend: Bagaimana Cara Menggunakan content-visibility Tanpa Menyebabkan Layout Shift?

FrontendSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah feed konten memiliki ratusan kartu, dan render pertama serta scrolling terasa lambat. Jelaskan bagaimana Anda akan menggunakan content-visibility: auto untuk menunda rendering di luar layar, bagaimana contain-intrinsic-size mencegah lompatan scrollbar, dan bagaimana Anda memverifikasi bahwa INP, stabilitas layout, dan aksesibilitas tidak mengalami regresi.

Pertanyaan dan Skenario yang Sesuai

Anda mengelola daftar panjang, feed artikel, atau workspace admin. DOM berisi ratusan bagian konten; hanya beberapa kartu yang terlihat di awal, namun browser tetap melakukan tugas style, layout, dan paint untuk subtree di luar layar. Wawancara ini meminta Anda mengurangi beban rendering pada main thread menggunakan CSS containment sambil tetap mempertahankan find-in-page, fokus, dan akses screen reader.

Asumsikan bahwa halaman dapat dibagi menjadi kartu atau bagian independen, tingginya bervariasi tetapi tidak tak terbatas, dan browser target mendukung content-visibility: auto. Browser yang tidak mendukung harus tetap merender halaman dengan benar.

Apa yang Dinilai oleh Pewawancara

  • Apakah Anda memisahkan bottleneck jaringan, skrip, dan rendering sebelum melakukan optimasi.
  • Apakah Anda dapat menjelaskan layout, style, dan paint containment yang tersirat dari auto, ditambah size containment di luar layar.
  • Apakah Anda mengantisipasi kesalahan ukuran placeholder yang menyebabkan lompatan scrollbar dan risiko CLS.
  • Apakah Anda memvalidasi performa bersama dengan fokus, find-in-page, pembaca layar, dan perilaku pembacaan DOM.

Jawaban yang lemah hanya memberikan satu deklarasi CSS. Jawaban yang kuat menyebutkan batasan (boundary), strategi ukuran, biaya pembacaan layout paksa, dan rencana fallback.

Pertanyaan untuk Diklarifikasi Sebelum Menjawab

  1. Apakah perlambatan terjadi pada render pertama, saat scrolling, setelah pemfilteran, atau setelah klik? Fase ini menentukan apakah Anda mengukur pekerjaan rendering, skrip, atau jaringan.
  2. Apakah tinggi kartu stabil? Variansi yang lebih besar meningkatkan nilai pengukuran nyata atau contain-intrinsic-size: auto yang mengingat ukuran yang sudah dirender.
  3. Apakah konten di luar layar harus tetap dapat dicari, difokuskan, dan dapat diakses oleh teknologi asistif? Jika ya, hidden bukanlah pengganti langsung untuk display: none.
  4. Apakah kode membaca offsetHeight atau getBoundingClientRect() selama setiap scroll atau pembaruan status? Pembacaan semacam itu dapat menarik kembali pekerjaan rendering yang dilewati ke dalam critical path.

Kerangka Jawaban 30 Detik

"Pertama, saya akan menggunakan panel Performance untuk memastikan bahwa merender subtree di luar layar adalah bottleneck-nya. Saya akan membagi feed menjadi bagian-bagian independen, menerapkan content-visibility: auto pada bagian non-kritis, dan memberikan contain-intrinsic-size yang realistis agar size containment tidak membuatnya terlihat kosong. Kemudian saya akan menguji fokus, find-in-page, dan perilaku teknologi asistif, serta mengaudit pembacaan DOM yang memicu layout paksa. Terakhir, saya akan membandingkan render pertama, scrolling, INP, CLS, dan fallback properti yang tidak didukung terhadap grup kontrol."

Jawaban Mendalam Langkah demi Langkah

1. Menetapkan batasan rendering

Bagi halaman panjang menjadi bagian-bagian atau kartu yang independen. Perubahan layout di dalam satu batas tidak boleh memengaruhi area yang tidak terkait; jika tidak, containment dapat menyembunyikan dependensi nyata dan menghasilkan layout yang salah.

css
.story {
  content-visibility: auto;
  contain-intrinsic-size: auto 720px;
}

Ketika suatu bagian berada jauh dari viewport, auto memungkinkan browser melewati sebagian pekerjaan style, layout, dan paint dari turunannya; saat mendekati viewport, browser akan merendernya sesuai kebutuhan. DOM tetap ada.

2. Menyediakan placeholder ukuran

Bagian di luar layar untuk sementara diberi ukuran tanpa memeriksa isinya. Tanpa tinggi eksplisit atau ukuran intrinsik, bagian tersebut dapat terlihat seperti kotak kosong yang sangat pendek, mengubah panjang scrollbar dan posisi scroll pengguna.

contain-intrinsic-size: auto 720px memberikan perkiraan awal. Setelah rendering, browser dapat mengingat ukuran sebenarnya. Turunkan perkiraan tersebut dari sampel produksi daripada memilih angka acak. Untuk variansi yang besar, kelompokkan tipe konten atau berikan petunjuk ukuran bersama data.

3. Membedakan auto, hidden, dan display none

  • auto: melewati rendering di luar layar dan melanjutkannya di dekat viewport; konten tetap berada di DOM dan accessibility tree.
  • hidden: mempertahankan status rendering sambil selalu melewati rendering; ini cocok untuk tampilan yang tidak aktif, bukan untuk setiap kebutuhan menyembunyikan aksesibilitas.
  • display: none: menghapus status layout dan rendering, sehingga menampilkannya kembali membutuhkan pembuatan ulang status tersebut.

Jika konten harus tidak terlihat oleh teknologi asistif, gunakan aria-hidden yang benar secara semantik atau hapus dari DOM, dan pastikan fokus tidak dapat masuk ke area yang tersembunyi.

4. Mengaudit pembacaan yang menggagalkan optimasi

Pembacaan layout yang sering pada bagian content-visibility dapat memaksa browser menghitung subtree yang dilewati lebih awal. Lakukan pengukuran hanya saat diperlukan, lakukan batching pembacaan sebelum penulisan, dan hindari pembacaan dan penulisan bergantian yang memicu layout sinkron.

js
requestAnimationFrame(() => {
  const height = card.getBoundingClientRect().height;
  card.style.setProperty('--measured-height', `${height}px`);
});

Ini mengilustrasikan waktu eksekusi, bukan resep universal. Gunakan rekaman Performance untuk membuktikan bahwa pembacaan memicu long task sebelum menghapusnya.

5. Memverifikasi dengan metrik yang berorientasi pada pengguna

Minimal, uji hal-hal berikut:

  • Render pertama dan total waktu rendering, untuk membuktikan pekerjaan di luar layar telah berkurang.
  • INP atau long task saat klik, untuk melihat apakah main thread memiliki kelonggaran beban.
  • CLS dan posisi scroll, untuk menangkap lompatan akibat ukuran placeholder.
  • Tab keyboard, find-in-page, dan screen reader, untuk memverifikasi perilaku aksesibilitas auto.
  • Browser yang tidak didukung, untuk memastikan perilaku default visible tetap merender semua konten.

Contoh dari web.dev mengurangi rendering halaman tertentu dari 232ms menjadi 30ms. Perlakukan itu sebagai hasil eksperimen, bukan janji untuk setiap situs; kesimpulan Anda harus berasal dari pengukuran kontrol dan perlakuan Anda sendiri.

Contoh Jawaban Berkualitas Tinggi

Saya akan mendefinisikan gejalanya sebagai pekerjaan rendering yang berlebihan untuk konten di luar layar, kemudian mengonfirmasi di panel Performance bahwa style, layout, atau paint mendominasi main thread. Setelah konfirmasi, saya akan membagi halaman menjadi bagian-bagian independen, mengatur content-visibility: auto, dan memperkirakan contain-intrinsic-size dari konten representatif. Browser kemudian dapat melewati rendering turunan di luar layar sambil tetap mempertahankan DOM dan akses teknologi asistif.

Saya tidak akan berhenti pada waktu render pertama saja. Saya akan memeriksa pergerakan scrollbar, fokus, dan find-in-page, serta mencari pembacaan getBoundingClientRect atau offsetHeight yang memaksakan layout saat scrolling atau pembaruan status. Saya akan membandingkan render pertama, long task saat scroll, INP, CLS, dan data pengguna nyata. Jika tinggi kartu sangat bervariasi atau batas memiliki dependensi layout lintas-bagian, saya akan merevisi pembagian dan strategi pengukuran. Browser yang tidak didukung akan mendapatkan perilaku default visible, sehingga optimasi tetap menjadi progressive enhancement.

Kesalahan Umum

  • Kesalahan → Menambahkan content-visibility: auto ke seluruh halaman → Alasan gagal → batas yang tidak jelas menyembunyikan dependensi layout dan membuat atribusi menjadi tidak mungkin → Perbaikan → bagi menjadi bagian-bagian independen dan catat baseline terlebih dahulu.
  • Kesalahan → Menghilangkan intrinsic sizing → Alasan gagal → size containment dapat meremehkan tinggi bagian, memperburuk scroll dan CLS → Perbaikan → perkirakan dari sampel dan amati posisi scroll yang sebenarnya.
  • Kesalahan → Menggunakan hidden sebagai sinonim untuk aria-hiddenAlasan gagal → penyembunyian visual dan semantik aksesibilitas berbeda → Perbaikan → pilih penghapusan DOM, aria-hidden, atau konten yang dipertahankan sesuai dengan semantik produk.
  • Kesalahan → Menghapus setiap pembacaan DOM yang terkait dengan performa → Alasan gagal → beberapa pengukuran diperlukan dan penghapusan secara membabi buta akan merusak perilaku → Perbaikan → gunakan rekaman performa untuk mengidentifikasi pembacaan yang benar-benar memaksakan layout.

Pertanyaan Lanjutan dan Tanggapan

Apakah Anda akan menggunakan satu intrinsic size jika tinggi kartu bervariasi hingga lima kali lipat?

Tidak. Satu perkiraan akan membuat beberapa kartu terlalu pendek atau terlalu tinggi secara drastis. Saya akan mengelompokkan jenis konten, memprioritaskan ukuran yang dirender dan diingat, dan, jika perlu, mengembalikan petunjuk ukuran dari server. Saya akan menggunakan CLS dan scroll error untuk memutuskan apakah kompleksitas pengelompokan tambahan tersebut sepadan.

Apakah content-visibility cukup jika produk mengharuskan decoding video di luar layar dihentikan sepenuhnya?

Tidak. Properti ini terutama mengontrol pekerjaan rendering dan tidak menggantikan pengelolaan siklus hidup media. Saya akan menjeda dan melanjutkan video saat visibilitas berubah, memastikan logika tersebut tidak membaca layout subtree yang dilewati secara berulang kali, dan mengukur kebijakan media secara terpisah dari optimasi CSS.

Bagaimana Anda merilis ke browser yang tidak mendukung properti ini?

Saya tidak akan membuat fungsionalitas bergantung padanya. Nilai default-nya adalah visible, sehingga halaman tetap utuh; progressive enhancement dan pemantauan kompatibilitas dapat menunjukkan apakah browser lama memerlukan paginasi atau virtual list sebagai gantinya.

Bagaimana Anda membuktikan bahwa peningkatan performa berasal dari properti ini, bukan karena DOM yang lebih kecil?

Pertahankan data dan struktur DOM yang sama dan ubah hanya properti CSS dalam kontrol lokal atau A/B. Catat waktu rendering, long task, INP, dan CLS. Jika paginasi, image lazy loading, atau penjadwalan skrip juga berubah, hasilnya tidak dapat diatribusikan hanya ke satu properti.

Sumber publik

Pertanyaan terkait