D
P
0
← Semua artikel Read in English

JavaScript, DOM & Animasi Browser

Lenis di <head> Bikin 'document.body is null' dan Memblokir Render, Pindahkan ke Footer

· · 2 menit baca
Lenis di <head> Bikin 'document.body is null' dan Memblokir Render, Pindahkan ke Footer

Saya menambahkan Lenis untuk smooth scroll ke sebuah situs sinematik yang saya bangun, dan bukannya scroll yang mulus, saya malah dapat dua masalah sekaligus. Pertama, console langsung melempar:

TypeError: document.body is null

Kedua, halaman terasa lebih lambat tampil. Ada jeda render yang sebelumnya tidak ada. Animasi belum sempat dinikmati, malah situsnya makin berat di muka.

Kenapa ini terjadi

Kedua masalah ini berasal dari satu kesalahan yang sama: library Lenis di-enqueue di dalam <head> dokumen.

Saat sebuah script ditaruh di <head>, ia dieksekusi sebelum browser selesai mem-parse <body>. Pada titik itu, document.body masih null. Lenis butuh elemen body saat inisialisasi (ia memasang listener dan membaca dimensi dari body), jadi ketika init jalan terlalu dini:

const lenis = new Lenis(); // document.body masih null di sini

…ia langsung melempar TypeError: document.body is null. Smooth scroll-nya bahkan tidak pernah aktif.

Dan masalah kedua adalah konsekuensi dari posisi yang sama: script di <head> itu render-blocking. Browser harus mengunduh dan mengeksekusinya sebelum melanjutkan render dokumen. Jadi selain error, Lenis di head juga menahan first paint.

Perbaikan untuk kedua masalah ini sama persis dan cuma satu langkah: pindahkan enqueue library Lenis dan init-nya ke footer dokumen.

Di lingkungan WordPress, itu berarti set argumen $in_footer ke true:

wp_enqueue_script(
    'lenis',
    'https://unpkg.com/lenis@1/dist/lenis.min.js',
    [],
    null,
    true // ← in_footer: jalankan setelah body ada
);

Atau di HTML biasa, cukup taruh <script> tepat sebelum </body>:

    <!-- ... isi halaman ... -->
    <script src="/js/lenis.min.js"></script>
    <script src="/js/lenis-init.js"></script>
  </body>

Begitu Lenis dimuat di footer, ia jalan setelah <body> ada. document.body tidak lagi null, init berhasil, TypeError hilang. Dan karena tidak lagi di head, ia berhenti memblokir render. Satu pemindahan, dua masalah selesai.

Pengerasan tambahan dari proyek yang sama

Sambil membereskan ini, ada beberapa hal lain yang harus saya tangani agar Lenis tidak bertabrakan dengan bagian lain situs:

<div class="search-overlay__body" data-lenis-prevent>
  <!-- isi yang bisa di-scroll secara native -->
</div>
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!reduceMotion) {
  const lenis = new Lenis();
  // ... raf loop
}

Pelajaran

Library smooth-scroll yang menyentuh document.body harus dimuat setelah body ada. Enqueue di footer, jangan pernah di head. Dan ingat, script di head itu render-blocking apa pun isinya, jadi memindahkannya ke footer sekaligus menyembuhkan error document.body is null dan jeda render dalam satu gerakan. Sisanya adalah pengerasan yang membuat smooth scroll terasa benar tanpa merusak interaksi lain: data-lenis-prevent di scroller dalam, melewati Lenis di halaman canvas 3D, dan menghormati prefers-reduced-motion.