Topik wawancara representatif

Wawancara Frontend: Bagaimana Cara Memuat Skrip Pihak Ketiga Tanpa Mengorbankan Performa?

FrontendSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah halaman produk e-commerce memuat skrip analitik, chat, periklanan, dan A/B testing. LCP p75 pengguna nyata di perangkat seluler adalah 3,8 detik dan INP adalah 280 milidetik; JavaScript pihak ketiga mentransfer sekitar 1,2 MB dari 14 origin. Bagaimana Anda akan menginventarisasi, memprioritaskan, memuat, mengisolasi, dan memvalidasi skrip-skrip ini?

Prompt dan konteks

Sebuah halaman produk e-commerce memuat skrip analitik, chat, periklanan, dan A/B testing. LCP p75 pengguna nyata di perangkat seluler adalah 3,8 detik dan INP adalah 280 milidetik; JavaScript pihak ketiga mentransfer sekitar 1,2 MB dari 14 origin, sementara pengujian lab desktop terlihat baik-baik saja. Anda harus mempertahankan kapabilitas bisnis yang penting sembari membatasi dampak pihak ketiga terhadap jaringan, main thread, privasi, dan ketersediaan halaman.

Perjelas empat batasan terlebih dahulu: skrip mana yang harus berjalan sebelum tampilan pertama (first screen), mana yang hanya diperlukan setelah interaksi, apakah skrip bergantung pada urutan satu sama lain, apakah data boleh dikirim sebelum persetujuan, dan apakah pemadaman (outage) pihak ketiga dapat memblokir proses checkout. Kode pihak ketiga adalah bagian dari lingkungan eksekusi halaman; kode tersebut tidak dapat diperlakukan sebagai aset statis biasa yang dimiliki tim lain selamanya.

Topik ini cocok untuk wawancara frontend, web-platform, dan performance-engineering. Materi wawancara frontend publik memperlakukan async, defer, urutan skrip, dan kompromi performa sebagai dasar-dasar yang berulang; materi web.dev, MDN, dan W3C menyediakan dasar teknis untuk waktu pemuatan, long task, CSP, dan kontrol sumber. Inti dari pertanyaan ini adalah tata kelola dan pembuktian, bukan menghafal komponen framework.

Hal yang dinilai oleh pewawancara

Jawaban yang lemah akan mengatakan “tambahkan async di mana-mana” atau “letakkan skrip di bagian bawah halaman.” Jawaban yang kuat menginventarisasi skrip berdasarkan nilai bagi pengguna dan dampak pada critical path, lalu memilih async, defer, modul, pemuatan yang dipicu oleh interaksi, atau facade iframe berdasarkan dependensi dan batasan kegagalan.

Pewawancara menginginkan lima sinyal: apakah kandidat dapat memisahkan waktu unduh dari waktu eksekusi; menjelaskan async yang tidak berurutan vs defer yang berurutan; menggabungkan anggaran performa, persetujuan, CSP/SRI, dan risiko rantai pasok (supply-chain); mengisolasi kegagalan vendor tanpa memblokir checkout; dan menggunakan RUM, data long task, serta perbandingan terkontrol untuk membuktikan perubahan tersebut.

Skor Lighthouse saja tidak cukup. Kondisi lab tidak mewakili ponsel low-end, jaringan lambat, pemblokir konten, atau server vendor yang terhenti (stall); jawaban harus mencakup persentil pengguna nyata, waktu eksekusi skrip, dan tingkat penyelesaian bisnis.

