Web Componentsの主要な技術要素であるCustom ElementsとShadow DOMを中心に、概要や使い方についてお話しました。

※ オフラインのため、音声ファイルを再生できません。ネットワーク状況をご確認の上、再度アクセスしてください。

橋本
みなさんこんにちは!ミツエーテックラジオは株式会社ミツエーリンクスのスタッフがWebデザイン、 WebフロントエンドなどのWeb技術に関するニュースやツールなどをシェアするためのポッドキャストです。
司会は橋本が務めさせていただきます。ゲストは加藤さんです!本日はよろしくお願いします!
加藤
よろしくお願いします!
橋本
今回は社内の開発者から「Web Componentsってなに?」「ReactVue.jsのようなフレームワークとどう違うの?」「実務で使う場合のメリットとデメリットが知りたい!」というお便りをいただいたので、Web Componentsについて話していこうと思います。
加藤
はい!お便りありがとうございます!
橋本
えーWeb Componentsについてテックラジオで取り上げるのは初めてなので、まずはWeb Componentsとは何か、といったところからお話していければと思います!
加藤
はい。Web Componentsを一言で言い表すと、再利用可能なカプセル化された独自のHTMLタグを作成できる技術です。単体で成立するような部品という意味でコンポーネントと呼びます。
橋本
この「コンポーネント」という言葉はVue.jsやReactなどのJSフレームワークに触ったことがある人にはわりと馴染みのあるものですよね。
加藤
そうですね。より具体的な話をすると、Web Componentsは5つのWeb標準技術を含む、とWICGでは定義されています。そのうち「Custom Elements」、「Shadow DOM」と「HTML Templates」の3つは特に重要な役割を担っているので、Web Componentsの主要な部分としていろいろな記事で取り上げられることが多いですね。
橋本
Web Components自体が1つのAPIというわけではなく、さまざまな技術の組み合わせを指すってことですけど、考え方はすこしPWAと似ていますね。今はモダンブラウザすべてでWeb Componentsの主要な技術がサポートされていますが、Web Components自体はわりと昔に誕生したものですよね。その背景はどういうところにあったんでしょうか。
加藤
そうですね…まぁWebサイトを構成するユーザーインターフェースを作成していくときは、まぁ当然HTML、CSS、JSを使って作成していくわけなんですけど、その作ったパーツをほかのプロジェクトでも再利用したいってなった時って、そのままHTMLとCSSとJSをコピーしても、既存のコードと競合してしまうので、競合解決するために少し調整したりする必要がありますよね。
橋本
あーたしかに。それって同じ姿、同じ振る舞いをするべきパーツが複数の場所で管理されている状態なので、保守や運用がしづらくなってしまいますね。
加藤
そうなんです。そういった課題を解決する技術としてWeb Componentsが提案されました。最初に少し話したようにWeb Componentsはカプセル化されているので、どんなプロジェクトでもそこまで気にせずに再利用ができますし、何よりタグ1つで機能を表現できるのでマークアップ自体も簡潔になります。
橋本
なるほど。そのタグ1つだけを使って複雑な機能を利用できるというのは開発者以外の人が使ってもミスなく実装できるというメリットもありそうですね。
ではWeb Componentsの実体についてもう少し詳しく教えていただけますか?
加藤
はい。各技術要素を1つ1つ詳しく見ていくととても15分には収まらないので、今回はWeb Componentsの表面的なところ、特にCustom ElementsとShadow DOMについて話していこうと思います!
橋本
はい、お願いします!
加藤
えーまず1つ目のCustom Elementsは、独自のHTML要素を自分で定義できるAPIです。これまでは、段落を表したいときはp要素、リンクを表したいときはa要素のようにWeb標準として定められたHTML要素を使ってきましたが、Custom Elementsをつかうと特定の目的を達成するためのHTML要素を自分で作ることができます。Custom Elementsの場合はHTML、CSSも含めてすべてJS内でまとめて管理できるので、たとえ100箇所で同じ要素を使っていても、修正するのはJS一か所だけで済む、というのが大きな利点ですね。
橋本
うーん確かに、静的なHTMLの場合は100箇所をすべて修正しなければならないですもんね…。その基本的な使い方としては、要素の名前や要素が持つプロパティ、イベントの設定をJSで定義して、HTMLにはJSで定義した名前をタグとして書いていくっていう感じですよね?
加藤
そうですね。Custom Elementsを有効にするためにdefineという、まぁ「定義する」という意味のメソッドがあるんですけど、そのメソッドに渡した名前がそのままHTMLのタグの名前になります。Custom Elementsにはいくつか種類があって、完全に一から作成するものと、既存のHTML要素を拡張するものの2つがあります。橋本くんはDOMのインターフェースってご存知ですか?
橋本
はい。あのーHTMLElementとか、ボタンだとHTMLButtonElementとかのDOMの型みたいなものですよね?
加藤
そうですね。まぁたとえばクリックしたときにアニメーションするボタンを要素として作りたい!というときは、まぁHTMLButtonElementを継承してクリックイベントを追加していったりすることができます。ちなみに、既存HTML要素の継承は現在Safariでは実装されていないので注意しましょう。
橋本
なるほど。要素の名前をタグとして定義して利用できるというのは、その作成した要素が持つ機能をそのままタグ名として反映できるので、より直感的なマークアップができそうですね。そのほかCustom Elementsを使う際の注意点などってありますか??
加藤
結構たくさんあるんですけど、まぁ要素の命名に関するルールがあったりするので、詳しくはHTML Standardに記載されている要件を参照いただくといいと思います!
橋本
はい!読んでおきます!
加藤
はい。続いて、ここからはShadow DOMについて話していきます。Custom Elementsがあればコンポーネントの基本自体は作れるんですけども、それだけだとWebサイトで読み込んでいるCSSやJSの影響を受けてしまいます。Shadow DOMはそれを解決するために、特定のHTML要素を通常のDOMツリーとは切り離した場所に、独立したDOM構造を作ることでカプセル化を実現します。
橋本
はい。これは分かりやすい例をあげるとするとvideo要素とかinput要素で内部的にShadow DOMが使われていることとかですね。HTMLファイルにはvideo要素しか記述しないんですけど、実際にブラウザで見てみると、再生ボタンやシークバーなど一通り動画視聴に必要なUIをブラウザが用意してくれます。
加藤
そうですね。Shadow DOMによってカプセル化することで、他のCSSやJSの影響を受けず、逆にShadow DOM内のコードもShadow DOMの外には影響を与えない状態を作ることができます。正直動画のコントローラー部分を毎回自作するのはかなりコストがかかるので、この辺りを特に意識せずブラウザ側でよしなにやってくれるっていうのはとてもありがたいですね。
橋本
なるほど。その特に意識せず、ってところが大事ですね。カプセル化されていることで開発者は安心して他のところに集中できますし。
加藤
うん、そうですね。ただ、Shadow DOMは外からの影響を受けない、と何度か言っているんですけども、実は100%受けないというわけではありません。たとえば、font-sizeやcolorなど、子要素にも継承されるスタイルが親要素に対して指定されていると、そのスタイルはShadow DOMの中の要素にも継承されてしまうので、そういう意味では影響はありますね。
橋本
あーそうなんですね…。継承されるスタイルについては、必要に応じてShadow DOM内に定義しておいたほうがよさそうですね。
加藤
うん、そうですね。あとは、やっぱりShadow DOMの外からShadow DOMの中の見た目を操作したい、というケースもやっぱり発生すると思うので、そういう場合は、CSS カスタムプロパティを使うこともできます。
橋本
というのは、Shadow DOMの外で定義されたカスタムプロパティなら外部から影響を受けないShadow DOMの中でも参照できるってことですかね。
加藤
そうですね。なので、コンポーネントを作るときは、ユースケースを考慮しながらどの部分をカスタマイズできるようにするのかっていうところを決めておくといいと思います。
橋本
なるほど。あとShadow DOMに関する注意点は何かありますか?
加藤
これもいろいろあるんですけど、1つはFlash of unstyled contents、つまりページロード時に一瞬スタイルが当たっていないコンテンツが表示されてしまう点ですね。Shadow DOMの中でもlink要素や@importによって外部のCSSファイルを読み込むことができるんですけど、これらはブラウザの描画処理を中断しないので、読み込みが完了するまではスタイリングされていないコンテンツが表示されてしまいます。
橋本
あー、そうなんですね。
加藤
はい。なので、できるだけShadow DOM内にデフォルトのスタイルだけでも書いておくとか、コンポーネントに本当に必要なスタイルのみを読み込むことを徹底するのがいいと思います。
橋本
はい。Web Componentsの中心技術であるCustom ElementsとShadow DOMについて話してきました。個人的にこれまでの開発ではあまり使ってこなかった技術が中心で、かなり考え方を大きく変えないといけないなって感じました。ReactやVue.jsといったフレームワークにもコンポーネントという概念がありますが、そのあたりとの違いでいうと、やっぱり手軽さ、みたいなところなんですかね?
加藤
1つはそうですね。Webpackなどのバンドラーとあわせて外部のライブラリを使うときは、まずnpmのパッケージをインストールして、インストールしたパッケージをJSで読み込んだうえで、最終的なJSファイルを出力する、といったプロセスが結構スタンダードっぽくなってきているんですけど、Web Componentsの場合は、基本はscript要素でコンポーネントのJSファイルを読み込んで、HTMLにタグを書くだけで完結するんですよね。
橋本
たしかに、そのBootstrapのようにJSファイルを読み込んで、あとはクラスを付けておけば動くっていう手軽さはなくなりましたよね。まぁそのぶん他の問題が解決されているわけですけど。
加藤
うん、そうですね。これまでのライブラリは手軽だったんですけど、jQueryなどの他のライブラリに依存しているものが多かったりして、ここ数年の表示パフォーマンスを重要視するトレンドにはマッチしない感じがしますよね。
橋本
はい。その点、Web Componentsは基本Web標準技術だけで構成できるので、バランスがいいですよね。ただ、コンポーネント使うのは楽だけど、作るのは大変!ってイメージがあります…。
加藤
うん、そうですよね。でももし、自分で作る余裕がない!という場合にはすでにWeb に公開されているコンポーネントを使うっていう手もあります。たとえば、webcomponents.orgっていうサイトでは、npmで公開されているWeb Componentsをまとめてリスト化していたりするので、もし自分の目的に見合ったものがあれば試してみるといいかもしれません。
橋本
なるほど…すでにいろいろ公開されてるんですね。ただ、やっぱりWebに公開されているものはバージョンアップによってコンポーネントの振る舞いが変わってしまうこともありえるので、そこは少し怖いですね。
加藤
はい。おっしゃる通りで、プロダクションとして使うのは若干の不安はあるので、バージョンを固定したり、プロトタイプとか、社内ツールとか、一般に影響が出ないところで使うのがいいかもしれません。
橋本
はい。ここまでWeb Componentsの概要をずらっと話してきました。今回は触れませんでしたが、フレームワークで使っているようなコンポーネントのライフサイクルなど、フレームワークのいいところを吸収しつつ、フレームワークに依存しないっていうところが個人的にはいいなぁと感じました。
加藤
うん。私もそう思いますね。フレームワークはいらないけど、逆にフレームワークの中でWeb Compoentsを使うことはできるし、たとえばフレームワークをReactからVue.jsやAngularに変えないといけない!とか、フレームワーク禁止になってしまった!なんてことがあってもコンポーネントの部分はそのまま活かすことができますよね。
橋本
そうですね。フレームワークを使っている人からすれば、わりと親しみやすいのかなーと思ったんですけど、一方でフレームワークになじみのない人からするとこれまでとは大きく違った考え方が必要になりそうですね。
加藤
はい。おっしゃる通りで、Web Componentsにこう…がっつり取り組んでいる人って、わりとJSをガリガリ書いている人たちが今は中心な気がしています。もちろんWeb Components自体JSが必要な技術なので仕方がないんですけども、コンポーネントを作る人だけではなく、コンポーネントを使う人たちともコミュニケーションをとることがよいコンポーネントを作る秘訣かなとは思ってます!
橋本
まぁあと、今日話せなかったことはいずれまた別の回でお話しようと思いますので、引き続きミツエーテックラジオを聞いていただけると嬉しいです!
最後に、ミツエーリンクスではスマートなコミュニケーションをデザインしたいUIデザイナー、UI開発者を募集しています。採用サイトではオンライン説明会やオンライン面接なども行っていますのでチェックしてみてください。
また、このPodcastはApple Podcast、 Google Podcast、Spotify、YouTubeで配信していますので、お好みのプラットフォームでフォローいただけると、最新のエピソードをすぐ視聴できます!こちらもぜひご活用ください。 「#ミツエーテックラジオ」でご意見、ご感想、こんなこと話してほしいというリクエストなどもお待ちしております。
それでは今日はこの辺で!ありがとうございましたー!
加藤
ありがとうございました!