Slide 1

Slide 1 text

Shadow DOMとCSSの現状 2024-02-27 DOMDOMトークス #1

Slide 2

Slide 2 text

発表者紹介 uhyo 株式会社カオナビ フロントエンドエンジニア 普段はTypeScriptとかReactをやっている。 好きなDOM仕様はDOM3 Load & Save (昔のOperaにだけ実装されてたやつ)

Slide 3

Slide 3 text

最近のDOMDOMニュース 2024年2⽉、Firefox 123がリリース。 Declarative Shadow DOMのサポートが追加され、 すべてのモダンブラウザでサポートが完了。

Slide 4

Slide 4 text

Declarative Shadow DOM復習 従来はJavaScriptのElement#attachShadowを 使わなければshadow rootを⽣成できなかった。 template要素のshadowrootmode属性を使うこと で、HTMLだけでshadow rootを⽣成できる。

Slide 5

Slide 5 text

Declarative Shadow DOM復習

Slide 6

Slide 6 text

DOMDOMクイズ こうするとshadow root を⽣成できる? (JSでtemplate要素を⽣ 成してdivに追加)

Slide 7

Slide 7 text

DOMDOMクイズ 答え: できない 理由: Declarative Shadow Root はHTMLパーサーの機能だから (どういう意味か調べてみよう!) ※innerHTMLとかでパーサーを起動してもできない (allowDeclarativeShadowRootsフラグで制御されているため)

Slide 8

Slide 8 text

Shadow DOMとCSS Shadow DOMの⽤途はいろいろあるが、個⼈的に はCSSのスコーピングを重要視。 •Shadow DOMの外で宣⾔されたスタイルは 中の要素に適⽤されない •逆も同様 (::partの話は今⽇は省略)

Slide 9

Slide 9 text

CSSのスコーピング Shadow Treeの中に適⽤ されるスタイルは同じ Shadow Treeの中で宣⾔する 必要がある。 利点: spanみたいな セレクタを雑に使える (クラス名とかに頼る機会が減る)

Slide 10

Slide 10 text

@scopeとの⽐較 CSS Cascading and Inheritance Level 6で定義さ れた@scopeもスコーピングができる。 上限と下限を指定できる。

Slide 11

Slide 11 text

@scopeとの⽐較 (1) UIライブラリと組み合わせる場合、 @scopeだと下限の設定に難がある。 children内にはスタイルを適⽤ したくない場合はどうすれば…… (Reactの例)

Slide 12

Slide 12 text

@scopeとの⽐較 (1) Shadow DOMはこのようなケースが得意。 Shadow tree内のstyleで宣⾔ されたスタイルはに 当てはめられたツリーには 適⽤されない

Slide 13

Slide 13 text

@scopeとの⽐較 (2) 親から .parent-component > div > div > button みたいなセレクタで攻撃された場合…… @scope: 防御できない Shadow DOM: 防御できる 「やろうと思えばできちゃう」を防げるのは優秀。

Slide 14

Slide 14 text

余談: 昔作ったやつ これからのCSS in JSはShadow DOM ベースに違いない!! と思い、 2020年に作ったCSS in JSライブラリ (もちろん流⾏らず) https://github.com/uhyo/castella

Slide 15

Slide 15 text

余談:昔作ったやつ CSSはマークアップと密結合している という考えから、HTMLとCSSのセッ トで1つのコンポーネントを定義。 HTMLはShadow DOMに⼊る。 (これがあるべき姿では? とはずっと思っている)

Slide 16

Slide 16 text

問題: リセットCSS 最近はリセットCSSを使うことが多い。 Shadow DOMの中にリセットCSSを適⽤するため には、Shadow DOMの中から読み込む必要がある。

Slide 17

Slide 17 text

問題: リセットCSS これコンポーネントごと に読み込んで⼤丈夫なの?

Slide 18

Slide 18 text

