Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
どんなページでも動かす!JS_CSS汚染を避ける戦い
Search
Ryota Kunisada
August 04, 2023
Technology
0
310
どんなページでも動かす!JS_CSS汚染を避ける戦い
第1回 3rdparty.jsで発表した資料です。
https://3rdpartyjs.connpass.com/event/289558/
Ryota Kunisada
August 04, 2023
Tweet
Share
More Decks by Ryota Kunisada
See All by Ryota Kunisada
開発者とQAの越境で自動テストが増える開発プロセスを実現する
92thunder
1
400
フロントエンドエンジニアとQAエンジニアの協働による自動テストを増やす開発プロセス
92thunder
0
73
トランクベース開発の導入で見えた DevOpsの技術・プロセス・文化との繋がり
92thunder
0
1.3k
開発生産性向上の取り組みログ
92thunder
0
110
Other Decks in Technology
See All in Technology
日々のSlackアラート確認運用をCustom Chat Modesで楽にした話 / 日々のSlackアラート確認運用をCustom Chat Modesで楽にした話
imamotohikaru
0
450
マーケットプレイス版Oracle WebCenter Content For OCI
oracle4engineer
PRO
3
1.3k
Post-AIコーディング時代のエンジニア生存戦略
shinoyu
0
250
Flutterコントリビューションのススメ
d_r_1009
1
350
こんな時代だからこそ! 想定しておきたいアクセスキー漏洩後のムーブ
takuyay0ne
4
550
Design and implementation of "Markdown to Google Slides" / phpconfuk 2025
k1low
1
390
レビュー負債を解消する ― CodeRabbitが支えるAI駆動開発
moongift
PRO
0
150
これからアウトプットする人たちへ - アウトプットを支える技術 / that support output
soudai
PRO
18
5.3k
「データ無い! 腹立つ! 推論する!」から 「データ無い! 腹立つ! データを作る」へ チームでデータを作り、育てられるようにするまで / How can we create, use, and maintain data ourselves?
moznion
7
3.7k
コミュニティと共に変化する 私とFusicの8年間
ayasamind
0
450
QAエンジニアがプロダクト専任で チームの中に入ると。。。?/登壇資料(杉森 太樹)
hacobu
PRO
0
190
エンジニア採用と 技術広報の取り組みと注力点/techpr1112
nishiuma
0
130
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
127
54k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
Scaling GitHub
holman
463
140k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
[RailsConf 2023] Rails as a piece of cake
palkan
57
6k
Visualization
eitanlees
150
16k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
How GitHub (no longer) Works
holman
315
140k
RailsConf 2023
tenderlove
30
1.3k
How to Think Like a Performance Engineer
csswizardry
28
2.3k
The Invisible Side of Design
smashingmag
302
51k
Transcript
どんなページでも動かす! JS/CSS汚染を避ける戦い テックタッチ株式会社 / 国定 凌太
92thunder • テックタッチ株式会社に1人目社員として入社後 フロントエンドエンジニアとして開発をリード • 2023年6月から北海道旭川市へ移住しフルリモートワークに • 普段語られることの少ないサードパーティJS開発の 仲間と会うためにイベントを企画!
「テックタッチ」の紹介 • WebサイトにサードパーティJSを組み込むことで、 ノーコードでガイドやツールチップでの案内を追加できる • スニペット / ブラウザ拡張で提供
個人的サードパーティスクリプトの分類 Embed • Google Map • 広告系 Widget • Intercom
• HubSpot Analytics • Google Analytics • Google Tag Manager UI拡張 • Techtouch • Grammarly Intercomホームページより抜粋
DOMアクセスは多い?少ない? Widget • チャットUIは画面内の 一部分で完結 • DOMへのアクセス を必要としない iframeを使うことで JS/CSS汚染を回避できる
UI拡張 • 吹き出しが要素に追従 • ページ内の要素にイベントを設定して動作 DOMアクセスが頻繁に発生するため iframeを介すとpostMessageのやり取りが複雑に 今日はこちらの話がメインになります 🙏 Intercomホームページより抜粋
苦労した話 🥺 • 「テックタッチ」を組み込むとページを一切クリックできない! • ページのCSSの影響を受けてレイアウトが崩れた! • とあるライブラリが入っているシステムでは 「テックタッチ」が動かない!
サードパーティスクリプトの不具合の例 https://twitter.com/ckazu/status/1622428980304568325 • Merlin AI powered by ChatGPT というChrome拡張が .loader
クラスのついた要素に 回転アニメーションを付与 • サードパーティスクリプトは 影響を考慮したCSS設計が必要
課題と解決策 プロトタイプJS汚染 CSSグローバル汚染 iframe Transform Runtime CSS詳細度 を上げる Shadow DOM
❌
プロトタイプ汚染 プロトタイプJS汚染 CSSグローバル汚染 Transform Runtime CSS詳細度 を上げる Shadow DOM
プロトタイプ汚染 • Webサイト側でJSの動作が書き換えられていることにより サードパーティスクリプトが意図しない動作になってしまう問題 • 汚染による影響を受けない/与えないための対策が必要 Prototype.js 1.5系 Native
プロトタイプ汚染を避けるには 🤔 3rd party script 1st party script ❌ プロトタイプ汚染された関数を呼び出すと意図しない動作に
Prototype.js 1.5系
プロトタイプ汚染を避けるには 🤔 3rd party script 1st party script ❌ プロトタイプ汚染された関数を呼び出すと意図しない動作に
Native 3rd party scriptではネイティブの関数を使いたいが、汚染されてしまっている … Prototype.js 1.5系
プロトタイプ汚染を避けるには 🤔 3rd party script 1st party script ❌ プロトタイプ汚染された関数を呼び出すと意図しない動作に
Prototype.js 1.5系 @babel/plugin-transform-runtime で変換 core-jsでネイティブに近い動作を実現 Native
transform-rutime を使って core-js に置き換える babel • 新しいバージョンでのJavaScriptの書き方を 古いバージョンのブラウザでも動作するようにトランスパイルする @babel/plugin-transform-runtime •
babelが変換するコードを指定したヘルパーコードに置き換えることができる • core-jsをヘルパーコードとして指定できる core-js • JavaScriptのポリフィル実装。グローバル汚染せずに使うこともできる。
CSSグローバル汚染 プロトタイプJS汚染 CSSグローバル汚染 Transform Runtime CSS詳細度 を上げる Shadow DOM
CSSグローバル汚染 • CSSはグローバルに影響する • サードパーティスクリプトの動作を考慮してCSSを実装する人は存在しない <div id="app"> <p>main-app</p> </div> <div
id="thirdparty-app"> <p>3rdparty-app</p> </div> p:not(#fakeId#fakeId) { color: red; } #thirdparty-app p { color: blue; } 適用されない
CSS詳細度とは • 詳細度 (Specificity) は、ある要素に最も関連性の高い CSS 宣言を決定する ためにブラウザーが使用するアルゴリズムで、これによって、その要素に使 用するプロパティ値が決定されます。出典: https://developer.mozilla.org/ja/docs/Web/CSS/Specificity
• CSS詳細度の重み付け計算方法 ◦ ID - CLASS - TYPE • 例 #thirdparty-app p 1-0-1 IDが1つ、pタグが1つ p:not(#fakeId#fakeId) 2-0-1 :not()の中身が加算される
CSSの詳細度を上げる :is() や :not() を使い、冗長なIDを設定して詳細度を上げることで打ち勝つ /* 2-0-1 */ p:not(#fakeId#fakeId) {
color: red; } /* 3-0-1 */ #thirdparty-app p:not(#fakeId#fakeId) { color: blue; } IEサポートするなら 詳細度の対応が必要だった
Shadow DOM 通常のDOMとの境界を作ることでCSSの影響を無効化できる 出典:https://developer.mozilla.org/ja/docs/Web/API/Web_components/Using_shadow_DOM
const thirdpartyApp = document.getElementById("thirdparty-app"); const shadow = thirdpartyApp.attachShadow({ mode: "open"
}); const p = document.createElement("p"); p.textContent = "3rdparty-app"; shadow.appendChild(p); const style = document.createElement("style"); style.textContent = `p { color: blue }`; shadow.appendChild(style); ShadowRootを介して内部のDOMにアクセスする必要があるため、 Shadow DOM対応していないライブラリに注意
今後の取り組み プロトタイプJS汚染 CSSグローバル汚染 Transform Runtime CSS詳細度 を上げる Shadow DOM Shadow
Realm Web Worker WASM パフォーマンス改善
おわりに • iframeを使わずにJS/CSS汚染を回避するための技術を紹介しました • サードパーティスクリプト開発に限った話だけではなく 通常のWebアプリケーション開発で扱う技術も多くある ◦ サードパーティではより深い理解が必要! • ブラウザサイドJavaScriptのSandbox技術は今後も進化していくので、
動向を見ながらユーザーによりよい体験を提供できるように取り入れる ◦ #3rdpartyjs でやっていきましょう!
検証 • プロトタイプ汚染: https://codesandbox.io/s/infallible-noyce-j64clh • CSS詳細度: https://codesandbox.io/s/css-specificity-q8g3pk • Shadow DOM:
https://codesandbox.io/s/shadow-dom-8h5pms
参考 • https://github.com/tc39/proposal-shadowrealm • https://github.com/tc39/proposal-ses