Pairs ヘルプサイトのカスタマイズに Web Components を導入した話

この記事は eureka Advent Calendar 2018 19 日目の記事です。


こんにちは、 Pairs 日本版の Web フロントエンドを開発しているエンジニアのOTこと@s5otです。

Pairs にはヘルプサイトがあり、ユーザー様が安心して Pairs を使っていただくための助けとなるコンテンツとお問い合わせの窓口を提供させていただいています。 また、チャットでカスタマーサポートのオペレーターによるサポートを受けることもできます。

ユーザー様の多様なニーズにより適切に応えるため、このチャットサポートの機能をアップデートすることになり、チャットを開始するUIパーツのカスタマイズ案件が発生しました。

このカスタマイズの技術的選択として、Web Components を採用することにしました。

Web Components 採用の背景

  • 開発する UI パーツはヘルプサイトのコアコンテンツ自体ではなくアドオンなものであるため、今後の運用を踏まえて独立性を確保したい。
  • ヘルプサイトには React や Vue のような UI を構築するためのライブラリ・フレームワークが入っていない。新たに追加することは避けたい。
  • Web Components はモダンブラウザでほぼサポートされており、一般に導入事例もある。

Web Components とは

Web Components の詳細な解説についてはすでに多くのコンテンツが提供されているため、ここでは省略して簡単なポイントのみの整理とします。 個人的にはGoogle の Web Fundamentals の記事が分かりやすかったです。

Web Components では

  • 再利用可能でカプセル化された UI コンポーネントを作成できます。
  • Web 標準に則っているため、ブラウザネイティブで動作し、既存のライブラリ・フレームワークと併用が可能です。

Web Components は下記の 4 つの仕様から構成されています。 この中でもコアなのは Custom Elements と Shadow DOM です。 特に Shadow DOM は比較的仕様が大きく、噛みごたえがあります。

Custom Elements

カスタム要素を定義し、ブラウザ上で新しいタグを使えるようになります。 button や img のような既存要素を拡張することもできます。

Shadow DOM

Shadow DOM は document から隔離された DOM です。 Shadow DOM は document.querySelector()などでは取得できません。 Shadow DOM 内で定義された CSS のスコープはその Shadow DOM 内に閉じます。 カスタム要素内の DOM は Shadow DOM で構成するため、グローバルCSSの影響を受けずに済みます。(必須ではない)

ES Modules

ブラウザ上で JS のモジュールシステムを実現します。JSで外部モジュールをimportで取り込むことができます。

HTML Template

JS から扱えるテンプレートを HTML で作成できます。

サンプル実装

WebComponents のカスタム要素は JS の class 構文で定義できます。 カスタム要素のライフサイクルメソッドが提供されるので、任意の処理をフックさせることができます。

カスタム要素の名前にはハイフンが必ず含まれなければなりません。 drawerのような単語1つの名前もNGです。 Polymer Projectでは、コアコンポーネントはironという接頭辞をつけ、マテリアルデザインのUIコンポーネントはpaperという接頭辞をつけるルールらしいです。 
定義したカスタム要素は HTML で利用できるようになります。

Web Components に対する所感

UI をコンポーネントベースで開発することによる再利用性・安全性・生産性は Web ブラウザのプラットフォームでも React や Vue などによって示されてきました。 
しかしながら、Web ブラウザのプラットフォームでは PWA と呼ばれるネイティブアプリのような高い機能性を持つ Web アプリだけが必要とされるわけではありません。 static なサイト、ランディングページ、ネイティブアプリの WebView 上のページ、デジタルサイネージなど多様なケースが存在します。

そのようなケースにおいて、 Web Components はUIコンポーネントベースの恩恵だけでなく、ブラウザネイティブで動作するためライブラリ・フレームワークを追加する必要がなく、パフォーマンスバジェットの面でも有効性をもたらしてくれるのではと考えています。

以前に Netflix がホームページを React から Vanilla JS への移行してパフォーマンスを改善した記事からもブラウザネイティブで動作する強みを感じました。(この記事はWeb Componentsの事例ではないですが)

また、パフォーマンスといえば AMP もWeb Components の実践例ですね。

さまざまな環境下でより多くのユーザーに対して良い体験・価値を届ける手段の 1 つとして、 Web Components を今後活用していければと考えています。