Rendering sisi klien untuk HTML dan interaktivitas

Merender HTML dengan JavaScript berbeda dengan merender HTML yang dikirim oleh server—dan yang dapat memengaruhi performa. Pelajari perbedaannya dalam panduan ini, dan tindakan yang dapat Anda lakukan untuk mempertahankan performa rendering situs—terutama dalam hal interaksi.

Penguraian dan perenderan HTML adalah hal yang secara default dilakukan browser dengan sangat baik untuk situs yang menggunakan logika navigasi bawaan browser—terkadang disebut "pemuatan halaman tradisional" atau "navigasi keras". Situs semacam ini terkadang disebut aplikasi multi-halaman (MPA).

Namun, developer dapat menyiasati default browser agar sesuai dengan kebutuhan aplikasi mereka. Hal ini tentu berlaku untuk situs yang menggunakan pola aplikasi web satu halaman (SPA), yang secara dinamis membuat sebagian besar HTML/DOM di klien menggunakan JavaScript. Rendering sisi klien adalah nama untuk pola desain ini, dan dapat memiliki efek pada Interaction to Next Paint (INP) situs Anda jika pekerjaan yang diperlukan berlebihan.

Panduan ini akan membantu Anda mempertimbangkan perbedaan antara menggunakan HTML yang dikirim oleh server ke browser dan membuatnya pada klien dengan JavaScript, dan bagaimana penggunaan HTML pada klien dapat menghasilkan latensi interaksi yang tinggi pada momen penting.

Cara browser merender HTML yang disediakan oleh server

Pola navigasi yang digunakan di pemuatan halaman tradisional melibatkan penerimaan HTML dari server pada setiap navigasi. Jika Anda memasukkan URL di kolom URL browser atau mengklik link di MPA, rangkaian peristiwa berikut akan terjadi:

  1. Browser mengirimkan permintaan navigasi untuk URL yang diberikan.
  2. Server merespons dengan HTML dalam potongan.

Langkah terakhir ini adalah kuncinya. Ini juga merupakan salah satu pengoptimalan performa paling mendasar dalam pertukaran server/browser dan dikenal sebagai streaming. Jika server dapat mulai mengirim HTML sesegera mungkin, dan browser tidak menunggu seluruh respons tiba, browser dapat memproses HTML dalam potongan saat diterima.

Screenshot penguraian HTML yang dikirim oleh server yang divisualisasikan di panel performa Chrome DevTools. Saat stream HTML masuk, potongan diproses pada beberapa tugas yang lebih singkat, dan rendering bersifat inkremental.
Penguraian dan rendering HTML yang disediakan oleh server seperti yang divisualisasikan di panel performa Chrome DevTools. Tugas-tugas yang terlibat dalam mengurai HTML dan merendernya dibagi menjadi beberapa potongan.

Seperti kebanyakan hal yang terjadi di browser, menguraikan HTML terjadi dalam tugas. Saat HTML di-streaming dari server ke browser, browser akan mengoptimalkan penguraian HTML dengan melakukannya sedikit demi sedikit karena bit aliran data tersebut masuk dalam jumlah potongan. Konsekuensinya adalah browser akan kembali ke thread utama secara berkala setelah memproses setiap potongan, sehingga menghindari tugas yang panjang. Ini berarti bahwa pekerjaan lain dapat terjadi saat HTML sedang diuraikan, termasuk pekerjaan rendering inkremental yang diperlukan untuk menampilkan halaman kepada pengguna, serta memproses interaksi pengguna yang mungkin terjadi selama periode mulai penting halaman. Pendekatan ini memberikan skor Interaction to Next Paint (INP) yang lebih baik untuk halaman tersebut.

Kesimpulannya? Saat melakukan streaming HTML dari server, Anda mendapatkan penguraian dan rendering HTML inkremental dan hasil otomatis ke rangkaian pesan utama secara gratis. Anda tidak dapat melakukannya dengan rendering sisi klien.

Cara browser merender HTML yang disediakan oleh JavaScript

Meskipun setiap permintaan navigasi ke halaman memerlukan sejumlah HTML yang disediakan oleh server, beberapa situs akan menggunakan pola SPA. Pendekatan ini sering melibatkan payload awal minimal HTML yang disediakan oleh server, tetapi kemudian klien akan mengisi area konten utama halaman dengan HTML yang dikumpulkan dari data yang diambil dari server. Navigasi berikutnya—terkadang disebut sebagai "navigasi lunak" dalam kasus ini—ditangani seluruhnya oleh JavaScript untuk mengisi laman dengan HTML baru.