実際にやってみた 複数のshadow treeの中から でCSSファイルを読み込む場合と読み込まない 場合で、ページのメモリ使⽤量の差を計測。 ブラウザ: Firefox 123.0, Google Chrome 121.0.6167.185 ソースコード: https://github.com/uhyo/domdom-talks-1

Slide 19

Slide 19 text

実際にやってみた 0 50 100 150 200 250 10000 20000 30000 40000 50000 メモリ増加量 (MB) コンポーネント数 (Firefox) (Chrome) +33% +74〜132%

Slide 20

Slide 20 text

実際にやってみた 0 50 100 150 200 250 10000 20000 30000 40000 50000 メモリ増加量 (MB) コンポーネント数 (Firefox) (Chrome) の量に対して線型にメモリ使⽤量 が増加、割合としては⼀定に +33% +74〜132%

Slide 21

Slide 21 text

グラフの注意点 Google Chromeのメモリ使⽤量は計測しても全然安定 しなかったので参考記録です。 Firefoxの+33%という数字はlink要素の追加以外にも CSS量の増加による影響をすべて含んだものです。

Slide 22

Slide 22 text

オーバーヘッドが⼤きい…… 同じリセットCSSを全部のコンポーネントに適⽤ したいだけなのに、コンポーネントの数が増える ほどメモリ使⽤量も増えるのは嬉しくない。 (コンポーネント数に⽐例するオーバーヘッドはある程度は 避けられないが) ※ reset.cssにリクエストが⾶ぶのはさすがに1回

Slide 23

Slide 23 text

救世主!? adoptedStyleSheets adoptedStyleSheetsを使うことで、複数の shadow tree間で同じCSSStyleSheet インスタンスを共有することができる。

Slide 24

Slide 24 text

adoptedStyleSheetsのメモリ使⽤量 0 50 100 150 200 250 10000 20000 30000 40000 50000 メモリ増加量 (MB) コンポーネント数 (Firefox) (Chrome) adoptedStyleSheets (Firefox) adoptedStyleSheets (Chrome) +38%

Slide 25

Slide 25 text

0 50 100 150 200 250 10000 20000 30000 40000 50000 メモリ増加量 (MB) コンポーネント数 adoptedStyleSheetsのメモリ使⽤量 Firefoxは逆にちょっと増えてる…… Chromeはよくわからんけど減ってはいる。 +38%

Slide 26

Slide 26 text

adoptedStyleSheets所感 よく分かんないけどChromeではメモリ使⽤量 減ってそう。 何でFirefoxのオーバーヘッド増えたの? Safariは謎(この資料をWindowsで作ったので) Declarative Shadow DOMでは対応していない のは⾟い。

Slide 27

Slide 27 text

次の希望: Declarative CSS Module Scripts adoptedStyleSheetsに相当する処理を JavaScriptを使わずに書けるようにしたいという 議論も存在する。 2023年4⽉のミーティングの結論は “Present members of WCCG reach consensus: discuss this further with implementers.” https://github.com/WICG/webcomponents/issues/939

Slide 28

Slide 28 text

次の希望2: Declarative Custom Elements 似たような問題意識に対して、 “I think we should solve declarative custom elements instead.” との⾒解を⽰すメンバーもいる。 その名の通り、customElements.register相当 のことをマークアップからできるようにする。 https://github.com/whatwg/html/issues/9962

Slide 29

Slide 29 text

WebComponents元年 Declarative Shadow DOMの サポートも出揃い、2023年からの WebComponents元年v4も佳境と なった。 しかし、Shadow DOMとCSS関連 が良い形におさまるにはまだ時間が かかりそうだ。 https://www.docswell.com/s/jxck/5246NN- 1st-year-of-webcomponents-v4 参考: When the 1st year of Web Components era come true https://www.docswell.com/s/araya/ZQ8P9E-2024-01-25-202509

Slide 30

Slide 30 text

まとめ Declarative Shadow DOMのサポートにより、 Shadow DOMベースのCSS in JSもSSRできる ようになった。 しかし、最終形態ではなく次の議論もこれから。 WebComponents 元年v5 まだかな?