Pembaruan parsial deklaratif

Dipublikasikan: 19 Mei 2026, Terakhir diperbarui: 8 September 2026

Web telah lama beralih dari media statis berbasis dokumen yang menjadi awalnya. Aplikasi web modern yang kaya fitur digunakan oleh semua orang karena berbagai alasan, mulai dari berkomunikasi, membeli, menggunakan konten multimedia, hingga mengelola kehidupan kita yang kompleks.

HTML, meskipun dengan semua kemajuannya, masih dikirimkan secara berurutan dari atas ke bawah dengan sedikit memperhatikan kapan konten siap atau kapan pengguna menggunakannya. CSS memungkinkan Anda mengubah urutan konten, tetapi sering kali dengan efek samping aksesibilitas yang signifikan. JavaScript memungkinkan Anda memanipulasi DOM melalui berbagai API untuk mengatasi hal ini, tetapi sering kali memerlukan sintaksis yang panjang, atau konstruksi pohon DOM untuk dihubungkan ke HTML.

Performa sangat penting untuk web, mengingat sifat media client-server. Namun, pilihan yang kurang optimal sering kali dibuat untuk menghindari sifat HTML yang berurutan ini, yang memperlambat performa. Hal ini mencakup menunggu hingga seluruh halaman siap atau menggunakan framework berat untuk mengirimkan komponen secara asinkron. Popularitas framework JavaScript menunjukkan bahwa developer web lebih memilih model berbasis komponen daripada model mental dokumen yang kaku dari asal-usul web.

Tim Chrome telah mempertimbangkan masalah ini dan telah mengembangkan tambahan baru pada platform web dengan nama Update Parsial Deklaratif.

Dua set API baru pertama mempermudah pengiriman HTML dengan cara yang kurang linear, baik di luar urutan dalam dokumen HTML itu sendiri, atau melalui cara yang lebih mudah untuk menyisipkan HTML secara dinamis ke dalam dokumen yang ada menggunakan API JavaScript baru. Polyfill juga tersedia agar Anda dapat langsung menggunakan API baru ini, bahkan di browser yang belum mendukungnya.

Streaming yang tidak berurutan

Browser Support

  • Chrome: 150.
  • Edge: 150.
  • Firefox: not supported.
  • Safari: not supported.

Source

Kumpulan perubahan pertama adalah API streaming di luar urutan baru yang menggunakan placeholder petunjuk pemrosesan dan elemen HTML <template> dengan atribut for. Contoh:

<div>
  <?marker name="placeholder">
</div>

...

<template for="placeholder">
  Here is some <em>HTML content</em>!
</template>

Petunjuk pemrosesan telah ada di XML sejak lama, tetapi telah diperlakukan sebagai komentar di HTML dan diabaikan. API baru ini mengubahnya dan menghadirkan petunjuk pemrosesan ke HTML. Misalnya, saat browser melihat petunjuk pemrosesan <?marker name="placeholder">, browser tidak akan langsung melakukan apa pun—seperti sebelumnya—tetapi petunjuk tersebut dapat dirujuk nanti.

Elemen <template> dengan atribut for mencari petunjuk pemrosesan yang sesuai dengan atribut name dan mengganti konten. Dalam hal ini, setelah diuraikan, DOM akan menjadi seperti berikut (mengabaikan beberapa perbedaan ruang kosong):

<div>
  Here is some <em>HTML content</em>!
</div>

Selain atribut <?marker> untuk penggantian, ada juga penanda rentang <?start> dan <?end> yang memungkinkan konten placeholder sementara ditampilkan sebelum template diproses:

<div>
  <?start name="another-placeholder">
  Loading…
  <?end>
</div>

...

<template for="another-placeholder">
  Here is some <em>HTML content</em>!
</template>

Dalam hal ini, string Loading… ditampilkan hingga <template> terlihat, lalu diganti dengan konten baru.

Anda juga dapat menyertakan petunjuk pemrosesan dalam template untuk memungkinkan beberapa pembaruan:

<ul id="results">
  <?start name="results">
  Loading…
  <?end>
</ul>

...

<template for="results">
  <li>Result One</li>
  <?marker name="results">
</template>

...

<template for="results">
  <li>Result Two</li>
  <?marker name="results">
</template>

...

Hal ini akan menghasilkan HTML berikut setelah diuraikan dan diproses:

<ul id="results">
  <li>Result One</li>
  <li>Result Two</li>
  <?marker name="results">
</ul>