Pertanyaan klarifikasi untuk diajukan terlebih dahulu

  • Skrip mana yang benar-benar dibutuhkan untuk first paint atau interaksi pertama? Pembayaran dan pemeriksaan penipuan (fraud) penting mungkin bersifat kritis; chat, rekomendasi, dan replay biasanya dapat menunggu interaksi atau idle time.
  • Apakah skrip bergantung satu sama lain? Analitik independen dapat menggunakan async; kode aplikasi yang bergantung pada DOM atau urutan biasanya menggunakan defer; dependensi yang tidak diketahui tidak boleh diparalelkan.
  • Apa yang diizinkan sebelum persetujuan (consent)? Tentukan tujuan, wilayah, dan status persetujuan sebelum membuat skrip, cookie, permintaan jaringan, atau pengukuran anonim.
  • Data halaman apa yang boleh diakses oleh vendor? Kode same-origin dapat membaca konteks halaman; jika chat atau iklan hanya perlu me-render tampilan, prioritaskan iframe atau server-side event dengan permukaan izin yang lebih kecil.
  • Bagaimana pengalaman pengguna saat terjadi kegagalan? Pembelian, login, dan navigasi memerlukan jalur pihak pertama (first-party); batas waktu (timeout) vendor tidak boleh membuat tombol kritis atau main thread menunggu selamanya.
  • Bisakah vendor diganti atau di-host sendiri (self-hosted)? Self-hosting dapat menghilangkan risiko DNS dan ketersediaan vendor tetapi menambah kepemilikan pembaruan, integritas, lisensi, dan cache; ini tidak otomatis lebih aman.

Kerangka jawaban 30 detik

“Saya akan membangun inventaris yang mencatat nilai bisnis, dependensi, byte, permintaan, waktu main-thread, tujuan data, dan dampak kegagalan, lalu mengklasifikasikan setiap skrip sebagai kritis, ditangguhkan (deferred), atau dapat dihapus. Skrip independen menggunakan async; skrip yang bergantung pada DOM atau urutan menggunakan defer; widget interaktif menggunakan facade atau iframe. Saya tidak akan membuat pelacak non-esensial sebelum adanya persetujuan. CSP hanya akan mengizinkan origin yang telah ditinjau, dan aset tetap dapat menggunakan SRI. Setiap vendor mendapatkan anggaran byte, waktu eksekusi, dan error. RUM akan membandingkan LCP, INP, long task, konversi, dan error skrip berdasarkan perangkat dan status persetujuan. Saya akan menguji penghapusan atau penangguhan secara bertahap (gray out) terlebih dahulu, lalu menggunakan injeksi kegagalan (fault injection) dan rollback untuk membuktikan bahwa halaman tetap dapat menyelesaikan tugas inti.”

Jawaban mendalam langkah demi langkah

1. Bangun inventaris dan critical path

Catat vendor, versi, pemicu, dependensi, origin permintaan, byte transfer, waktu parsing dan eksekusi, long task, data yang dibaca, pemilik, dan syarat penghapusan setiap skrip. Nyatakan nilai sebagai hasil yang dapat diuji seperti “mengatribusikan kegagalan checkout,” bukan “meningkatkan pengalaman.” Skrip tanpa tujuan, pemilik, atau metrik yang jelas adalah kandidat untuk dihapus.

Gambarkan grafik dependensi untuk first paint dan interaksi pertama. Pertahankan hanya kode pihak pertama yang diperlukan untuk layar awal, login, keranjang, dan pembayaran pada critical path. Analitik, chat, rekomendasi, replay, dan tag pemasaran sering kali dapat menunggu hingga setelah paint atau interaksi eksplisit. Unduhan asinkron tidak menghilangkan biaya parsing, kompilasi, atau eksekusi pada main thread.

2. Pilih semantik pemuatan berdasarkan dependensi

Skrip klasik tanpa atribut akan memblokir parsing HTML. async mengunduh secara paralel dan mengeksekusi segera setelah siap, tanpa jaminan urutan; ini cocok untuk analitik independen atau iklan. defer juga mengunduh secara paralel tetapi berjalan setelah parsing sesuai urutan dokumen, yang cocok untuk kode yang membutuhkan DOM atau skrip lain. Skrip modul ditangguhkan secara default, tetapi grafik dependensinya tetap perlu ditinjau.

Gunakan tabel keputusan:

