この記事は Developer Relations Engineer の Chris Arriola による Google Cloud Blog の記事 "A video guide to reactive programming with Google Maps Platform" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。 ...

この記事は Developer Relations Engineer の Chris Arriola による Google Cloud Blog の記事 "A video guide to reactive programming with Google Maps Platform" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

Google Maps Platform Android SDK は、非同期操作を管理するコードを記述するのに役立つ、リアクティブ プログラミングの拡張機能をサポートしています。

Google Maps Platform を使ってリアクティブでレスポンシブなマッピング アプリケーションを構築する

ユーザーのタッチイベントから、ネットワーク呼び出し完了の待機やプッシュ通知の受け取りに至るまで、モバイルアプリでは非同期イベントはあらゆるタイミングで発生する可能性があります。こうしたイベントを考慮しながら他の非同期イベントと組み合わせてコードを記述するのは、アプリ デベロッパーにとって手間のかかる作業です。リアクティブ プログラミングを使えば個々のイベントのコールバックを渡す必要がなくなるため、非同期イベントを扱うプロセスを簡素化できます。リアクティブ プログラミングでは、イベントはストリーミングとしてモデル化され、アイテムが 1 つずつ処理されます。


リアクティブなコード記述には、Kotlin Flows と RxJava の 2 つのライブラリを使用できます。次の 2 つの動画で、それぞれのライブラリの使い方を説明します。

Kotlin を使ってリアクティブでレスポンシブなアプリケーションを作成する

Kotlin でコルーチンと Flow を使用する場合は、KTX ライブラリを使えば Kotlin Flow でイベントを受け取ることができます。Maps KTX ライブラリには Kotlin Flow オブジェクトを返す拡張機能が含まれているため、リアクティブにイベントをリッスンできます。Kotlin Flows では、アクティビティを一時停止して 1 個の値を返すのではなく、時間の経過とともに複数の値を 1 個ずつ返すことができます。例えばカメラのように時間の経過とともに変化するイベントも、Flow を使って受け取ることができます。アプリで Kotlin Flow を使うには、build.gradle ファイルの依存関係セクションに Maps KTX ライブラリを追加します。


RxJava で Android 向けにリアクティブな地図を作る

一般に広く使用されている Android ライブラリ RxJava を Google Maps Platform の SDK に統合します。RxJava はリアクティブ拡張機能を Java で実行するもので、観測可能なシーケンスを使って非同期かつイベントベースのプログラムを記述するためのライブラリです。RxJava を使えば、連鎖的に発生する変化をコールバック ベースの非同期コードで記述できます。この仕組みと、RxJava のその他の使い方を 3 つ目の動画で説明します。


今回の 3 部構成の YouTube 動画シリーズでリアクティブ プログラミングの考え方について理解を深め、レスポンシブでリアクティブなモバイルアプリの作成にお役立ていただければ幸いです。役に立つ動画のアイデアがあれば、私たちの動画のコメント欄に投稿してください(どの動画でもかまいません)。最新情報、チュートリアル、お客様事例などをお届けする Google Maps Platform の YouTube チャンネルに、ぜひご登録ください。

Google Maps Platform に関する詳しい情報はこちらをご覧ください。ご質問やフィードバックはページ右上の「お問い合わせ」より承っております。


この記事は 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 ストアでダウンロードできます。 

この記事は 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 圧縮後)。

2 つの国立公園の絵文字。片方は明瞭でもう片方はぼやけている。棒グラフは、ビットマップ フォントと COLRv1 フォントの Noto Emoji のバイナリサイズ(約 9MB と 1.85MB)を比較している。
明瞭な 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

この記事は Nick Birine による Google Ads Developer Blog の記事 "Warning: deprecation and sunset of Feeds" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。 ...
この記事は Nick Birine による Google Ads Developer Blog の記事 "Warning: deprecation and sunset of Feeds" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

以前 お知らせしたように、フィードをアセットに移行する作業を行っており、アカウントの自動移行も始まっています。まだ以前のフィードをお使いの方は、やがて API 呼び出しが失敗するようになります。なるべく早めにアセットに移行してください。

