עדכונים חלקיים דקלרטיביים

תאריך פרסום: 19 במאי 2026

האינטרנט כבר מזמן לא מדיום סטטי שמבוסס על מסמכים, כמו שהוא היה בהתחלה. כולם משתמשים באפליקציות אינטרנט מודרניות ועשירות מסיבות רבות, החל מתקשורת, רכישה וצריכת תוכן עשיר, ועד לניהול החיים המורכבים שלנו.

למרות כל השיפורים שנעשו ב-HTML, הוא עדיין מועבר לפי הסדר מלמעלה למטה, בלי להתחשב במועד שבו התוכן מוכן או במועד שבו המשתמש צורך אותו. שירות CSS מאפשר לשנות את סדר התוכן, אבל לעיתים קרובות יש לכך השפעות משמעותיות על הנגישות. ‫JavaScript מאפשרת לכם לשנות את ה-DOM באמצעות ממשקי API שונים כדי להשתחרר מהמגבלה הזו במידה מסוימת, אבל לעיתים קרובות נדרש תחביר מפורט או בנייה של עצי DOM כדי להתחבר ל-HTML.

הביצועים חשובים מאוד באינטרנט, בהתחשב באופי של הלקוח-שרת של המדיום, אבל לעיתים קרובות נעשות בחירות לא אופטימליות כדי לעקוף את האופי הזה של HTML, מה שמאט את הביצועים. הפעולות האלה כוללות המתנה עד שהדף כולו יהיה מוכן או שימוש במסגרת כבדה כדי להציג רכיבים באופן אסינכרוני. הפופולריות של מסגרות JavaScript מראה שמפתחי אתרים מעדיפים מודל מבוסס-רכיבים ולא את המודל המנטלי הנוקשה של מסמך שמקורו באינטרנט.

צוות Chrome בחן את הבעיה הזו ופיתח תוספות חדשות לפלטפורמת האינטרנט בשם Declarative Partial Updates (עדכונים חלקיים הצהרתיים).

שני סטים חדשים של ממשקי API מאפשרים להציג HTML בצורה פחות לינארית, בין אם מחוץ לסדר במסמך ה-HTML עצמו או באמצעות דרכים קלות יותר להוסיף HTML באופן דינמי למסמכים קיימים באמצעות ממשקי JavaScript API חדשים. התכונות האלה מוכנות לבדיקות של מפתחים החל מ-Chrome 148 באמצעות התכונה הניסיונית chrome://flags/#enable-experimental-web-platform-features. יש גם Polyfills שמאפשרים לכם להשתמש בממשקי ה-API החדשים האלה באופן מיידי, גם בדפדפנים שעדיין לא תומכים בהם.

התוספות האלה לפלטפורמת האינטרנט עוברות תהליך סטנדרטיזציה עם משוב חיובי מספקי דפדפנים אחרים ומגורמים שעוסקים בסטנדרטיזציה. אנחנו מעדכנים את התקנים הרלוונטיים כך שיכללו את ממשקי ה-API החדשים האלה.

סטרימינג לא לפי הסדר

השינוי הראשון הוא ממשקי API חדשים להזרמת נתונים לא לפי הסדר באמצעות רכיב ה-HTML ‏<template> ומשתני placeholder של הוראות עיבוד. לדוגמה:

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

...

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

הוראות עיבוד קיימות ב-XML כבר הרבה זמן, אבל הן נחשבות לתגובות ב-HTML והמערכת מתעלמת מהן. ה-API החדש משנה את זה ומביא הוראות עיבוד ל-HTML. כשהדפדפן רואה את הוראות העיבוד <?marker name="placeholder">, הוא לא עושה שום דבר באופן מיידי – בדיוק כמו קודם – אבל אפשר להתייחס אליהן בהמשך.

האלמנט <template> מחפש את הוראות העיבוד המתאימות באמצעות המאפיין name ומחליף את התוכן. במקרה הזה, אחרי הניתוח, ה-DOM ייראה כך:

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

בנוסף למאפיין <?marker> להחלפות, יש גם סמני טווח <?start> ו-<?end> שמאפשרים להציג תוכן זמני של placeholder לפני שהתבנית עוברת עיבוד:

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

...

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

במקרה כזה, Loading… מוצג עד שרואים את <template>, ואז הוא מוחלף בתוכן החדש.

אפשר גם לכלול הוראות עיבוד בתבניות כדי לאפשר כמה עדכונים:

<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>
...

אחרי הניתוח, קוד ה-HTML שמתקבל הוא:

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

