Web ComponentとReact

以下の記事は、自分の知識整理のための記事です。間違っていたらご指摘ください。

Web Componentとは

ウェブの再利用可能なウィジェットコンポーネントを作成するための標準技術の集合。

これにより、HTML, CSS, JSをカプセル化した上で再利用することが可能になる。

1. カスタム要素

カスタム要素と、その動作に関するJavaScript API。以下のようなコードをJavaScriptに書くことで、HTMLからpopup-infoタグを使用できるようになる。

customElements.define("popup-info", PopupInfo);

class PopupInfo extends HTMLElement {
  constructor() {
    // コンストラクターでは常に super を最初に呼び出してください
    super();

    // ここに要素の機能を記述します
  }
}
<popup-info></popup-info>

2. Shadow DOM

Shadow DOMツリーを要素に紐づけて関連する機能を制御するための、一連のJava Script APIカプセル化している。つまり、シャドウDOM外のJavaScript, CSSが、シャドウDOM内の要素に影響を与えることは無い。

1のカスタム要素単体だと、カプセル化されていないので、Shadow DOMと組み合わせることで、外部と隔離された形でタグが使用できるようになる。Shadow DOMは、HTML templateと違って、attachされたらすぐにレンダリングされる。

3. HTML template

template要素と、slot要素によって、レンダリングされたページに表示されないマークアップのtemplateを書くことができる。JavaScriptを介してインスタンス化される。

HTML templateは、templateの内容をカスタム要素としてカプセル化した上でShadow DOMに追加することで真価を発揮する。

customElements.define(
  "my-paragraph",
  class extends HTMLElement {
    constructor() {
      super();
      let template = document.getElementById("my-paragraph");
      let templateContent = template.content;

      const shadowRoot = this.attachShadow({ mode: "open" });
      shadowRoot.appendChild(templateContent.cloneNode(true));
    }
  },
);
<template id="my-paragraph">
  <style>
    p {
      color: white;
      background-color: #666;
      padding: 5px;
    }
  </style>
  <p>My paragraph</p>
</template>

こうすると、以下のような形で、my-paragraphタグを利用できる。my-paragraphは、HTML templateなので、ページ読み込みと同時にレンダリングされるわけではないので、パフォーマンス向上に貢献できる。

<my-paragraph></my-paragraph>

Web ComponentとReact

メルカリのWeb Componentsに関する記事によると、メルカリ Core teamはWeb ComoponentsからReactに移行中であるとのこと(2022年末)。 そもそもWeb Componentsを導入した背景としては、Web Componentsを使えば、React, Vueなど、様々なフレームワークで利用できるというメリットがあったためらしい。

しかし、導入後、以下のような課題が出てきた。

  • Web Componentsを使ってくれる・contributeしてくれる人が少ない
  • Web Componentsでサーバーサイドレンダリング(SSR)を実行するのは難しい
  • Web Componentsのその他の技術的な制約

そこで、Web ComponentsからReactへの移行を実施しているらしい。

所感

Web Components自体は面白い技術だが、導入した場合、メルカリの記事にあるような技術課題に直面しそう。つまり、Web Componentsは「世間的な認知がそこまで高くない・SSRなどの技術的制約が存在する」。Web Componentsを導入するのであれば、組織全体でWeb Components体制をサポートする必要がある。ただ、そこまでの企業努力をしてまで導入するメリットは、一般的な会社には無さそう。エンジニア採用しやすくて、使いやすい技術スタックという観点で考えると、Reactに軍配が上がる。

参考

https://developer.mozilla.org/ja/docs/Web/API/Web_components

https://engineering.mercari.com/en/blog/entry/20221207-web-design-system-migrating-web-components-to-react/

https://engineering.mercari.com/blog/entry/20210823-8128e0d987/