Dengan petunjuk pemrosesan akhir di bagian akhir, jika ada placeholder <template for="results"> lainnya yang ditambahkan ke dokumen nanti.

Mengapa menggunakan petunjuk pemrosesan, bukan elemen HTML standar?

Ini adalah pertanyaan umum bagi mereka yang pertama kali menggunakan API ini, dengan saran untuk menggunakan elemen <slot> atau bahkan <template> itu sendiri. Versi awal proposal ini menggunakan elemen HTML standar, tetapi petunjuk pemrosesan diubah saat desain diulang. Petunjuk pemrosesan memungkinkan patching terjadi tanpa memengaruhi DOM. Hal ini memungkinkan penggunaan di <head>—misalnya untuk update <title>—atau bahkan di dalam elemen lain seperti <table> (misalnya untuk menambahkan baris tambahan opsional).

Meskipun sintaksisnya tidak dikenal oleh banyak developer web, petunjuk pemrosesan menawarkan fleksibilitas yang jauh lebih besar dengan lebih sedikit kemungkinan masalah kompatibilitas mundur. Atribut ini sudah digunakan dalam XML, dan kini menjadi bagian dari standar HTML berkat proposal ini.

Demo

Dalam video ini, aplikasi album foto dasar diimplementasikan dengan HTML streaming:

Demo album foto yang diimplementasikan dengan streaming di luar urutan (sumber)

Status dan foto akan di-streaming ke dalam HTML setelah tata letak awal.

Kasus penggunaan

Ada banyak kasus penggunaan untuk HTML patching di luar urutan ini jika dipadukan dengan HTML streaming:

  • Arsitektur pulau. Pola umum yang dipopulerkan oleh framework seperti Astro adalah arsitektur pulau, tempat komponen di-hydrate secara independen di atas HTML statis. <template for> API memungkinkan konten statis ditangani dengan cara yang serupa langsung di HTML. Framework JavaScript juga dapat menggunakan ini untuk pulau yang lebih interaktif atau untuk menangani komponen.
  • Kirimkan konten saat sudah siap. Berkat arsitektur pulau ini, konten dapat di-streaming saat sudah siap, bukan ditahan untuk konten yang memerlukan pemrosesan ekstra—misalnya, pencarian database. Meskipun banyak platform mengizinkan streaming HTML, sifat HTML yang berurutan berarti konten sering kali tertahan, atau dengan menggunakan manipulasi DOM JavaScript yang kompleks. Sekarang Anda dapat mengirimkan konten statis sambil menunggu, lalu memasukkan konten dinamis yang lebih mahal di akhir streaming HTML.
  • HTML dapat dikirimkan dalam urutan yang optimal untuk performa pemuatan halaman. Untuk langkah lebih jauh, Anda dapat mengubah urutan meskipun sudah siap. Misalnya, menu mega adalah fitur navigasi umum yang berisi banyak HTML yang tidak akan dilihat pengguna hingga halaman menjadi interaktif. Potongan besar HTML ini dapat dikirimkan nanti dalam dokumen HTML untuk memprioritaskan HTML yang lebih penting yang diperlukan untuk pemuatan halaman awal. Urutan tidak lagi menjadi penghalang dengan HTML.

Ini hanyalah beberapa kasus penggunaan, dan kami tidak sabar untuk melihat penggunaan API baru ini oleh para developer.

Batasan dan nuansa

API ini mencakup beberapa batasan dan kehalusan yang perlu diperhatikan:

  • <template for> hanya dapat memperbarui petunjuk pemrosesan dalam elemen induk yang sama karena alasan keamanan. Menambahkan <template for> langsung ke elemen <body> akan memberikan akses ke seluruh dokumen (termasuk <head>).
  • Petunjuk pemrosesan <?end> bersifat opsional dan jika tidak ada, konten di antara elemen <?start> dan akhir elemen yang memuatnya akan diganti.
  • Memindahkan petunjuk pemrosesan setelah <template for> mulai melakukan streaming juga dapat menimbulkan konsekuensi yang tidak terduga dengan konten baru yang terus di-streaming ke lokasi lama.
  • Perhatikan bahwa saat menyisipkan <template for> secara dinamis dengan metode seperti setHTML atau properti innerHTML, "induk" template saat diuraikan adalah fragmen dokumen perantara. Artinya, menyisipkan HTML dengan metode ini tidak dapat mengubah DOM yang ada, dan patching terjadi "di tempat" di dalam fragmen. Namun, saat melakukan streaming menggunakan metode seperti streamHTMLUnsafe (yang akan dibahas sebentar lagi), tidak ada fragmen perantara, sehingga template dapat menggantikan konten yang ada.