現在のステータスと自動移行に関する主な日付は、下記の表をご参照ください。
フィードのタイプ サブタイプ ステータス 自動移行の日付
拡張機能 プロモーション 自動移行を実施中 2021 年 10 月 20 日 *
拡張機能 コールアウト サイトリンク 構造化スニペット 自動移行を実施中 2021 年 10 月 20 日 *
拡張機能 アプリ コール ホテル コールアウト 価格 サポート終了 2022 年 2 月 15 日
拡張機能 イメージ 2022 年半ばごろに移行準備が整う予定 2022 年 9 月
動的検索広告 ページ フィード サポート終了 2022 年 4 月 27 日
動的リマーケティング 教育 サポート終了 2022 年 4 月 27 日
動的リマーケティング カスタム フライト ホテル 不動産 旅行 地域 求人 2022 年 4 月にサポート終了予定 2022 年 10 月 5 日
* 2022 年 1 月 10 日まで延期

イメージ拡張機能は 2022 年 2 月に移行される予定ではなかったでしょうか?
当初の計画ではそうでしたが、イメージ拡張機能の移行は 2022 年 9 月に延期されています。

移行までに、何をする必要がありますか?
できる限り早急に新しいアセットタイプをサポートする必要があります。

フィード ID からアセット ID への移行をトレースするには、手動で移行する必要があります。自動移行によってこの関係を取得する方法はありません。

詳しくは、以下の移行ガイドをご覧ください。 自動移行が行われるとどうなりますか?
移行されたアカウントでは、フィードベースのエンティティに対する変更呼び出しが拒否されます。以前のフィードベースのエンティティに対する統計情報のレポート機能は、近いうちに削除される予定です。前述の移行ガイドで説明されているように、アセットを対象とした同等のレポートデータが提供される予定です。

自動移行からオプトアウトすることはできますか?
できません。初回の自動移行はオプトアウトを提供しましたが、今後の移行にてオプトアウトはご利用いただけません。

ご不明な点などございましたら、フォーラムよりお問合せください。




Reviewed by Thanet Knack Praneenararat - Ads Developer Relations Team

この記事は Anash P. Oommen による Google Ads Developer Blog の記事 "Upcoming changes to Simulations in the Google Ads API and Bid Landscapes in the AdWords API" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

現在、Google Ads APIAdWords API で、SimulationModificationMethod = DEFAULT の広告グループのシミュレーション計算方法を変更する作業を行っています。

この記事は Anash P. Oommen による Google Ads Developer Blog の記事 "Upcoming changes to Simulations in the Google Ads API and Bid Landscapes in the AdWords API" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

現在、Google Ads APIAdWords API で、SimulationModificationMethod = DEFAULT の広告グループのシミュレーション計算方法を変更する作業を行っています。

変更事項

優先されるキーワードの入札単価がある広告グループに対しては、広告グループのデフォルト入札単価のさまざまな値ごとに異なる推定トラフィックを提供します。現在は、優先される入札単価があるすべてのキーワードが、この推定値から除外されます。そのため、推定トラフィックが予想より少なくなります。

2022 年 1 月 17 日の週より、広告グループのシミュレーション計算方法を変更し、デフォルト入札を使っているキーワードと、優先される入札があるキーワードの両方の推定を含めるようにしました。さらに、シミュレーションにおいて、広告グループのデフォルト入札のみが変わり、優先されるキーワード入札はすべて同じであると仮定します。この内容は、Google Ads API の AdGroupSimulationService サービスに含まれる GetAdGroupSimulation メソッドや、AdWords API の DataService サービスに含まれる getAdGroupBidLandscape メソッドや queryAdGroupBidLandscape メソッドが返すシミュレーションに影響する可能性があります。

必要な対応

この機能をお使いの方は、上記のメソッドが返す結果が変わってもコードが引き続き機能することを確認することをお勧めします。

質問がある方は、Google Ads API フォーラムでお知らせください。