Rendering sisi klien juga dapat terjadi di non-SPA dalam kasus yang lebih terbatas saat HTML ditambahkan secara dinamis ke DOM melalui JavaScript.

Ada beberapa cara umum untuk membuat HTML atau menambahkan ke DOM melalui JavaScript:

  1. Properti innerHTML memungkinkan Anda menetapkan konten pada elemen yang ada melalui string, yang diurai browser ke dalam DOM.
  2. Metode document.createElement memungkinkan Anda membuat elemen baru untuk ditambahkan ke DOM tanpa menggunakan penguraian HTML browser apa pun.
  3. Metode document.write memungkinkan Anda menulis HTML ke dokumen (dan browser menguraikannya, seperti dalam pendekatan #1). Namun, karena sejumlah alasan, penggunaan document.write sangat tidak dianjurkan.
Screenshot penguraian HTML yang dirender melalui JavaScript yang divisualisasikan di panel performa Chrome DevTools. Pekerjaan terjadi dalam satu tugas panjang yang memblokir thread utama.
Penguraian dan rendering HTML melalui JavaScript pada klien seperti yang divisualisasikan di panel performa Chrome DevTools. Tugas yang terlibat dalam mengurai dan merendernya tidak terpotong, sehingga tugas panjang yang memblokir thread utama.

Konsekuensi dari pembuatan HTML/DOM melalui JavaScript sisi klien bisa sangat signifikan:

  • Tidak seperti HTML yang di-streaming oleh server sebagai respons terhadap permintaan navigasi, tugas JavaScript pada klien tidak secara otomatis terpotong, yang dapat mengakibatkan tugas yang panjang yang memblokir thread utama. Artinya, INP halaman Anda dapat terkena dampak negatif jika Anda membuat terlalu banyak HTML/DOM sekaligus di klien.
  • Jika HTML dibuat di klien selama startup, resource yang dirujuk di dalamnya tidak akan ditemukan oleh pemindai pramuat browser. Hal ini tentu akan berdampak negatif pada Largest Contentful Paint (LCP) halaman. Meskipun ini bukan masalah performa runtime (melainkan masalah penundaan jaringan dalam pengambilan resource penting), Anda tidak ingin LCP situs Anda terpengaruh dengan menghindari pengoptimalan performa browser mendasar ini.

Yang dapat Anda lakukan terkait dampak performa rendering sisi klien

Jika situs Anda sangat bergantung pada rendering sisi klien dan Anda telah melihat nilai INP yang buruk di data kolom, Anda mungkin ingin tahu apakah rendering sisi klien ada hubungannya dengan masalah tersebut. Misalnya, jika situs Anda adalah SPA, data kolom Anda dapat mengungkapkan interaksi yang bertanggung jawab atas pekerjaan rendering yang cukup besar.

Apa pun penyebabnya, berikut beberapa penyebab potensial yang dapat Anda pelajari untuk membantu agar keadaan kembali normal.

Sediakan HTML sebanyak mungkin dari server

Seperti yang disebutkan sebelumnya, browser menangani HTML dari server dengan cara yang sangat berperforma tinggi secara default. Ini akan memecah penguraian dan rendering HTML sedemikian rupa sehingga menghindari tugas yang panjang, dan mengoptimalkan jumlah total waktu thread utama. Hal ini menyebabkan Total Blocking Time (TBT) yang lebih rendah, dan TBT berkorelasi kuat dengan INP.

Anda mungkin mengandalkan framework frontend untuk membangun situs Anda. Jika demikian, pastikan Anda merender HTML komponen di server. Hal ini akan membatasi jumlah rendering sisi klien awal yang diperlukan situs Anda, dan seharusnya menghasilkan pengalaman yang lebih baik.

  • Untuk React, Anda dapat menggunakan Server DOM API untuk merender HTML di server. Namun, perhatikan: metode tradisional rendering sisi server menggunakan pendekatan sinkron, yang dapat menghasilkan Time to First Byte (TTFB) yang lebih lama, serta metrik berikutnya seperti First Contentful Paint (FCP) dan LCP. Jika memungkinkan, pastikan Anda menggunakan API streaming untuk Node.js atau runtime JavaScript lainnya, sehingga server dapat memulai streaming HTML ke browser sesegera mungkin. Next.js—framework berbasis React—menyediakan banyak praktik terbaik secara default. Selain merender HTML secara otomatis di server, layanan ini juga dapat menghasilkan HTML secara statis untuk halaman yang tidak berubah berdasarkan konteks pengguna (seperti autentikasi).
  • Vue juga melakukan rendering sisi klien secara default. Namun, seperti React, Vue juga dapat merender HTML komponen di server. Manfaatkan API sisi server ini jika memungkinkan, atau pertimbangkan abstraksi tingkat tinggi untuk project Vue Anda agar praktik terbaik lebih mudah diterapkan.
  • Svelte merender HTML di server secara default—meskipun jika kode komponen Anda memerlukan akses ke namespace khusus browser (misalnya window), Anda mungkin tidak dapat merender HTML komponen tersebut di server. Pelajari pendekatan alternatif jika memungkinkan sehingga Anda tidak menyebabkan rendering sisi klien yang tidak perlu. SvelteKit—yaitu Svelte sebagaimana Next.js untuk React—menyematkan banyak praktik terbaik ke dalam project Svelte Anda sebanyak mungkin, sehingga Anda dapat menghindari potensi kesalahan dalam project yang menggunakan Svelte saja.

Batasi jumlah node DOM yang dibuat pada klien

Bila DOM berukuran besar, pemrosesan yang diperlukan untuk merendernya cenderung meningkat. Apakah situs Anda adalah SPA lengkap, atau memasukkan node baru ke dalam DOM yang ada sebagai hasil dari interaksi untuk MPA, pertimbangkan untuk menjaga DOM tersebut sekecil mungkin. Hal ini akan membantu mengurangi pekerjaan yang diperlukan selama rendering sisi klien untuk menampilkan HTML tersebut, yang diharapkan dapat membantu menjaga INP situs Anda lebih rendah.

Mempertimbangkan arsitektur pekerja layanan streaming

Ini adalah teknik lanjutan—salah satu yang mungkin tidak mudah berfungsi di setiap kasus penggunaan—tetapi itulah teknik yang dapat mengubah MPA Anda menjadi situs yang terasa seperti dimuat seketika ketika pengguna menavigasi dari satu halaman ke halaman berikutnya. Anda dapat menggunakan pekerja layanan untuk melakukan pra-cache bagian statis situs di CacheStorage saat menggunakan ReadableStream API untuk mengambil HTML halaman lainnya dari server.

Jika berhasil menggunakan teknik ini, Anda tidak membuat HTML pada klien, tetapi pemuatan langsung sebagian konten dari cache akan memberikan kesan bahwa situs Anda dimuat dengan cepat. Situs web yang menggunakan pendekatan ini bisa terasa hampir seperti SPA, tetapi tanpa gangguan dari perenderan sisi klien. Hal ini juga mengurangi jumlah HTML yang Anda minta dari server.

Singkatnya, arsitektur pekerja layanan streaming tidak menggantikan logika navigasi bawaan browser, melainkan ditambahkan ke dalamnya. Untuk mengetahui informasi selengkapnya tentang cara melakukannya dengan Workbox, baca Aplikasi multihalaman yang lebih cepat dengan streaming.

Kesimpulan

Cara situs Anda menerima dan merender HTML memiliki dampak pada performa. Ketika Anda mengandalkan server untuk mengirim semua (atau sebagian besar) HTML yang diperlukan agar situs Anda berfungsi, Anda mendapatkan banyak manfaat secara gratis: penguraian dan rendering inkremental, dan otomatis menghasilkan thread utama untuk menghindari tugas yang panjang.

Rendering HTML sisi klien memperkenalkan sejumlah potensi masalah performa yang dapat dihindari dalam banyak kasus. Namun, karena persyaratan masing-masing situs, hal ini tidak sepenuhnya dapat dihindari. Untuk mengurangi potensi tugas panjang yang dapat dihasilkan dari rendering situs klien yang berlebihan, pastikan Anda mengirim sebanyak mungkin HTML situs web Anda dari server jika memungkinkan, pertahankan ukuran DOM Anda sekecil mungkin untuk HTML yang harus dirender di klien, dan pertimbangkan arsitektur alternatif untuk mempercepat penayangan HTML ke klien sekaligus memanfaatkan penguraian inkremental dan perenderan yang disediakan browser untuk HTML yang dimuat dari server.

Jika Anda bisa mendapatkan rendering sisi klien situs seminimal mungkin, Anda tidak hanya akan meningkatkan INP situs, tetapi juga metrik lainnya seperti LCP, TBT, dan bahkan mungkin TTFB dalam beberapa kasus.

Banner besar dari Unsplash, oleh Maik Jonietz.