Cybozu Frontend Monthly #8

イベント概要

サイボウズフロントエンドマンスリーは、サイボウズ社内で行っているフロントエンド情報共有会「フロントエンドウィークリー」の公開版です。

その月に気になったフロントエンドの情報を、サイボウズのフロントエンドエキスパートチームのメンバーが共有していきます。

このイベントのハッシュタグは #サイボウズフロントエンドマンスリー です。

※フロントエンドウィークリーとは

毎週火曜の 17:00 〜 18:00 で社内向けに行っているフロントエンドの気になる記事を紹介する会です。2016年3月15日から行われています。
ハッシュタグ #サイボウズフロントエンドウィークリー で実況しています。

開催日

2021年03月02日

イベントページ

https://cybozu.connpass.com/event/205864/

配信URL

https://www.youtube.com/watch?v=V-qsrYmUHjk

タイムテーブル

07:50 - 08:00配信開始
08:00 - 08:05オープニング
08:05 - 08:55本編
08:55 - 09:00クロージング

メンバー


紹介記事

SmartHR が Internet Explorer サポート終了のお知らせを出した

  • 共有者: nakajmg

Microsoft が自身のサービスでの IE サポート終了予定を発表してから、国内のサービスからもそれに追従するようにサポート終了のお知らせが出てきています。

SmartHR に続いてMoney Forward も IE サポート終了のお知らせを出しました

背景として挙げているのはセキュリティ面、Microsoft Edge の存在、そしてMicrosoft 365 における IE11 サポート終了の発表です。 また、両者ともに IE サポートの終了月を Microsoft 365 の IE サポート終了の日に合わせて 2021 年 8 月までとしています。

今後もこの動きに追従する発表が出てきそうです。

(※追記) クラウドワークスさんも同時期に IE を推奨ブラウザから外すお知らせを出しています


Using AbortController as an Alternative for Removing Event Listeners | CSS-Tricks

  • 共有者: pirosikick

AbortController を jQuery の once 関数みたいな一度実行したら消えるタイプのイベントリスナーの代替として使う話。 mousemovemouseupのイベントハンドラを、mouseup時に両方削除するようなユースケースの場合、AbortController を使うとスッキリ書ける。


Introducing Env: a better way to read environment variables in JavaScript - Human Who Codes

  • 共有者: pirosikick

ブラウザにサーバーサイドから環境変数を流し込む際に陥りがちな罠と、それを回避するために作られた@humanwhocodes/envについて。 env.requiredenv.existsは Proxy で実装されている。 200 行くらいのシンプルなコードなので、@humanwhocodes/envを参考に自前で環境変数をラップしてアクセスする関数を作るのもよさそう。


Maximally optimizing image loading for the web in 2021

  • 共有者: b4h0_c4t

Core Web Vitals を指標として画像読み込みの最適化する手法を簡単なコード付きで紹介しています。

半分ほどはブラウザが限定されていますが、手法として覚えておいても損はないかなという感じです。

  • Responsive Layout

    • 画像に width 、 height を設定する
  • Lazy Rendering

    • content-visibility を利用する
  • AVIF

    • AVIF 形式の画像を利用する
  • Load the right number of pixels

    • srcset で画面サイズ毎に適切な画像を読み込む
  • Caching / Immutable URLs

    • cache-control を利用する
  • Lazy loading

    • loading="lazy" 属性を追加する
  • Asynchronous decoding

    • decoding="async" 属性を追加する
  • Blurry placeholder

    • background-image に blurry image を差し込む

:focus-visible 周りのブラウザ実装が進んだ

  • 共有者: sakito

2 月に:focus-visibleまわりでブラウザの動きが多かったのでまとめました。

:focus-visible おさらい

:focus-visibleは、タブ移動時のみ要素のoutlineが表示されるもの。:focusだと要素にクリック時やタブ移動時にフォーカスした際にoutlineが表示されるので、outlineを消しがちだったがそれを避けることができる。

Chrome

Chrome で:focus-visible が UA style sheet のデフォルトになりました。

Chrome 86 から:focus-visibleは使用できていたが、UA style sheet:forcusだったので、下記のような記述が必要だった。

:focus:not(:focus-visible) {
  outline: 0;
}

今回の変更で:focus-visibleが UA style sheet のデフォルトになったので上記の記述は不要になる。

この変更はChrome 90から入るぽいです。

Firefox

Firefox 85 で:focus-visible が有効にになりました。