お知らせ : Google Ads(AdWords)API のフィードバックをお送りください。2021 AdWords API と Google Ads API 年次アンケートへの回答をお願いします。



Reviewed by Thanet Knack Praneenararat - Ads Developer Relations Team

この記事は David Wihl による Google Ads Developer Blog の記事 "Shared budget for Smart Shopping Campaigns" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。 ...
この記事は David Wihl による Google Ads Developer Blog の記事 "Shared budget for Smart Shopping Campaigns" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

 2022 年 2 月 15 日より、すべての(既存と今後の)スマート ショッピング キャンペーン(SSC)で、共有予算タイプが使われるようになります。共有と言っても、設定サれた予算は SSC のみで使用され、共有でない標準のキャンペーン予算と同じように動作します。共有予算に新規キャンペーンを追加することはできません。この変更によってキャンペーンのパフォーマンスが影響を受けることはありません。レポートとクエリでは、既存と今後の SSC 予算は explicitly_shared = true(AdWords API では isExplicitlyShared)として返されます。

注 : AdWords API は、2022 年 4 月 27 日に提供終了となる予定です。デベロッパーの皆さんは、それまでに Google Ads API に移行する必要があります。

ご質問やさらにサポートが必要なことがありましたら、フォーラムからご連絡ください。


Reviewed by Thanet Knack Praneenararat - Ads Developer Relations Team

Google は、2 月 21 日より、社会課題をテクノロジーで解決に導くスタートアップを対象とした 3 か月集中型のプログラム 「Google for Startups Accelerator Class 4」を実施します。 このプログラムは Google による技術、組織運営など幅広い分野にわたるトレーニングや個別のメンターシップを提供し、参加企業のさらなる成長を支援します。昨年 9 月 より募集を開始し、多くの素晴らしい目標を持ったスタートアップにご応募を頂き、厳正な選考の結果、本プログラムに下記 8 社のスタートアップが参加します。


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 デベロッパー、David Bienvenu による Chromium Blog の記事 "Chrome on Windows performance improvements and the journey of Native Window Occlusion" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

この記事は 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 の応答性とユーザー エクスペリエンスが悪化する可能性があるため、避けなければなりません。そこで、次のようにして別のスレッドでオクルージョンの計算をしています。
  1. 最小化されたウィンドウは表示されないので、無視する。
  2. 別の仮想デスクトップ上にある Chrome ウィンドウはオクルージョン対象とマークする。
  3. ディスプレイのモニターを組み合わせた仮想画面の矩形を計算する。これがオクルージョンされていない画面の矩形になります。
  4. デスクトップで開いているウィンドウについて、前から後の順番に反復処理を行う。見えないウィンドウ、透明なウィンドウ、フローティング ウィンドウ(スタイルが WS_EX_TOOLBAR であるウィンドウ)、クロークされたウィンドウ、他の仮想デスクトップのウィンドウ、非矩形ウィンドウ [2] などは無視する。重要な点として、このようなウィンドウを無視すると、オクルージョン対象のウィンドウの一部が表示されているものと見なされる(偽陰性)可能性がありますが、表示されているウィンドウがオクルージョン対象と見なされる(偽陽性)ことはありません。各ウィンドウについて以下を行います。
    • オクルージョンされていない画面の矩形から対象のウィンドウの領域を引く。
    • 対象のウィンドウが Chrome ウィンドウである場合は、その領域がオクルージョンされていない領域と重なっているかどうかを確認する。重なっていない場合、その Chrome ウィンドウは前にあるウィンドウによって完全に覆われているため、オクルージョン対象になります。
  5. すべての Chrome ウィンドウの計算が終わるまで繰り返す。
  6. この時点で、オクルージョン対象とマークされていない Chrome ウィンドウは表示されていることになり、オクルージョンの計算は終了する。ここで、UI スレッドにタスクをポストし、Chrome ウィンドウの表示状態を更新します。
  7. この操作は、すべて同期ロックを使わずに行われるので、オクルージョンの計算は UI スレッドに最低限の影響しか与えない。たとえば、UI スレッドをブロックしてユーザー エクスペリエンスを悪化させることはありません。