Status standardisasi

Atribut <template for> adalah bagian dari standar HTML, tetapi belum didukung di semua browser.

Potensi penambahan pada masa mendatang

Beberapa potensi penambahan fitur di masa mendatang yang sedang dipertimbangkan meliputi:

  • Mencakup sisi klien. Misalnya, <template for="footer" src="/partials/footer.html">, atau bahkan tanpa menambal <template src="/partials/footer.html">. Untuk mengetahui detail selengkapnya, lihat penjelasan. Fitur ini tersedia di balik tanda chrome://flags/#enable-experimental-web-platform-features.
  • Mencegah penimpaan konten yang tidak akan berubah. Hal ini dapat dicapai dengan nomor revisi atau pembuatan versi konten. Hal ini memungkinkan status dipertahankan di antara perubahan rute atau pembaruan lainnya, bukan mereset konten.
  • Membersihkan saat melakukan patching. Misalnya, <template for=icon safe><svg id="from-untrusted-source">...</svg></template>

Polyfill

Tim Chrome telah merilis template-for-polyfill yang tersedia di npm agar situs dapat langsung menggunakan fungsi baru ini bahkan sebelum fungsi ini tersedia di browser lain.

Ada beberapa batasan karena tidak dapat memperbarui parser HTML browser secara langsung, tetapi kasus penggunaan yang paling umum telah tercakup. Situs tetap harus diuji di browser lain.

Metode streaming dan penyisipan HTML yang diperbarui

Tidak semua konten dapat dikirimkan sebagai HTML. Bagian kedua dari pekerjaan yang telah dilakukan Chrome di area ini bertujuan untuk mempermudah memperbarui konten dengan JavaScript.

Sudah ada beberapa cara untuk menyuntikkan HTML secara dinamis ke dalam dokumen yang ada menggunakan JavaScript:

  • setHTML
  • setHTMLUnsafe
  • innerHTML dan outerHTML
  • createContextualFragment
  • insertAdjacentHTML

Namun, semuanya berfungsi dengan cara yang sedikit berbeda dengan nuansa dan perbedaan yang mungkin tidak selalu dipertimbangkan oleh developer:

  • Apakah konten baru menggantikan atau menambahkan?
  • Apakah mereka membersihkan HTML yang berpotensi berbahaya—misalnya, dengan melakukan escape pada tag <script>?
  • Jika tidak, haruskah <script> dijalankan?
  • Bagaimana cara kerjanya dengan Trusted Types?

Hanya sedikit developer yang dapat melihat API tersebut secara jujur dan menjawab pertanyaan tersebut dengan yakin untuk setiap API.

Batasan besarnya adalah bahwa elemen ini hanya dapat digunakan untuk kumpulan lengkap HTML yang diketahui sebelumnya, saat ada panggilan untuk mengizinkan HTML di-streaming. Praktisnya, ini berarti Anda harus mendownload seluruh konten sebelum menyisipkannya, padahal salah satu keunggulan HTML adalah kemampuan untuk langsung melakukan streaming konten. Hal ini dapat diatasi secara terbatas dengan membagi payload atau menggunakan metode yang tidak efisien dan tidak digunakan lagi seperti document.write, tetapi hal ini menimbulkan masalahnya sendiri.

Kumpulan API Statis dan Streaming baru

Browser Support

  • Chrome: behind a flag.
  • Edge: behind a flag.
  • Firefox: not supported.
  • Safari: not supported.

Chrome telah mengerjakan serangkaian API baru dan ekstensi untuk setHTML dan setHTMLUnsafe yang ada untuk mengatasi masalah ini, serta memperkenalkan fungsi streaming.

Fitur ini siap untuk pengujian developer mulai dari Chrome 148 menggunakan tanda chrome://flags/#enable-experimental-web-platform-features dan direncanakan untuk diluncurkan di Chrome 155.

Ada metode untuk menyetel atau mengganti bersama dengan metode untuk menyisipkan konten sebelum atau setelah HTML yang ada. Setiap metode memiliki padanan streaming:

Tindakan Statis Streaming
Menetapkan konten HTML elemen setHTML(html, options); streamHTML(options);
Ganti seluruh elemen dengan HTML ini replaceWithHTML(html, options); streamReplaceWithHTML(options);
Tambahkan HTML sebelum elemen beforeHTML(html, options); streamBeforeHTML(options);
Tambahkan HTML sebagai turunan pertama elemen prependHTML(html, options); streamPrependHTML(options);
Tambahkan HTML sebagai turunan terakhir elemen appendHTML(html, options); streamAppendHTML(options);
Tambahkan HTML setelah elemen afterHTML(html, options); streamAfterHTML(options);
Metode penyisipan dan streaming baru