עם הוראת העיבוד הסופית בסוף, למקרה שיוסיפו עוד <template for="results"> למסמך בהמשך.

הדגמה (דמו)

בסרטון הזה, מיושמת אפליקציה בסיסית של אלבום תמונות באמצעות סטרימינג של HTML:

הדגמה של אלבום תמונות שהוטמעה באמצעות סטרימינג לא מסודר (מקור)

גם הסטטוס וגם התמונות מוזרמים ל-HTML אחרי הפריסה הראשונית.

תרחישים לדוגמה

יש הרבה תרחישי שימוש בתיקון HTML לא לפי הסדר בשילוב עם סטרימינג של HTML:

  • ארכיטקטורת איים. דפוס נפוץ שהפך לפופולרי בזכות מסגרות כמו Astro הוא ארכיטקטורת האיים, שבה הרכיבים עוברים הידרציה באופן עצמאי על גבי HTML סטטי. ‫<template for> API מאפשר לטפל בתוכן סטטי באופן דומה ישירות ב-HTML. אפשר להשתמש בזה גם ב-JavaScript frameworks כדי ליצור איים אינטראקטיביים יותר או כדי לטפל ברכיבים.
  • העברת תוכן כשהוא מוכן. בזכות ארכיטקטורת האיים הזו, אפשר להזרים תוכן כשהוא מוכן במקום לעכב אותו בגלל תוכן שדורש עיבוד נוסף, למשל חיפוש במסד נתונים. הרבה פלטפורמות מאפשרות סטרימינג של HTML, אבל בגלל האופי של HTML, התוכן לרוב מושהה או שמתבצעות מניפולציות מורכבות ב-DOM של JavaScript. עכשיו אפשר להציג את התוכן הסטטי בזמן ההמתנה, ואז להוסיף את התוכן היקר יותר בסוף של זרם ה-HTML.
  • אפשר להציג HTML בסדר האופטימלי לביצועי טעינת הדף. אפשר גם לשנות את הסדר אחרי שהסרטון מוכן. לדוגמה, תפריטי מגה הם תכונת ניווט נפוצה שמכילה הרבה קוד HTML שהמשתמש לא יראה עד שהדף יהפוך לאינטראקטיבי. אפשר להעביר את החלק הגדול הזה של ה-HTML לחלק מאוחר יותר במסמך ה-HTML, כדי לתת עדיפות ל-HTML חשוב יותר שנדרש לטעינת דף הראשונית. הזמנה לא מהווה יותר מחסום עם HTML.

אלה רק כמה תרחישים לדוגמה, ואנחנו נרגשים לראות איך מפתחים משתמשים ב-API החדש הזה.

הגבלות וניואנסים

יש כמה הגבלות וניואנסים שחשוב להכיר לגבי ה-API:

  • מטעמי אבטחה, <template for> יכול לעדכן הוראות עיבוד רק באותו רכיב אב. הוספה של <template for> ישירות לרכיב <body> נותנת לו גישה לכל המסמך (כולל <head>).
  • הוראת העיבוד <?end> היא אופציונלית, ואם היא לא מופיעה, התוכן שבין הרכיב <?start> לסוף הרכיב המכיל יוחלף.
  • העברת הוראות עיבוד אחרי שסטרימינג של <template for> התחיל יכולה גם לגרום לתוצאות לא צפויות, כשהתוכן החדש ממשיך להיות בסטרימינג למיקום הישן.
  • שימו לב: כשמכניסים <template for> באופן דינמי באמצעות שיטה כמו setHTML או innerHTML, ה "הורה" של התבנית בזמן הניתוח הוא קטע מסמך ביניים. המשמעות היא שאי אפשר להשתמש בשיטות האלה כדי להוסיף HTML ולשנות DOM קיים, והתיקון מתבצע 'במקום' בתוך הפרגמנט. עם זאת, כשמבצעים סטרימינג באמצעות שיטות כמו streamHTMLUnsafe (שנסביר עליהן בהמשך!), אין פרגמנט ביניים ולכן התבניות יכולות להחליף תוכן קיים.

תוספות פוטנציאליות בעתיד

הנה כמה תוספות פוטנציאליות שאנחנו שוקלים להוסיף בעתיד:

  • הוספות בצד הלקוח. לדוגמה, <template for="footer" patchsrc="/partials/footer.html">.
  • קיבוץ. בצד הלקוח, אפשר להרחיב את האפשרות של הכללת קטעים כדי לטפל באוסף של כמה עדכונים שמתבצעים בו-זמנית.
  • מניעת החלפה של תוכן שלא ישתנה. אפשר לעשות את זה באמצעות מספר תיקון תוכן או ניהול גרסאות. כך אפשר לשמור את המצב בין שינויים במסלול או עדכונים אחרים, במקום לאפס את התוכן.
  • ניקוי בזמן תיקון. לדוגמה, <template for=icon safe><svg id="from-untrusted-source">...</svg></template>.

