Özel öğeleri önceden oluşturma

Web özellikleri: Bildirimsel gölge DOM

Önceden oluşturma, özel bir öğenin işaretlemesini (gölge ağacı dahil) sunucudan göndermek anlamına gelir. Böylece bileşen, herhangi bir JavaScript çalıştırılmadan önce stillendirilir ve yapılandırılır. Bunun için ana platform temel öğesi Bildirim temelli gölge DOM'dur (DSD): Ayrıştırıcı, gölge kökü yalnızca HTML'den ekler ve öğe daha sonra kayıtlıysa sınıfı tarafından yükseltilir ("hidratlanır"). Sunucu tarafında oluşturma, akış ve stil uygulanmamış içeriğin yanıp sönmesini (FOUC) önlemek için bu kalıbı kullanın.

Bildirim temelli gölge kökü oluşturma

Ana makinenin ilk alt öğesi olarak shadowrootmode özelliğine sahip bir <template> yerleştirin. Ayrıştırıcı, içeriğini gölge kök olarak ekler ve şablonu kaldırır. Komut dosyası gerekmez.

<my-card>
  <template shadowrootmode="open">
    <style>
      .card { border: 1px solid; border-radius: 8px; padding: 1rem; }
    </style>
    <div class="card">
      <slot name="header"></slot>
      <div class="body"><slot></slot></div>
    </div>
  </template>

  <!-- Light DOM children are projected into the slots above. -->
  <h2 slot="header">Server-rendered title</h2>
  <p>Visible and styled before JS loads.</p>
</my-card>

Sıvı alımı zamanlaması

Eşleşen sınıf kaydedildiğinde tarayıcı, ana makineyi yükseltir. Gölge kök zaten mevcut olduğundan, oluşturucu körü körüne ikinci bir gölge kök oluşturmamalıdır:

class MyCard extends HTMLElement {
  constructor() {
    super();
    // Reuse the server-rendered shadow root if present; only create one if absent.
    if (!this.shadowRoot) {
      this.attachShadow({ mode: 'open' });
      this.shadowRoot.append(template.content.cloneNode(true));
    }
    // Hydrate in place: attach listeners once against existing markup (not unguarded
    // in connectedCallback, which re-runs if the element moves in the DOM), and do
    // NOT re-render; that would discard the server's DOM and flash.
    this.shadowRoot.getElementById('toggle')
      ?.addEventListener('click', () => this.toggleAttribute('open'));
  }
}

Neredeyse tüm durumlarda shadowrootmode="open" (closed değil) değerini ayarlayın. Böylece komut dosyaları ve araçlar, doldurmak için this.shadowRoot adresine ulaşabilir. Mevcut bir gölge kökü sunucuda veya testlerde tekrar HTML'ye dönüştürmek için getHTML({ serializableShadowRoots: true }) kullanın ve kökü serializable: true ile ekleyin.

FOUC'yi önleme

DSD, yalnızca stiller bildirim temelli şablonun içinde gönderilirse ilk boyamada doğru şekilde oluşturulur. Bunu korumak için:

  • Bileşen CSS'sini ayrı bir komut dosyası yüklü sayfaya değil, <template shadowrootmode> (<style> etiketi veya <link>) içine yerleştirin.
  • my-card:not(:defined) { … } ile yalnızca JS'yi beklemesi gereken stiller için eşleyin. Bunlar genellikle SSR geçişini kaçıran istemci tarafından oluşturulan örneklerdeki karartma gibi sayfa düzeyindeki koruma kurallarıdır. Gölge kök henüz orada mevcut olmadığından ve :host seçiciler dışarıdan uygulanmadığından bunlar light-DOM (sayfa) stil sayfasında bulunur. DSD şablonundaki yapısal stiller için bu tür bir korumaya gerek yoktur.
  • Hidrasyon sırasında gölge ağacını yeniden oluşturmayın. Sunucu işaretlemesini yetkili olarak kabul edin ve davranışı buna ekleyin.

Yedek stratejiler

shadowrootmode öğesini ayrıştırmayan motorlarda şablon etkisizdir ve içeriği gölge kök olarak eklenmez. Bunu (Object.hasOwn(HTMLTemplateElement.prototype, 'shadowRootMode')) tespit edin ve yoksa yükseltme sırasında aynı işaretlemeden gölge kökü zorunlu olarak ekleyin. Böylece bileşen yine de oluşturulur.