いままで:-moz-focusringの疑似クラスを使用していたが、Firefox 85 で:focus-visibleが実装されました。 FirefoxDevTools でスタイルの切り替えもできるようになっています。

Safari

Igalia が Open Prioritization を通して、WebKit に:focus-visible を実装協力

Igalia がOpen Prioritizationというクラウドファンディングを通して、WebKit に:focus-visibleを実装することになり、実装するために WPT のテストを実装したり、実装するにあたった課題を報告している記事です。

上記でも紹介している Chrome で:focus-visible が UA style sheet のデフォルトになっていない Issue を報告をしているのも Igalia の人なのですが、この PJ を通して発見されたものになります。

littledan/proposal-module-fragments

  • 共有者: @sosukesuzuki

3 月の TC39 ミーティングで @littledan 氏から Module Fragments という Stage 0 のプロポーザルについて発表される予定です。

Module Fragments は次のようにインラインでモジュールを定義できる構文を導入します。

module "#foo" {
  export let foo = "foo";
}

import { foo } from "#foo";

Module Fragments は主に webpack や Rollup、Parcel のようなモジュールバンドラーの出力として使われることを想定しています。

現在のモジュールバンドラーはいくつかの潜在的な問題を抱えています。

  • ECMAScript Modules の仕様をエミュレートする必要があるため実装が複雑になる

    • しかも ECMAScript Modules に関連する仕様は増え続けるのでその度に追従するための実装をする必要がある
  • 出力のコードにモジュール構造が残らず JavaScript エンジンでの最適化に使うことができないので、パフォーマンスに悪影響が及ぶ可能性がある

モジュールバンドラーは Module Fragments を使ったコードを出力にすることでこれらの問題を解決することができます。

手前味噌ですがこれについて解説する記事を書いたので気になる方はご覧ください。

https://sosukesuzuki.dev/posts/stage-0-module-fragments/


Requesting performance isolation with the Origin-Agent-Cluster header

  • 共有者: shisama_

Site Isolation の Origin で Isolation するための機能の話です。 HTTP レスポンスヘッダとしてOrigin-Agent-Cluster: ?1を返すことで iframe で埋め込まれた Same-site cross-origin なページをプロセスレベルで分離することが可能になります。

たとえば、https://mail.example.com の中に iframe を使って https://chat.example.com が埋め込まれていたとします。 両者はサブドメインは違えど eTLD+1 は同じなので SameSite となります。Site Isolation は Same-site であればプロセスは 1 つのため、メモリ管理も同じプロセス内で行われます。

そのため、一方に XSS が埋め込まれてメモリにアクセスできれば、サイドチャネル攻撃により情報を盗まれる可能性があります。 Origin レベルで分離することで Same-site でも Cross-origin の場合でも一方に脆弱性があってももう一方への影響を防ぐことができます。 Origin-Agent-Cluster が有効になっている場合、次のことができなくなります。

  • document.domain = "example.com" をしても何もしない。書き換えないだけで例外は投げない
  • postMessage() による WebAssembly.Module を Cross-origin のページに送信できない
  • SharedArrayBufferWebAssembly.Memory を Cross-origin のページに送信できない

プロセスが同じだと iframe で埋め込んだページがリソースを使いまくっていた場合、埋め込み元のページにも影響していました。しかし、プロセスが分離されると、埋め込み元のことを気にしなくても良くなるといったパフォーマンスの改善にもつながります。
埋め込み先が重くても埋め込み元は影響を受けない。
ただ、パフォーマンスに関しても本当に速くなるのかは実際動かして確認したほうがいいとのことです。

ただし、Origin-Agent-Cluster はセキュリティに関する HTTP ヘッダではない、とこの記事には書かれています。次のような理由から origin-keyed agent cluster がセキュリティ機能として考えないほうがいいとされています。その代わり、リソースを分離することでブラウザにリソース割当の優先度決めを助長する方法として考えられます。

  • Firefox や Safari では iframe ごとのプロセスの分離が実装されていない
  • リソースが限られている Android ではできるだけプロセスを増やさないようにしている

    • Site Isolation もパスワード画面など一部でしか適用されていない
  • ブラウザはプロセスの分離ではなく、スレッドによる分離などを優先して利用するかもしれない
  • サイト全体ではなく一部のページにのみ Origin-Agent-Cluster が適用されていた場合、適用されていないページを踏むとブラウザはその Origin を origin keyed cluster としてみなさない
その他参考文献

フロントエンドエキスパートチームについて

https://speakerdeck.com/cybozuinsideout/frontendexpert-team