פוליפיל

צוות Chrome פרסם template-for-polyfill שזמין ב-npm כדי לאפשר לאתרים להשתמש בפונקציונליות החדשה הזו באופן מיידי, עוד לפני שהיא תהיה זמינה בדפדפנים אחרים.

יש כמה מגבלות כי אי אפשר לעדכן ישירות את מנתחי ה-HTML של הדפדפן, אבל התרחישים הנפוצים ביותר מכוסים. עדיין צריך לבדוק את האתרים בדפדפנים אחרים.

שיטות חדשות להוספת HTML ולהעברה בסטרימינג

לא ניתן להעביר את כל התוכן בפורמט HTML. חלק נוסף בעבודה ש-Chrome מבצע בתחום הזה הוא להקל על עדכון התוכן באמצעות JavaScript.

כבר יש כמה דרכים להוסיף באופן דינמי HTML למסמך קיים באמצעות JavaScript:

  • setHTML
  • setHTMLUnsafe
  • innerHTML ו-outerHTML setters
  • createContextualFragment
  • insertAdjacentHTML

עם זאת, כל אחת מהן פועלת בצורה שונה, עם ניואנסים והבדלים שמפתחים לא תמיד לוקחים בחשבון:

  • האם התוכן החדש מחליף את התוכן הקיים או מתווסף אליו?
  • האם הם מבצעים סניטציה של קוד HTML שעלול להיות מסוכן על ידי ביטול התגים <script>, למשל?
  • אם לא, האם צריך להריץ את <script>?
  • איך הם עובדים עם TrustedTypes?

מעט מאוד מפתחים יכולים להסתכל על ממשקי ה-API האלה ולענות על השאלות האלה לגבי כל אחד מהם.

מגבלה משמעותית היא שאפשר להשתמש בהם רק עבור קבוצה מלאה של HTML שידועה מראש, כשהיו קריאות לאפשר סטרימינג של HTML. בפועל, זה אומר שצריך להוריד את כל התוכן לפני שמוסיפים אותו, כשנקודת החוזק של HTML היא היכולת להזרים תוכן באופן מיידי. אפשר לעקוף את הבעיה הזו במידה מוגבלת על ידי פיצול של מטען ייעודי (payload) או שימוש בשיטות לא רשמיות שהוצאו משימוש כמו document.write, אבל הן יוצרות בעיות משלהן.

קבוצה חדשה של ממשקי API סטטיים וממשקי API של סטרימינג

צוות Chrome הציע חבילה של ממשקי API חדשים ותוספים ל-setHTML ול-setHTMLUnsafe הקיימים, כדי לפתור את הבעיה הזו, וגם כדי להוסיף פונקציונליות של סטרימינג:

יש שיטות להגדיר או להחליף, וגם שיטות להוספת תוכן לפני או אחרי קוד HTML קיים. לכל שיטה יש מקבילה בזרם:

פעולה סטטי סטרימינג
הגדרת תוכן ה-HTML של האלמנט setHTML(html, options); streamHTML(options);
החלפת הרכיב כולו ב-HTML הזה replaceWithHTML(html, options); streamReplaceWithHTML(options);
מוסיפים את ה-HTML לפני הרכיב beforeHTML(html, options); streamBeforeHTML(options);
מוסיפים את ה-HTML כרכיב המשני הראשון של הרכיב prependHTML(html, options); streamPrependHTML(options);
מוסיפים את ה-HTML כרכיב המשני האחרון של הרכיב appendHTML(html, options); streamAppendHTML(options);
מוסיפים את ה-HTML אחרי הרכיב afterHTML(html, options); streamAfterHTML(options);
השיטות החדשות להוספה ולסטרימינג

יש גם גרסאות Unsafe שנסביר עליהן בהמשך. יכול להיות שייראה שיש הרבה כאלה (במיוחד כשמוסיפים את המקבילות של Unsafe), אבל מוסכמת השמות העקבית מאפשרת להבין בקלות מה כל אחת מהן עושה, בהשוואה לשיטות הלא קשורות שהוזכרו קודם.

הגרסאות הסטטיות מקבלות HTML חדש כארגומנט DOM String, יחד עם אפשרויות אופציונליות:

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

contentElement.setHTML(newHTML);

גרסאות הסטרימינג פועלות עם