実装についてさらに詳しく知りたい方は、ドキュメントをご覧ください。


オクルージョンの計算タイミングの決定

オクルージョンの計算をし続けると、Chrome のパフォーマンスが低下することになるので、それは避けたいことです。つまり、ウィンドウが表示対象またはオクルージョン対象になるタイミングを検知する必要があります。ありがたいことに Windows では、ウィンドウの移動、リサイズ、最大化、最小化などのさまざまなシステム イベントをトラッキングできます。オクルージョン計算スレッドは、これらのイベントを追跡したいことを Windows に伝えます。そしてイベントが通知されると、イベントを精査して新たにオクルージョン計算を行うかどうかを決定します。非常に短い時間内に複数のイベントを受け取る可能性があるため、オクルージョンの計算は 16 ミリ秒に 1 回を超える頻度では行いません。この時間は、フレームレートが 1 秒あたり 60 フレーム(fps)である場合に 1 フレームが表示される時間に対応します。

リッスンするイベントは、ウィンドウのアクティブ化や非アクティブ化、ウィンドウの移動やリサイズ、ユーザーの画面ロックやロック解除、モニターの電源オフなどです。オクルージョンの計算は必要以上に行いたくありませんが、ウィンドウが表示されるイベントを見逃すわけにはいきません。見逃してしまうと、ウェブ コンテンツが表示されるはずの場所が白くなってしまうからです。これは絶妙なバランスです [3]

リッスンするイベントは、Chrome ウィンドウがオクルージョンされるかどうかに関わるものです。たとえば、マウスを動かすとたくさんのイベントが発生し、カーソルも点滅するたびにイベントを発行しています。そういったイベントはウィンドウ オブジェクトとは関係ないので、無視します。また、ツールチップの表示によってオクルージョンの計算がトリガーされることはないので、大半のポップアップ ウィンドウのイベントも無視します。

オクルージョン スレッドは、さまざまな Windows イベントを検知したいことを Windows に伝えます。UI スレッドは、主要な状態変化(モニターの電源オフ、ユーザーによる画面ロック)が発生した場合にそれを検知したいことを Windows に伝えます。





結果

この機能は、効果を測定する実験と合わせて開発され、2020 年 10 月に M86 リリースの一部としてすべての Chrome Windows ユーザーにロールアウトされました。指標から、この機能をオンにした場合にパフォーマンスが大幅に改善されることがわかります。
  • 起動時間が 8.5% から 25.8% 短縮
  • GPU メモリ使用量を 3.1% 削減
  • レンダラー全体の描画フレーム数を 20.4% 削減
  • レンダラーのクラッシュが発生したクライアントが 4.5% 減少
  • First Input Delay(初回入力までの遅延時間)が 3.0% 向上
  • First Contentful Paint(視覚コンテンツの初期表示時間)と Largest Contentful Paint(最大視覚コンテンツの表示時間)が 6.7% 向上
起動時間と初回入力までの遅延時間が改善したのは、Chrome が起動時に 2 つ以上の全画面ウィンドウを復元する場合、いずれかのウィンドウがオクルージョンされる可能性が高いためです。Chrome はそのウィンドウに関する大半の作業を省略できるので、より重要なフォアグラウンド ウィンドウのためにリソースを節約できます。

すべての統計情報の出典 : Chrome クライアントから匿名で集計した実データ
[1] 音声や動画を再生しているタブなど、一部のタブは優先度が下がりません。
[2] 非矩形ウィンドウの計算は複雑です。これはあまり使われないと考えられていましたが、Windows 7 のデフォルト テーマの特性上、Windows 7 では一般的に使われています。
[3] 最初にこれをリリースしたとき、Citrix で別のユーザーが画面をロックすると、Windows が現在のセッションではないセッションの変化通知を送信してくるため、白いウィンドウが表示されることがすぐにわかりました。詳細はこちらをご覧ください。

Reviewed by Eiji Kitamura - Developer Relations Team