MetodeWaktu eksekusiPengurutanKecocokan yang baikRisiko utama
Skrip klasik polosDieksekusi setelah unduhan dan memblokir parsingUrutan dokumenBootstrap sinkron yang jarang terjadiMenunda parsing dan first paint
asyncDieksekusi saat unduhan selesaiTanpa jaminanAnalitik independen, iklan, widget sederhanaDapat menginterupsi parsing; balapan dependensi (race condition)
deferDieksekusi setelah parsing sesuai urutanDipertahankanKode yang bergantung pada DOM atau startupMasih menunda DOMContentLoaded
Dipicu interaksiSaat tindakan pengguna atau idle timeDikontrol pemuat (loader)Chat, peta, video, replayPembukaan pertama memiliki latensi ekstra
Facade IframeShell statis terlebih dahulu, embed terisolasi kemudianBatasan lintas dokumen (cross-document)Video, UI pembayaran, widget kompleksBiaya komunikasi dan aksesibilitas

Jangan menandai semua skrip yang saling bergantung dengan async. Jika plugin.js membutuhkan vendor.js, gunakan defer berurutan, impor modul, atau loader eksplisit alih-alih berharap waktu unduh akan pas.

3. Tangguhkan, pangkas, atau ganti fungsionalitas

Gunakan interaksi pengguna, requestIdleCallback dengan fallback batas waktu, atau antrean pasca-paint untuk pekerjaan yang tidak kritis. Tombol chat dapat berupa entri statis pihak pertama yang hanya membuat widget saat diklik; video dapat menampilkan thumbnail dan kontrol putar sebelum menyematkan iframe. Ini mengurangi beban jaringan dan main-thread pada layar awal serta menghindari membayar biaya untuk fitur yang tidak pernah digunakan pengguna.

Hapus tag manager duplikat, SDK analitik, dan eksperimen yang terbengkalai. Minta vendor untuk menyediakan build yang lebih ringkas, bundle khusus halaman, kompresi, dan caching. Self-hosting dapat mengurangi risiko DNS pihak ketiga atau ketersediaan, tetapi memerlukan pembaruan versi, SRI, lisensi, pembatalan cache, dan rollback; ini tidak menghilangkan biaya eksekusi.

4. Tentukan batasan privasi, keamanan, dan kegagalan

Sebelum persetujuan diketahui, jangan membuat skrip pelacakan non-esensial atau memuatnya dan hanya menonaktifkan pengiriman di kemudian waktu. Tentukan apakah penarikan persetujuan menghapus cookie, menghentikan antrean, dan mencegah permintaan berikutnya. Batasi origin dengan CSP script-src dan direktif koneksi terkait; gunakan SRI untuk sumber daya eksternal versi tetap. Audit pemuatan dinamis, dependensi yang dimuat vendor, dan strict-dynamic secara terpisah daripada hanya memercayai domain pertama.

Kode pihak ketiga yang berjalan secara same-origin memiliki permukaan izin yang luas. Tempatkan komponen yang hanya melakukan render di dalam iframe dan kirim bidang minimum melalui postMessage. Pertahankan pembelian, login, navigasi, dan pemulihan error sebagai pihak pertama; akhiri batas waktu vendor dengan timeout, circuit breaker, atau placeholder alih-alih memblokir alur inti.

5. Tetapkan anggaran dan pantau

Berikan setiap vendor dan jenis halaman anggaran untuk byte transfer, jumlah permintaan, eksekusi main-thread, long task, tingkat error, dan kontribusi terhadap LCP/INP. Melebihi anggaran akan memicu peninjauan atau degradasi otomatis, bukan tiket pembersihan di masa mendatang. Segmentasikan anggaran berdasarkan perangkat low-end, jaringan lambat, dan status persetujuan karena rata-rata dapat menyembunyikan kondisi ekstrem (tail).

Di lab, gunakan panel DevTools Performance dan Network, WebPageTest, serta fault injection untuk mengamati parsing, eksekusi, long task, dan single point of failure. Di produksi, gunakan RUM untuk mencatat sumber, resource timing, long task PerformanceObserver, LCP, INP, CLS, konversi, dan error. Bandingkan segmen perangkat, browser, wilayah, dan template halaman agar perubahan campuran lalu lintas (traffic mix) tidak disalahartikan sebagai pengoptimalan.

