Upgrade to Pro — share decks privately, control downloads, hide ads and more …

UserAgentに依存した分岐を捨てられるか (または何故捨てられていないのか)

pastak
January 12, 2024
3.4k

UserAgentに依存した分岐を捨てられるか (または何故捨てられていないのか)

ToKyoto.js #2 で話した資料です

pastak

January 12, 2024
Tweet

More Decks by pastak

Transcript

  1. About me • Pasta-K • x.com/pastak • github.com/pastak • Kyoto.jsオーガナイザー

    • 京都市出身・在住 • Helpfeel&はてなで働いています
  2. UserAgentの現状 - Firefox & Safari • Firefox • UA-CHには反対している •

    https://github.com/mozilla/standards-positions/pull/579 • パフォーマンスへの懸念・将来の仕様への懸念 • Safari • UA-CHに未対応 • 一度UAのバージョンの凍結を実施しようとするも断念 • SafariのUA文字列が固定されて固定されなくなったおはなし - fragmentary
  3. iPadと画面幅とUserAgent • iPadは画面幅に応じてUserAgentが変更される • 画面幅が広いときはIntel Macと同じように見える • 例: Mozilla/5.0 (Macintosh;

    Intel Mac OS X 10_15) AppleWebKit/ 605.1.15 (KHTML, like Gecko) • 画面幅が狭いときはiPadと分かるiPhoneとも異なるUAになる • 例: Mozilla/5.0 (iPad; CPU OS 13_0 like Mac OS X) AppleWebKit/ 605.1.15 (KHTML, like Gecko) Mobile/15E148 • 画面幅が変わったときに動的に変わることはない
  4. ざっくりUA-CHとは • サーバーからのResponse Headerを 使って、必要な情報を宣言すると、 後続のRequest時に付与される • `navigator.userAgentData` でも アクセス可能

    • 重要な値は `Critical-CH` を付与す ると、Chromeがその値を追加した 再度のリクエストが実施される IUUQTEFWFMPQFSTHPPHMFDPNQSJWBDZTBOECPYQSPUFDUJPOTVTFSBHFOUΑΓ
  5. 特定の機能が利用出来るか確認したい > ユーザーエージェントによる判定は決して行うべきではありません。その代わりに常に機能の検出を 行う代替手段があります(*) • Feature Detectionとして代替手段はよく知られている • 各種APIやHTML要素の属性などのサポートの有無を検出する •

    navigator.serviceWorker • 'name' in HTMLDetailsElement.prototype • CSSの機能をサポートしているかを検出する • CSSで @supports (<supports-condition>) • JSで CSS.supports メソッドを使う IUUQTEFWFMPQFSNP[JMMBPSHKBEPDT8FC)551#SPXTFS@EFUFDUJPO@VTJOH@UIF@VTFS@BHFOU
  6. ブラウザや端末に応じて異なるHTMLを返したい > 形式的な <div> または <span> 要素を追加することで、それを防ぐことがで きませんか?ユーザーエージェントの検出を正しく行うことは、 HTML の純度

    をいくらか損なっても構わないくらい難しいものです。また、デザインを考え 直してください。プログレッシブエンハンスメントや流体レイアウトを使用す ることで、回避することはできませんか?(*) • 出来たら困らないけど、実際問題として結構難しくないですか? • ??「レスポンシブってやつに移行すれば、モバイルでもタブレットでもPCで も同じHTMLでいけるっしょ〜」 IUUQTEFWFMPQFSNP[JMMBPSHKBEPDT8FC)551#SPXTFS@EFUFDUJPO@VTJOH@UIF@VTFS@BHFOU
  7. 画面幅に応じて表示する要素やCSSを変更する • JavaScriptでMediaQueryListを使用する const mql = window.matchMedia("(max-width: 600px)"); const element

    = document.querySelector('.text'); mql.addEventListener("change", (e) => { if (e.matches) { element.textContent = 'ڱ͍ը໘'; } else { element.textContent = '޿͍ը໘'; } }); • CSSで@mediaを使用する @media (max-width: 1250px)
  8. 本当にUserAgentの利用をやめないといけないのか? • 今後もOSやブラウザの名前、ブラウザのメジャーバージョンは取得できそうな状況は続きそう • iPadは環境に応じてOSを名乗り分けてくるが…… • Safariが再度UAのバージョンをフリーズする可能性も低そう • この問題にどれくらい我々は向き合う必要があるのかは若干懐疑的 •

    いつか信頼できなくなる可能性はあるものの、Webの互換性や機能要件的にも廃止すること は無さそう • UA-CHも実際に標準化出来そうな様子も無いので、これらの問題が実際に問題として表面化 するのはいつの未来? • Chromeが提案しているPrivacy Budget(*)が入れば、むやみに取得することはできなくな る可能性はあるものの実際どうなのでしょう… IUUQTEFWFMPQFSTHPPHMFDPNQSJWBDZTBOECPYQSPUFDUJPOTQSJWBDZCVEHFU