この記事は Chromium Blog の記事 "Chrome 98 Beta: Color Gradient Vector Fonts, Region Capture Origin Trial, and More " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
特に記載のない限り、下記の変更は Android、Chrome OS、Linux、macOS、Windows 向けの最新の Chrome ベータ版チャンネル リリースに適用されます。ここに記載されている機能の詳細については、リンクまたは ChromeStatus.com の一覧でご確認ください。2022 年 1 月 10 日の時点で Chrome 98 はベータ版です。PC 向けの最新版は Google.com で、Android では Google Play ストアでダウンロードできます。
COLRv1 カラー グラデーション ベクター フォント
このバージョンの Chrome は、新しく追加されたフォント形式として COLRv1 カラー グラデーション ベクター フォントをサポートします。カラーフォントのグリフには複数の色が含まれています。例として、絵文字や国旗、多色文字などが挙げられます。
COLRv1 は COLRv0 フォント形式が進化したもので、ウェブでのカラーフォントの普及を目的としています。COLRv1 フォントは、グラデーション、座標変換、合成などのさまざまな視覚表現に対応しながらも、フォントのサイズはとても小さくなっています。また、COLRv1 フォントは OpenType のバリエーションもサポートしています。フォントのサイズがとても小さいのは、内部形状の再利用とコンパクトなフォント形式定義、効率的な圧縮によるものです。
次のイメージは、Noto Color Emoji の例を示しています。これはビットマップ フォントでは約 9 MB ですが、COLRv1 ベクター フォントでは 1.85 MB しかありません(WOFF2 圧縮後)。
明瞭な COLRv1 ベクター フォント(左)と、ビットマップ フォント(右)の比較。 WOFF2 圧縮後のビットマップ フォントと COLRv1 フォントとしての Noto Emoji のフォントサイズ。
詳細については、Chrome 98 の COLRv1 カラー グラデーション ベクター フォント をご覧ください。
3 桁のバージョン番号に対する準備
今年中に Chrome のバージョン 100 がリリースされ、ユーザー エージェント文字列で報告されるバージョン番号の桁数が増える予定です。サイトオーナーが新しい文字列をテストしやすくするために、Chrome 96 では、Chrome のユーザー エージェント文字列として「100」が返されるようにするランタイム フラグが導入されました。この新しいフラグ chrome://flags/#force-major-version-to-100 は、Chrome 96 以降で利用できます。詳細については、Chrome の User-Agent 文字列のメジャー バージョンを強制的に 100 にする をご覧ください。
オリジン トライアル
このバージョンの Chrome には、以下のオリジン トライアルが導入されています。オリジン トライアルとして新機能を試せるようにすることで、ウェブ標準コミュニティにユーザビリティ、実用性、有効性についてのフィードバックを提供することができます。以下の項目を含め、現在 Chrome でサポートされているオリジン トライアルに登録するには、Chrome オリジン トライアル ダッシュボード をご覧ください。Chrome のオリジン トライアルの詳細については、ウェブ デベロッパーのためのオリジン トライアル ガイド をご覧ください。Microsoft Edge は、Chrome とは別に独自のオリジン トライアルを行っています。詳細については、Microsoft Edge オリジン トライアル デベロッパー コンソール をご覧ください。
新しいオリジン トライアル
リージョン キャプチャ
リージョン キャプチャは、自分でキャプチャした動画トラックをクロップするための API です。現在、アプリケーションは、preferCurrentTab
の指定の有無にかかわらず、getDisplayMedia()
を使ってアプリケーション自体が実行されているタブをキャプチャできます。その際、(通常はリモートに共有する前に)結果の動画トラックをクロップし、コンテンツの一部を削除する場合があります。
今回のリリースに追加されたその他の機能
contain-intrinsic-size に auto キーワードを追加
contain-intrinsic-size
に auto キーワード のサポートが追加され、ウェブサイトで最後に記憶した要素のサイズ(存在する場合)が利用できるようになります。これにより、content-visibility: auto
が指定された要素よりもユーザー エクスペリエンスが向上します。この機能がない場合、ウェブ デベロッパーは要素がレンダリングされるサイズを推定しなければなりません。この機能と content-visibility: auto
を併用すると、要素が飛び回る可能性があります。
AudioContext.outputLatency
新しい AudioContext.outputLatency
プロパティ は、オーディオ出力のレイテンシを秒単位で推定します。厳密に言えば、これはユーザー エージェントがホストシステムにバッファリングをリクエストした時間から、オーディオ出力デバイスがバッファ内の最初のサンプルを処理した時間までの間隔です。スピーカーやヘッドフォンなど、音響シグナルを生成するデバイスの場合、後者の時間はサンプルのサウンドが生成された時間です。Firefox では、すでにこの機能が実装されています。
CSS の色調整 : color-scheme の 'only' キーワード
color-scheme
の仕様に再追加された only
キーワードが Chrome でサポートされるようになりました 。これにより、特定の単一要素で color-scheme を無効化できるようになります。たとえば、強制的なダーク化を無効化できます。いくつかの例で使い方を示します。
div { color-scheme: light }
これは、div 要素の color-scheme を強制的にダーク以外にします。
div { color-scheme: only light }
これは、上の例と同じく、要素の color-scheme
をライトに保ち、ユーザー エージェントによる強制ダーク化を無効にします。
document.adoptedStyleSheets の変更が可能に
仕様に従い、document.adoptedStyleSheets
プロパティの変更が可能になります 。これにより、push()
や pop()
などの操作ができるようになります。これまでの adoptedStyleSheets
の実装は扱いにくく、たとえばシートを追加する場合、配列全体を代入し直さなければなりませんでした。
document.adoptedStyleSheets = [...adoptedStyleSheets, newSheet];
新しい実装では、同じ操作を次のように行うことができます。
document.adoptedStyleSheets.push(newSheet);
ハイ ダイナミック レンジ カラーのメディアクエリ
Chrome で CSS メディアクエリ 'dynamic-range'
と 'video-dynamic-range'
がサポートされ、現在のディスプレイ デバイスの HDR サポート状況を検出 できるようになります。有効な値は、'standard'
と 'high'
です。このクエリを使うと、ページで CSS ルールを切り替えたり、Window.matchMedia()
を使って変更に対応したりできます。
ポップアップ、タブ、ウィンドウのための新たな window.open() の動作
仕様の更新に伴い、このバージョンの Chrome では window.open()
で新しいウィンドウやタブを開くかどうかを指定 できるようになります。次の例に新しい構文を示します。1 つ目は、ポップアップ ウィンドウを開きます。2 つ目は、新しいタブまたはウィンドウを開きます。
const popup = window.open('_blank','','popup=1');
const tab = window.open('_blank','','popup=0');
また、window.statusbar.visible
が正しい値を返すようになります。具体的には、ポップアップでは false
を、タブやウィンドウでは true
を返します。
Private Network Access なサブリソースに Preflight リクエスト
サブリソースに対するプライベート ネットワーク リクエストの前に CORS Preflight リクエストが送られ 、対象サーバーから明示的なパーミッションを求めるようになります。プライベート ネットワーク リクエストとは、パブリックなウェブサイトからプライベート IP アドレスや localhost へのリクエスト、またはプライベートなウェブサイト(イントラネットなど)から localhost へのリクエストを指します。プリフライト リクエストを送ることで、ルーターなどのプライベート ネットワーク デバイスに対する Cross-Site Request Forgery (CSRF) 攻撃のリスクを緩和できます。多くの場合、プライベート ネットワーク デバイスはこのような脅威から保護されていません。
window と worker の structuredClone() メソッド
window と worker が、オブジェクトをディープコピーする structuredClone()
メソッドをサポートします。ディープコピーでは、オブジェクトのプロパティがコピーされますが、その際に別のオブジェクトへの参照を見つけると、自身を再帰的に呼び出してそのオブジェクトもコピーします。これにより、2 つのコードで意図せずにオブジェクトが共有され、知らない間にお互いの状態を変更してしまうことがなくなります。ディープコピーの説明や使い方については、structuredClone による JavaScript のディープコピー をご覧ください。
WebAuthn minPinLength 拡張機能
Chrome で、Web Authentication を通して CTAP 2.1 minPinLength 拡張機能 が公開されるようになります。これにより、あらかじめセキュリティ キーが構成されているサイトで、認証システムに設定された最小 PIN 長を知ることができるようになります。
インストールした PC ウェブアプリ向けのウィンドウ コントロール オーバーレイ
インストールした PC ウェブアプリでウィンドウ コントロール オーバーレイ が有効になっている場合、アプリのクライアント領域が拡張され、タイトルバー領域を含むウィンドウ全体を覆います。そのため、ウィンドウ コントロール ボタン(閉じる、最大化 / 復元、最小化)はクライアント領域の上に重なって表示されます。ウェブ デベロッパーは、ウィンドウ コントロール オーバーレイを除くウィンドウ全体の描画と入力ハンドリングをする必要があります。この機能を使うと、デベロッパーはインストールされた PC ウェブアプリを OS のアプリのように見せることができます。
WritableStream コントローラーの AbortSignal
WritableStreamDefaultController
が signal プロパティをサポート します。このプロパティは、必要に応じて WritableStream
操作を停止できる AbortSignal
のインスタンスを返します。ストリーム API では、データ ストリームの作成、構成、使用のためのユビキタスで相互運用可能なプリミティブが提供されます。この変更により、ライターからのリクエストがあったときに、下層のシンクが継続中の書き込み操作を即座に中断したりクローズしたりできるようになります。これまでは、writer.abort()
が呼び出されても、時間がかかる書き込み操作が完了してからでないとストリームを中断できませんでした。この変更により、書き込みを即座に中断できるようになります。この機能は、JavaScript で作成したストリームだけでなく、プラットフォームが提供する WebTransport
などのストリームでも利用できます。
サポートの終了と機能の削除
このバージョンの Chrome では、以下のサポートの終了と機能の削除が行われます。現在サポートが終了している機能 と以前に削除された機能 のリストは、ChromeStatus.com をご覧ください。
WebRTC での SDES 鍵交換の削除
2013 年以降、WebRTC の SDES 鍵交換メカニズムは、関連する IETF 標準で使用禁止と宣言されています。昨年には、Chrome での使用も大幅に減少しました。SDES が削除される のは、これがセキュリティの問題になっているためです。Javascript にセッションキーが公開されるので、ネゴシエーションの交換にアクセスできるエンティティや Javascript を侵害できるエンティティが、その接続で送信されるメディアを復号化できることになります。
Reviewed by Eiji Kitamura - Developer Relations Team
参加企業一覧(アルファベット順) CogSmart : 頭部 MRI 画像などを利用した脳健康測定、BrainSuite プログラムを通じて、「認知症にならない健康脳づくり」「生涯健康脳」の社会的な普及を目指しているヘルスケア サービス (Healthcare / Brain)
Hubble : 契約書の管理・共有をスマートにするリーガルテック SaaS (Legal Tech)
Latona : IoT やエッジコンピューティングの技術を使ったビジネス プラットフォームを開発し、企業に提供することで、ワークプロセスの自動化・生産性の向上を目指しているサービス (AI, ML)
NearMe : タクシーをシェアしてお得にドアツードア移動できる「相乗り」サービス。NearMe(ニアミー)は、独自の AI によりルーティングを最適化したスマートシャトルなどを展開し、リアルタイムの位置情報を活用して地域活性化に貢献する “瞬間マッチング” プラットフォーム作りを目指している。(Mobility as a Service, Sharing Economy)
PocketMarche : 全国の農家・漁師と直接やり取りしながら旬の食材を購入できる産直アプリ。生産者や地域と継続してつながるふるさと納税サービス。(EC, Marketplace)
Study Valley : 来年度から必修化される探究学習を効率的に行えるようにし、また社会との接点を創出する学習プラットフォーム (Ed Tech)
Tutorial : PC 端末にインストールせず、いつでもどこでも利用できる、クラウド型 RPA Robotic Crowd を提供 (Robotics)
unerry : 月 200 億件超の位置情報ビッグデータを扱う AI プラットフォームを開発・運営 (Geo Location AI)
今後の流れ 今後 3 か月に渡って、社会課題解決に特化したセッションをはじめ、機械学習などのテクノロジーに関するセッション、世界の外部メンターや Google 社員によるオンライン メンタリングなどを提供していきます。
プログラムについての詳細は、Google for Startups のページをご参照ください。
Google は、2 月 21 日より、社会課題をテクノロジーで解決に導くスタートアップを対象とした 3 か月集中型のプログラム 「Google for Startups Accelerator Class 4 」を実施します。 このプログラムは Google による技術、組織運営など幅広い分野にわたるトレーニングや個別のメンターシップを提供し、参加企業のさらなる成長を支援します。昨年 9 月 より募集を開始し、多くの素晴らしい目標を持ったスタートアップにご応募を頂き、厳正な選考の結果、本プログラムに下記 8 社のスタートアップが参加します。
参加企業一覧(アルファベット順) CogSmart : 頭部 MRI 画像などを利用した脳健康測定、BrainSuite プログラムを通じて、「認知症にならない健康脳づくり」「生涯健康脳」の社会的な普及を目指しているヘルスケア サービス (Healthcare / Brain)
Hubble : 契約書の管理・共有をスマートにするリーガルテック SaaS (Legal Tech)
Latona : IoT やエッジコンピューティングの技術を使ったビジネス プラットフォームを開発し、企業に提供することで、ワークプロセスの自動化・生産性の向上を目指しているサービス (AI, ML)
NearMe : タクシーをシェアしてお得にドアツードア移動できる「相乗り」サービス。NearMe(ニアミー)は、独自の AI によりルーティングを最適化したスマートシャトルなどを展開し、リアルタイムの位置情報を活用して地域活性化に貢献する “瞬間マッチング” プラットフォーム作りを目指している。(Mobility as a Service, Sharing Economy)
PocketMarche : 全国の農家・漁師と直接やり取りしながら旬の食材を購入できる産直アプリ。生産者や地域と継続してつながるふるさと納税サービス。(EC, Marketplace)
Study Valley : 来年度から必修化される探究学習を効率的に行えるようにし、また社会との接点を創出する学習プラットフォーム (Ed Tech)
Tutorial : PC 端末にインストールせず、いつでもどこでも利用できる、クラウド型 RPA Robotic Crowd を提供 (Robotics)
unerry : 月 200 億件超の位置情報ビッグデータを扱う AI プラットフォームを開発・運営 (Geo Location AI)
今後の流れ 今後 3 か月に渡って、社会課題解決に特化したセッションをはじめ、機械学習などのテクノロジーに関するセッション、世界の外部メンターや Google 社員によるオンライン メンタリングなどを提供していきます。
プログラムについての詳細は、Google for Startups のページをご参照ください。
ブラウザをタブグループ で整理している方でも、ウィンドウに名前を付けている 方でも、タブ検索 やその他の方法を使っている方でも、目的のタブにたどり着くためにたくさんの機能を使うことができます。速さと好奇心 の今回の投稿では、どのウィンドウが表示されているかを利用してどのように Chrome を最適化したかについて説明します。その結果、起動が 25.8% 速くなり、クラッシュは 4.5% 減少しました。
背景
Chrome では、数年間にわたるユーザー エクスペリエンス改善の取り組みの中で、バックグラウンド タブの優先度を下げてきました
[1] 。たとえばバックグラウンド タブでは、JavaScript の速度を制限したり、ウェブ コンテンツの
レンダリング を抑制したりしています。これにより、CPU や GPU、メモリの使用量が減少し、実際にユーザーに表示されるフォアグラウンド タブで利用できるメモリや CPU、GPU が増加します。一方で、このロジックの対象になるのは、ウィンドウでフォーカスが当たっていないタブ、最小化されているウィンドウ、画面外のウィンドウのみです。
実験を通して、Chrome のウィンドウの 20% 近くが、完全に別のウィンドウのうしろに隠れている(オクルージョンされている)ことがわかりました。私たちは、こういったオクルージョンされているウィンドウをバックグラウンド タブと同じように扱うことができれば、パフォーマンスは大幅に向上するに違いないという仮説を立てました。そこで、今から 3 年ほど前に、各 Chrome ウィンドウのオクルージョン状態をリアルタイムに追跡し、オクルージョン対象のウィンドウのタブの優先度を下げるというプロジェクトを始めました。このプロジェクトを行うには、ユーザーの画面に表示されている Chrome 以外のウィンドウのネイティブ位置を知る必要があります。そこで、プロジェクトをネイティブ ウィンドウ オクルージョンと名付けました(位置情報は、オクルージョンの計算に使った後、即座に破棄しています)。
ネイティブ ウィンドウ オクルージョンの計算
Windows OS では、あるウィンドウが完全に他のウィンドウに隠れているかどうかを直接的に知る方法は提供されていません。そのため、Chrome は独自に検知する必要があります。他の Chrome ウィンドウだけを考えればよいのなら、これは簡単です。Chrome のウィンドウがどこにあるかはわかっているからです。しかしここでは、ユーザーが開いているかもしれない Chrome 以外のウィンドウをすべて考慮し、Chrome
のウィンドウのオクルージョン状態が変わるかもしれないイベントをすべて検知する必要があります。
どの Chrome ウィンドウがオクルージョン対象かを継続的に追跡するには、主に 2 つのことが必要です。1 つ目はオクルージョンの計算です。ここでは、デスクトップで開いているウィンドウについて
z-order 順(前から後)に反復処理を行い、そのウィンドウが Chrome ウィンドウを完全に隠しているかどうかを確認します。2 つ目は、そのオクルージョンの計算をいつ行うかを決めることです。
オクルージョンの計算
理論的には、どのウィンドウがオクルージョン対象かを判断するのは簡単です。しかし実際には、マルチモニタ環境 、仮想デスクトップ 、透過ウィンドウ 、クロークされたウィンドウ など、複雑な要素がたくさん存在します。この点には、慎重に対処しなければなりません。実際にユーザーに表示されているウィンドウをオクルージョン対象と判断してしまうと、ウェブ コンテンツが表示されるはずの場所が白くなってしまうからです。また、オクルージョンの計算をしている間に UI スレッドをブロックすることは、Chrome の応答性とユーザー エクスペリエンスが悪化する可能性があるため、避けなければなりません。そこで、次のようにして別のスレッドでオクルージョンの計算をしています。
最小化されたウィンドウは表示されないので、無視する。
別の仮想デスクトップ上にある Chrome ウィンドウはオクルージョン対象とマークする。
ディスプレイのモニターを組み合わせた仮想画面の矩形を計算する。これがオクルージョンされていない画面の矩形になります。
デスクトップで開いているウィンドウについて、前から後の順番に反復処理を行う。見えないウィンドウ、透明なウィンドウ、フローティング ウィンドウ(スタイルが WS_EX_TOOLBAR であるウィンドウ)、クロークされたウィンドウ、他の仮想デスクトップのウィンドウ、非矩形ウィンドウ [2] などは無視する。重要な点として、このようなウィンドウを無視すると、オクルージョン対象のウィンドウの一部が表示されているものと見なされる(偽陰性)可能性がありますが、表示されているウィンドウがオクルージョン対象と見なされる(偽陽性)ことはありません。各ウィンドウについて以下を行います。
オクルージョンされていない画面の矩形から対象のウィンドウの領域を引く。
対象のウィンドウが Chrome ウィンドウである場合は、その領域がオクルージョンされていない領域と重なっているかどうかを確認する。重なっていない場合、その Chrome ウィンドウは前にあるウィンドウによって完全に覆われているため、オクルージョン対象になります。
すべての Chrome ウィンドウの計算が終わるまで繰り返す。
この時点で、オクルージョン対象とマークされていない Chrome ウィンドウは表示されていることになり、オクルージョンの計算は終了する。ここで、UI スレッドにタスクをポストし、Chrome ウィンドウの表示状態を更新します。
この操作は、すべて同期ロックを使わずに行われるので、オクルージョンの計算は UI スレッドに最低限の影響しか与えない。たとえば、UI スレッドをブロックしてユーザー エクスペリエンスを悪化させることはありません。
実装についてさらに詳しく知りたい方は、ドキュメント をご覧ください。
オクルージョンの計算タイミングの決定
オクルージョンの計算をし続けると、Chrome のパフォーマンスが低下することになるので、それは避けたいことです。つまり、ウィンドウが表示対象またはオクルージョン対象になるタイミングを検知する必要があります。ありがたいことに Windows では、ウィンドウの移動、リサイズ、最大化、最小化などのさまざまなシステム イベントをトラッキングできます。オクルージョン計算スレッドは、これらのイベントを追跡したいことを Windows に伝えます。そしてイベントが通知されると、イベントを精査して新たにオクルージョン計算を行うかどうかを決定します。非常に短い時間内に複数のイベントを受け取る可能性があるため、オクルージョンの計算は 16 ミリ秒に 1 回を超える頻度では行いません。この時間は、フレームレートが 1 秒あたり 60 フレーム(fps)である場合に 1 フレームが表示される時間に対応します。
リッスンするイベントは、ウィンドウのアクティブ化や非アクティブ化、ウィンドウの移動やリサイズ、ユーザーの画面ロックやロック解除、モニターの電源オフなどです。オクルージョンの計算は必要以上に行いたくありませんが、ウィンドウが表示されるイベントを見逃すわけにはいきません。見逃してしまうと、ウェブ
コンテンツが表示されるはずの場所が白くなってしまうからです。これは絶妙なバランスです
[3] 。
リッスンするイベントは、Chrome ウィンドウがオクルージョンされるかどうかに関わるものです。たとえば、マウスを動かすとたくさんのイベントが発生し、カーソルも点滅するたびにイベントを発行しています。そういったイベントはウィンドウ
オブジェクトとは関係ないので、無視します。また、ツールチップの表示によってオクルージョンの計算がトリガーされることはないので、大半のポップアップ ウィンドウのイベントも無視します。
オクルージョン スレッドは、さまざまな Windows イベントを検知したいことを Windows に伝えます。UI スレッドは、主要な状態変化(モニターの電源オフ、ユーザーによる画面ロック)が発生した場合にそれを検知したいことを
Windows に伝えます。
結果
この機能は、効果を測定する
実験 と合わせて開発され、2020 年 10 月に M86 リリースの一部としてすべての Chrome Windows ユーザーにロールアウトされました。指標から、この機能をオンにした場合にパフォーマンスが大幅に改善されることがわかります。
起動時間と初回入力までの遅延時間が改善したのは、Chrome が起動時に 2 つ以上の全画面ウィンドウを復元する場合、いずれかのウィンドウがオクルージョンされる可能性が高いためです。Chrome はそのウィンドウに関する大半の作業を省略できるので、より重要なフォアグラウンド ウィンドウのためにリソースを節約できます。
すべての統計情報の出典 : Chrome クライアントから匿名で集計した実データ 。
[1] 音声や動画を再生しているタブなど、一部のタブは優先度が下がりません。
[2] 非矩形ウィンドウの計算は複雑です。これはあまり使われないと考えられていましたが、Windows 7 のデフォルト テーマの特性上、Windows 7 では一般的に使われています。
[3] 最初にこれをリリースしたとき、Citrix で別のユーザーが画面をロックすると、Windows が現在のセッションではないセッションの変化通知を送信してくるため、白いウィンドウが表示されることがすぐにわかりました。詳細はこちら をご覧ください。
Reviewed by
Eiji Kitamura - Developer Relations Team
この記事は Chrome デベロッパー、David Bienvenu による Chromium Blog の記事 "Chrome on Windows performance improvements and the journey of Native Window Occlusion " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
ブラウザをタブグループ で整理している方でも、ウィンドウに名前を付けている 方でも、タブ検索 やその他の方法を使っている方でも、目的のタブにたどり着くためにたくさんの機能を使うことができます。速さと好奇心 の今回の投稿では、どのウィンドウが表示されているかを利用してどのように Chrome を最適化したかについて説明します。その結果、起動が 25.8% 速くなり、クラッシュは 4.5% 減少しました。
背景
Chrome では、数年間にわたるユーザー エクスペリエンス改善の取り組みの中で、バックグラウンド タブの優先度を下げてきました [1] 。たとえばバックグラウンド タブでは、JavaScript の速度を制限したり、ウェブ コンテンツのレンダリング を抑制したりしています。これにより、CPU や GPU、メモリの使用量が減少し、実際にユーザーに表示されるフォアグラウンド タブで利用できるメモリや CPU、GPU が増加します。一方で、このロジックの対象になるのは、ウィンドウでフォーカスが当たっていないタブ、最小化されているウィンドウ、画面外のウィンドウのみです。
実験を通して、Chrome のウィンドウの 20% 近くが、完全に別のウィンドウのうしろに隠れている(オクルージョンされている)ことがわかりました。私たちは、こういったオクルージョンされているウィンドウをバックグラウンド タブと同じように扱うことができれば、パフォーマンスは大幅に向上するに違いないという仮説を立てました。そこで、今から 3 年ほど前に、各 Chrome ウィンドウのオクルージョン状態をリアルタイムに追跡し、オクルージョン対象のウィンドウのタブの優先度を下げるというプロジェクトを始めました。このプロジェクトを行うには、ユーザーの画面に表示されている Chrome 以外のウィンドウのネイティブ位置を知る必要があります。そこで、プロジェクトをネイティブ ウィンドウ オクルージョンと名付けました(位置情報は、オクルージョンの計算に使った後、即座に破棄しています)。
ネイティブ ウィンドウ オクルージョンの計算
Windows OS では、あるウィンドウが完全に他のウィンドウに隠れているかどうかを直接的に知る方法は提供されていません。そのため、Chrome は独自に検知する必要があります。他の Chrome ウィンドウだけを考えればよいのなら、これは簡単です。Chrome のウィンドウがどこにあるかはわかっているからです。しかしここでは、ユーザーが開いているかもしれない Chrome 以外のウィンドウをすべて考慮し、Chrome
のウィンドウのオクルージョン状態が変わるかもしれないイベントをすべて検知する必要があります。
どの Chrome ウィンドウがオクルージョン対象かを継続的に追跡するには、主に 2 つのことが必要です。1 つ目はオクルージョンの計算です。ここでは、デスクトップで開いているウィンドウについて z-order 順(前から後)に反復処理を行い、そのウィンドウが Chrome ウィンドウを完全に隠しているかどうかを確認します。2 つ目は、そのオクルージョンの計算をいつ行うかを決めることです。
オクルージョンの計算
理論的には、どのウィンドウがオクルージョン対象かを判断するのは簡単です。しかし実際には、マルチモニタ環境 、仮想デスクトップ 、透過ウィンドウ 、クロークされたウィンドウ など、複雑な要素がたくさん存在します。この点には、慎重に対処しなければなりません。実際にユーザーに表示されているウィンドウをオクルージョン対象と判断してしまうと、ウェブ コンテンツが表示されるはずの場所が白くなってしまうからです。また、オクルージョンの計算をしている間に UI スレッドをブロックすることは、Chrome の応答性とユーザー エクスペリエンスが悪化する可能性があるため、避けなければなりません。そこで、次のようにして別のスレッドでオクルージョンの計算をしています。
最小化されたウィンドウは表示されないので、無視する。
別の仮想デスクトップ上にある Chrome ウィンドウはオクルージョン対象とマークする。
ディスプレイのモニターを組み合わせた仮想画面の矩形を計算する。これがオクルージョンされていない画面の矩形になります。
デスクトップで開いているウィンドウについて、前から後の順番に反復処理を行う。見えないウィンドウ、透明なウィンドウ、フローティング ウィンドウ(スタイルが WS_EX_TOOLBAR であるウィンドウ)、クロークされたウィンドウ、他の仮想デスクトップのウィンドウ、非矩形ウィンドウ [2] などは無視する。重要な点として、このようなウィンドウを無視すると、オクルージョン対象のウィンドウの一部が表示されているものと見なされる(偽陰性)可能性がありますが、表示されているウィンドウがオクルージョン対象と見なされる(偽陽性)ことはありません。各ウィンドウについて以下を行います。
オクルージョンされていない画面の矩形から対象のウィンドウの領域を引く。
対象のウィンドウが Chrome ウィンドウである場合は、その領域がオクルージョンされていない領域と重なっているかどうかを確認する。重なっていない場合、その Chrome ウィンドウは前にあるウィンドウによって完全に覆われているため、オクルージョン対象になります。
すべての Chrome ウィンドウの計算が終わるまで繰り返す。
この時点で、オクルージョン対象とマークされていない Chrome ウィンドウは表示されていることになり、オクルージョンの計算は終了する。ここで、UI スレッドにタスクをポストし、Chrome ウィンドウの表示状態を更新します。
この操作は、すべて同期ロックを使わずに行われるので、オクルージョンの計算は UI スレッドに最低限の影響しか与えない。たとえば、UI スレッドをブロックしてユーザー エクスペリエンスを悪化させることはありません。
実装についてさらに詳しく知りたい方は、ドキュメント をご覧ください。
オクルージョンの計算タイミングの決定
オクルージョンの計算をし続けると、Chrome のパフォーマンスが低下することになるので、それは避けたいことです。つまり、ウィンドウが表示対象またはオクルージョン対象になるタイミングを検知する必要があります。ありがたいことに Windows では、ウィンドウの移動、リサイズ、最大化、最小化などのさまざまなシステム イベントをトラッキングできます。オクルージョン計算スレッドは、これらのイベントを追跡したいことを Windows に伝えます。そしてイベントが通知されると、イベントを精査して新たにオクルージョン計算を行うかどうかを決定します。非常に短い時間内に複数のイベントを受け取る可能性があるため、オクルージョンの計算は 16 ミリ秒に 1 回を超える頻度では行いません。この時間は、フレームレートが 1 秒あたり 60 フレーム(fps)である場合に 1 フレームが表示される時間に対応します。
リッスンするイベントは、ウィンドウのアクティブ化や非アクティブ化、ウィンドウの移動やリサイズ、ユーザーの画面ロックやロック解除、モニターの電源オフなどです。オクルージョンの計算は必要以上に行いたくありませんが、ウィンドウが表示されるイベントを見逃すわけにはいきません。見逃してしまうと、ウェブ
コンテンツが表示されるはずの場所が白くなってしまうからです。これは絶妙なバランスです
[3] 。
リッスンするイベントは、Chrome ウィンドウがオクルージョンされるかどうかに関わるものです。たとえば、マウスを動かすとたくさんのイベントが発生し、カーソルも点滅するたびにイベントを発行しています。そういったイベントはウィンドウ
オブジェクトとは関係ないので、無視します。また、ツールチップの表示によってオクルージョンの計算がトリガーされることはないので、大半のポップアップ ウィンドウのイベントも無視します。
オクルージョン スレッドは、さまざまな Windows イベントを検知したいことを Windows に伝えます。UI スレッドは、主要な状態変化(モニターの電源オフ、ユーザーによる画面ロック)が発生した場合にそれを検知したいことを
Windows に伝えます。
結果
この機能は、効果を測定する
実験 と合わせて開発され、2020 年 10 月に M86 リリースの一部としてすべての Chrome Windows ユーザーにロールアウトされました。指標から、この機能をオンにした場合にパフォーマンスが大幅に改善されることがわかります。
起動時間と初回入力までの遅延時間が改善したのは、Chrome が起動時に 2 つ以上の全画面ウィンドウを復元する場合、いずれかのウィンドウがオクルージョンされる可能性が高いためです。Chrome はそのウィンドウに関する大半の作業を省略できるので、より重要なフォアグラウンド ウィンドウのためにリソースを節約できます。
すべての統計情報の出典 : Chrome クライアントから匿名で集計した実データ 。
[1] 音声や動画を再生しているタブなど、一部のタブは優先度が下がりません。
[2] 非矩形ウィンドウの計算は複雑です。これはあまり使われないと考えられていましたが、Windows 7 のデフォルト テーマの特性上、Windows 7 では一般的に使われています。
[3] 最初にこれをリリースしたとき、Citrix で別のユーザーが画面をロックすると、Windows が現在のセッションではないセッションの変化通知を送信してくるため、白いウィンドウが表示されることがすぐにわかりました。詳細はこちら をご覧ください。
Reviewed by Eiji Kitamura - Developer Relations Team