6. Rilis secara bertahap, lakukan rollback, dan kelola perubahan vendor

Terapkan secara bertahap (gray out) pada satu template halaman dan sebagian kecil lalu lintas seluler terlebih dahulu. Setiap perubahan skrip membawa versi, sumber, konfigurasi persetujuan, dan tombol rollback; pembaruan vendor mengikuti jalur yang sama. Jika skrip mengalami batas waktu atau melempar error, lewati atau lakukan degradasi secara default daripada mencoba lagi tanpa henti. Rollback mengembalikan manifes terakhir yang telah ditinjau alih-alih menarik versi yang tidak diketahui dari URL vendor.

Verifikasi invarian: pengguna dapat menjelajah, menambahkan ke keranjang, dan membeli ketika vendor gagal; data yang dibatasi tidak diminta tanpa persetujuan; anggaran skrip tetap berada di bawah batas; laporan CSP tidak menunjukkan origin baru; dan INP interaksi kritis tidak mengalami regresi. Pertahankan pemicu penghapusan atau penggantian eksplisit untuk setiap vendor.

7. Buat verifikasi yang dapat dieksekusi

Uji DNS yang lambat, kesalahan 5xx vendor, unduhan yang terputus di tengah jalan, exception yang dilempar, long task pada main-thread, penarikan persetujuan, cookie pihak ketiga yang dinonaktifkan, pemblokir konten, dan browser yang lebih lama. Pastikan lebih dari sekadar rendering visual: status pembelian, pemulihan, interaksi keyboard, pengumuman pembaca layar (screen-reader), dan batasan permintaan data.

Gunakan kelompok kontrol yang hanya mengubah satu strategi pemuatan, seperti sinkron ke tertunda (deferred), dengan menjaga aturan konten dan lalu lintas tetap konstan. Verifikasi p75/p95 LCP, INP, long task, byte sumber daya, konversi, dan error vendor. Jika checkout membaik tetapi pembukaan chat menjadi lebih lambat, laporkan kompromi tersebut dan sesuaikan pemicunya alih-alih hanya melaporkan satu skor yang menarik.

Contoh jawaban berkualitas tinggi

“Saya tidak akan memulai dengan menambahkan async ke seluruh 14 skrip. Saya akan menginventarisasi tujuan, dependensi, permintaan, byte, waktu main-thread, penggunaan data, pemilik, dan dampak kegagalan setiap skrip, lalu mengklasifikasikannya sebagai kritis, ditangguhkan, atau dapat dihapus. Pembayaran dan login tetap berada pada critical path pihak pertama; analitik independen dapat dibuat asinkron; kode yang bergantung pada DOM atau urutan menggunakan defer; chat, peta, dan video dimuat saat interaksi atau di balik facade iframe.

Sebelum adanya persetujuan, saya tidak akan membuat pelacak non-esensial. CSP akan mengizinkan sumber yang telah ditinjau dan aset tetap dapat menggunakan SRI. Widget yang hanya me-render diletakkan di dalam iframe, sementara pembelian dan navigasi mempertahankan fallback pihak pertama. Setiap vendor memiliki anggaran byte, eksekusi, long task, dan error.

Saya akan merilis perubahan secara bertahap ke kohort seluler kecil. Di lab, saya akan mencekik (throttle) jaringan, memeriksa trace Performance, dan menginjeksi kegagalan vendor. Di produksi, saya akan mensegmentasikan RUM berdasarkan perangkat, wilayah, dan status persetujuan serta membandingkan LCP, INP, CLS, long task, resource timing, konversi, dan error. Setiap perubahan dapat dibatalkan (reversible) dan pembaruan vendor ditinjau. Jika vendor gagal, pembelian inti tetap berfungsi; jika data dikirim sebelum persetujuan atau batas pengaman melebihi anggaran, peluncuran dihentikan.”