Ada juga versi Unsafe yang akan segera dibahas. Meskipun mungkin terlihat banyak—terutama saat Anda menambahkan padanan Unsafe—konvensi penamaan yang konsisten membuat fungsi masing-masing metode lebih jelas dibandingkan dengan metode yang tidak terkait yang disebutkan sebelumnya.

Versi statis mengambil HTML baru sebagai argumen String DOM, beserta opsi opsional:

const newHTML = "<p>This is a new paragraph</p>";
const contentElement = document.querySelector('#content-to-update');

contentElement.setHTML(newHTML);

Versi streaming berfungsi dengan Streams API seperti dengan getWriter():

const contentElement = document.querySelector('#content-to-update');
const writer = contentElement.streamHTMLUnsafe().getWriter();

// Example stream of updating content
while (true) {
  await writer.write(`<p>${++i}</p>`);
  await new Promise((resolve) => setTimeout(resolve, 1000));
}

writer.close();

Atau, sebagai alternatif dari respons pengambilan menggunakan rantai perintah:

const contentElement = document.querySelector('#content-to-update');
const response = await fetch('/api/content.html');

response.body
  .pipeThrough(new TextDecoderStream())
  .pipeTo(contentElement.streamHTMLUnsafe());

Metode praktis textStream()

Browser Support

  • Chrome: 151.
  • Edge: 151.
  • Firefox: not supported.
  • Safari: not supported.

Metode praktis textStream juga ditambahkan, yang memungkinkan Anda melakukan streaming secara langsung tanpa memerlukan langkah TextDecoderStream() perantara:

const contentElement = document.querySelector('#content-to-update');
const response = await fetch('/api/content.html');

response.textStream().pipeTo(contentElement.streamHTMLUnsafe());

options

Argumen options memungkinkan Anda menentukan sanitizer kustom yang secara default adalah default yang berarti konfigurasi pembersih default. Cara penggunaannya adalah sebagai berikut:

const newHTML = '<p>This is a new paragraph</p>';
const contentElement = document.querySelector('#content-to-update');

// Only allows basic formatting
const basicFormattingSanitzer = new Sanitizer({ elements: ['em', 'i', 'b', 'strong'] });

contentElement.setHTML(newHTML, {sanitizer: basicFormattingSanitzer});

Metode "Tidak aman"

Ada juga versi "tidak aman" dari setiap API:

Tindakan Statis Streaming
Menetapkan konten HTML elemen setHTMLUnsafe(html,options); streamHTMLUnsafe(options);
Ganti seluruh elemen dengan HTML ini replaceWithHTMLUnsafe(html, options); streamReplaceWithHTMLUnsafe(options);
Tambahkan HTML sebelum elemen beforeHTMLUnsafe(html, options); streamBeforeHTMLUnsafe(options);
Tambahkan HTML sebagai turunan pertama elemen prependHTMLUnsafe(html, options); streamPrependHTMLUnsafe(options);
Tambahkan HTML sebagai turunan terakhir elemen appendHTMLUnsafe(html, options); streamAppendHTMLUnsafe(options);
Tambahkan HTML setelah elemen afterHTMLUnsafe(html, options); streamAfterHTMLUnsafe(options);
Metode penyisipan dan streaming "tidak aman"

Metode "tidak aman" ini menonaktifkan sanitizer secara default, dan Anda dapat menentukan sanitizer kustom jika mau. Metode ini juga memungkinkan skrip dijalankan dengan opsi runScripts opsional—yang secara default adalah false.

Seperti setHTML, setHTMLUnsafe adalah metode yang sudah ada, tetapi parameter opsi runScripts telah ditambahkan ke metode tersebut agar dapat digunakan dengan eksekusi skrip:

const newHTML = `<p>This is a new paragraph</p>
                 <script src=script.js></script>`;
const contentElement = document.querySelector('#content-to-update');

contentElement.setHTMLUnsafe(newHTML, {runScripts: true});

Kata "tidak aman" dalam metode ini adalah untuk mengingatkan developer tentang potensi risiko dan cara mereka dapat membersihkan atau membatasi skrip, bukan untuk mengatakan bahwa metode ini tidak boleh digunakan.

