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
390
フロントエンドエンジニアとQAエンジニアの協働による自動テストを増やす開発プロセス
92thunder
0
72
トランクベース開発の導入で見えた DevOpsの技術・プロセス・文化との繋がり
92thunder
0
1.2k
開発生産性向上の取り組みログ
92thunder
0
110
Other Decks in Technology
See All in Technology
プレイドのユニークな技術とインターンのリアル
plaidtech
PRO
1
460
Kubernetes self-healing of your workload
hwchiu
0
580
知覚とデザイン
rinchoku
1
610
ViteとTypeScriptのProject Referencesで 大規模モノレポのUIカタログのリリースサイクルを高速化する
shuta13
3
220
デザインとエンジニアリングの架け橋を目指す OPTiMのデザインシステム「nucleus」の軌跡と広げ方
optim
0
120
CREが作る自己解決サイクルSlackワークフローに組み込んだAIによる社内ヘルプデスク改革 #cre_meetup
bengo4com
0
350
パフォーマンスチューニングのために普段からできること/Performance Tuning: Daily Practices
fujiwara3
2
140
.NET 10のBlazorの期待の新機能
htkym
0
150
オブザーバビリティと育てた ID管理・認証認可基盤の歩み / The Journey of an ID Management, Authentication, and Authorization Platform Nurtured with Observability
kaminashi
1
1k
会社を支える Pythonという言語戦略 ~なぜPythonを主要言語にしているのか?~
curekoshimizu
3
880
Okta Identity Governanceで実現する最小権限の原則 / Implementing the Principle of Least Privilege with Okta Identity Governance
tatsumin39
0
180
webpack依存からの脱却!快適フロントエンド開発をViteで実現する #vuefes
bengo4com
4
3.6k
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
A Tale of Four Properties
chriscoyier
161
23k
Making Projects Easy
brettharned
120
6.4k
Site-Speed That Sticks
csswizardry
13
930
Speed Design
sergeychernyshev
32
1.2k
Statistics for Hackers
jakevdp
799
220k
Code Review Best Practice
trishagee
72
19k
Side Projects
sachag
455
43k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Producing Creativity
orderedlist
PRO
347
40k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.6k
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