Kesalahan umum

  • Menambahkan async ke setiap skrip → skrip yang bergantung dapat berjalan di luar urutan dan eksekusi masih dapat menginterupsi parsing → petakan dependensi; gunakan async untuk pekerjaan independen dan defer atau modul untuk pekerjaan yang berurutan.
  • Hanya memindahkan tag ke akhir body → unduhan dan eksekusi masih bersaing untuk mendapatkan main thread dan interaksi dapat mengalami regresi → tangguhkan, pangkas, pisahkan, atau picu berdasarkan fungsi, lalu ukur biaya eksekusi.
  • Hanya menggunakan Lighthouse → kondisi lab mengabaikan perangkat low-end, jaringan lambat, dan vendor yang macet → bandingkan persentil pengguna nyata, long task, dan metrik bisnis.
  • Menonaktifkan pelacakan setelah persetujuan ditolak → skrip sudah berjalan dan mungkin telah mengirim permintaan → periksa persetujuan sebelum membuat skrip atau permintaan jaringan.
  • Memperlakukan self-hosting sebagai solusi keamanan yang lengkap → pembaruan, integritas, lisensi, dan biaya eksekusi tetap ada → gabungkan versi yang telah ditinjau, SRI, CSP, anggaran, dan rollback.
  • Mencoba lagi vendor yang gagal hingga berhasil → vendor menjadi single point of failure untuk halaman kritis → gunakan timeout, placeholder terdegradasi, dan jalur inti pihak pertama.

Pertanyaan lanjutan dan jawabannya

Pertanyaan lanjutan 1: Analitik harus segera mengirimkan event layar pertama. Bisakah itu menjadi kritis?

Pertama, periksa apakah event tersebut benar-benar harus dikirim sebelum first paint. Jika event page-view dapat dikelompokkan (batched) setelah paint dan potensi kehilangan data dapat diterima, tangguhkan pengirimannya. Jika atribusi atau kepatuhan membutuhkan pengiriman yang lebih awal, gunakan skrip async independen, timeout yang singkat, dan antrean pihak pertama yang kecil; jangan memblokir proses rendering. Tetapkan anggaran dengan membandingkan penundaan event dengan nilai bisnis dari LCP dan INP.

Pertanyaan lanjutan 2: Vendor hanya menyediakan URL dinamis. Bagaimana Anda bisa menggunakan SRI?

Anda tidak dapat menyematkan hash yang andal pada konten yang terus berubah. Mintalah aset berversi, bangun proses signed-release yang di-host sendiri, atau isolasi fitur tersebut di dalam iframe atau integrasi sisi server (server-side). CSP, audit akses, dan pemantauan perubahan akan mengurangi risiko. Jangan memalsukan hash atau menggantinya dengan unsafe-inline.

Pertanyaan lanjutan 3: Skrip pihak ketiga masih membuat long task dengan defer. Apa langkah berikutnya?

defer mengubah waktu eksekusi, bukan beban kerja parsing atau eksekusi itu sendiri. Gunakan trace Performance untuk mengidentifikasi skrip dan tugas tersebut, lalu minta vendor untuk membaginya, memicunya saat interaksi, menghapus fitur, atau memindahkan beban kerja ke iframe atau server-side event. Jika skrip tersebut harus berjalan, jadwalkan potongan kerja yang lebih kecil di idle time dengan timeout dan verifikasi bagian ekor distribusinya (tail) dengan RUM.

Pertanyaan lanjutan 4: Tim pemasaran ingin lima tag ditambahkan sekaligus. Apa yang Anda katakan?

Wajibkan setiap tag untuk menyatakan tujuan, pemilik, keputusan yang diharapkan, kategori persetujuan, anggaran performa, dan syarat penghapusan. Periksa apakah ada pengumpulan data duplikat atau event yang sudah ada yang dapat menjawab kebutuhan tersebut. Ukur di dalam sandbox dan luncurkan secara bertahap hanya setelah nilainya jelas. Tag tanpa nilai yang terukur atau yang melebihi batas anggaran tidak boleh masuk ke produksi.

Sumber publik

Pertanyaan terkait