Seberapa "tidak aman" hal ini bergantung pada seberapa tepercaya inputnya. Semua metode statis Unsafe berfungsi dengan DOM String atau TrustedHTML sebagai argumen html dan juga memungkinkan penggunaan sanitizer. Meskipun dengan runScript seluruh maksudnya adalah untuk mengizinkan skrip, oleh karena itu, secara default tidak ada sanitizer yang digunakan.

Kasus penggunaan

API baru ini memudahkan developer menambahkan HTML ke halaman yang ada, dengan menambahkan API baru dengan nama dan opsi yang konsisten. Streaming API memberikan manfaat performa karena tidak perlu menunggu hingga semua konten baru tersedia di platform.

Kasus penggunaan mencakup:

  • Streaming dinamis untuk update konten besar di Aplikasi Web Satu Halaman. Seperti yang disebutkan sebelumnya, kelemahan besar arsitektur SPA saat ini adalah tidak dapat memanfaatkan sifat streaming dari pemuatan HTML awal—hingga saat ini.
  • Menyisipkan konten umum seperti footer HTML. Dengan menggunakan JavaScript API, Anda dapat menarik partial dan menyisipkannya ke dalam halaman, sehingga mendapatkan manfaat dari penyimpanan dalam cache, daripada mengulanginya di setiap halaman yang dikirim. Namun, mengingat dependensinya pada JavaScript untuk dijalankan, ini hanya boleh digunakan untuk konten yang tidak akan terlihat pada pemuatan awal.

Sekali lagi, itu hanyalah beberapa contoh dan kami ingin melihat apa yang akan Anda buat.

Batasan dan nuansa

API baru ini juga mencakup beberapa batasan dan nuansa yang perlu diperhatikan:

  • Integrasi streaming dengan Trusted Types API memerlukan penggunaan metode createParserOptions baru yang memungkinkan penyuntikan pembersih ke operasi setelan HTML apa pun. Lihat penjelasan untuk mengetahui detail selengkapnya tentang integrasi trusted types
  • Mirip dengan <template for>, memindahkan elemen yang sedang di-streaming ke dalam, dapat menimbulkan konsekuensi yang tidak terduga atau error streaming.
  • streamHTMLUnsafe berfungsi lebih seperti parser utama dalam banyak hal, termasuk memproses petunjuk <template for> saat ditambahkan ke dokumen utama dan menunda skrip defer hingga akhir streaming.

Status standardisasi

Metode penyisipan dan streaming yang lebih baru sedang dalam proses ditambahkan ke standar HTML, tetapi belum didukung di semua browser.

Polyfill

Tim Chrome telah merilis html-setters-polyfill yang tersedia di npm agar situs dapat langsung menggunakan fungsi baru ini bahkan sebelum fungsi ini tersedia di browser lain.

Perhatikan bahwa polyfill ini tidak melakukan streaming, melainkan melakukan buffering dan menerapkan saat selesai. Ini lebih merupakan polyfill untuk bentuk API daripada untuk fungsi.

Selain itu, penetapan konten aman bergantung pada setHTML dan Sanitizer API yang tidak didukung di Safari.

Gunakan keduanya bersama-sama

Meskipun ini adalah dua API terpisah, manfaatnya akan jauh lebih terasa jika keduanya digabungkan. Dengan mengalirkan elemen <template for> baru ke dalam HTML, Anda dapat memperbarui berbagai bagian konten secara dinamis tanpa harus menargetkan setiap bagian secara langsung dengan referensi JavaScript terpisah ke DOM.

Pemuatan halaman gaya SPA dasar dapat diimplementasikan dengan memuat halaman kerangka dengan petunjuk pemrosesan, lalu melakukan streaming setiap template halaman baru ke bagian bawah HTML untuk dimasukkan ke dalam petunjuk pemrosesan tersebut.

Tidak diragukan lagi ada lebih banyak potensi dan kasus penggunaan untuk kedua API ini, jadi jangan biarkan imajinasi kami (yang terbatas) menghalangi Anda. Dengan mempermudah pengelolaan update parsial, Anda dapat mengurangi beberapa kode boilerplate, mempermudah update, dan membuka potensi baru untuk web.

Ada beberapa API lagi yang sedang dikerjakan Chrome dalam project Pembaruan Parsial Deklaratif, tetapi kami senang dapat menghadirkan dua API pertama ini kepada Anda. Kami akan terus mengabari Anda dan memberi tahu Anda saat lebih banyak konten tersedia di ruang ini.