Chrome DevTools のフル ユーザー補助ツリー

Johan Bay
Johan Bay

Chrome DevTools に完全なユーザー補助ツリーが導入され、デベロッパーはツリー全体の概要を簡単に把握できるようになります。この投稿では、このツリーの作成方法と、作業での使用方法について説明します。

アクセシビリティ ツリーとは何ですか?

スクリーン リーダーなどの支援技術は、Chromium のユーザー補助 API を使用してウェブ コンテンツを操作します。この API の基礎となるモデルは、ユーザー補助ツリーです。ツリーとは、支援技術が属性やプロパティをクエリしてアクションを実行できるユーザー補助オブジェクトのツリーです。ウェブ デベロッパーは、主に HTML の ARIA 属性などの DOM プロパティを使用して、アクセシビリティ ツリーの形成や操作を行います。

Chrome DevTools には、ユーザー補助ペインによって、支援技術に対してコンテンツがどのように公開されるかをデベロッパーが把握できる機能があります。具体的には、DOM ツリー ビューアでノードを選択すると、対応するユーザー補助ノードのプロパティがペインに表示されます。このペインには、ノードの祖先と直近の子も表示されます。

Chrome DevTools のユーザー補助ペイン。

ツリーはどのように作成されますか?

DevTools の新しい完全なツリービューについて説明する前に、ユーザー補助ツリーについて簡単に説明します。アクセシビリティ ツリーは DOM ツリーから派生したものです。構造はほぼ同じですが、スタイル設定のみに使用される <div> 要素など、意味的なコンテンツのないノードを削除するように簡素化されています。ツリーの各ノードには、ButtonHeading などのロールと、多くの場合、ARIA 属性から取得される名前またはノードのコンテンツから派生した名前があります。HTML ドキュメントを見ると、

<html>
<head>
  <title>How old are you?</title>
</head>
<body>
  <label for="age">Age</label>
  <input id="age" type="number" name="age" value="42">
  <div>
    <button>Back</button>
    <button>Next</button>
  </div>
</body>
</html>

Chromium のレンダラ(Blink)は、内部のユーザー補助ツリーを次のように取得します。

role='rootWebArea' focusable name='How old are you?'
  role='genericContainer' ignored
    role='genericContainer' ignored
      role='labelText'
        role='staticText' name='Age'
      role='spinButton' editable focusable name='Age' value='42'
        role='genericContainer' editable
          role='staticText' editable name='42'
      role='genericContainer'
        role='button' focusable name='Back'
          role='staticText' name='Back'
        role='button' focusable name='Next'
          role='staticText' name='Next'

この表現には、ロールが genericContainer の不要なノードが複数含まれています。これは、アクセシビリティ ツリーが DOM ツリーの簡素化された派生であるという上記の記述と矛盾しているように見えるかもしれませんが、ただし、これらのノードほとんどは内部ツリーにのみ存在し、支援技術には公開されません。DevTools はレンダラ プロセスから直接アクセシビリティ情報を収集するため、これは DevTools が処理するツリー表現です。

DevTools の完全なアクセシビリティ ツリー

新しい完全なアクセシビリティ ツリーは DOM ツリーと同期されているため、デベロッパーは 2 つのツリーを切り替えることができます。新しいツリーは、より探索しやすく、有用で、使いやすいものになる予定です。

ユーザー補助ツリーの仕組みを理解したところで、DevTools を使用して新しいツリービューを確認しましょう。タイトル、見出し、2 つのボタンを含む次の HTML ドキュメントを使用して、ツリーを表示します。

<!DOCTYPE html>
<title>Test</title>
<h1>Heading for example page</h1>
<div>
  <button>Back</button>
  <button>Next</button>
</div>

以前のツリービューでは、1 つのノードとその祖先のみを探索できました。

DevTools の以前のツリービュー。

新しいツリーを切り替えると、DOM ツリービューが置き換えられ、ページのアクセシビリティ ツリー全体が表示されます。

DevTools の新しいツリービュー。

遅延ツリーの作成

大規模なサイトでもツリーのパフォーマンスを維持するため、ツリーは探索時にフロントエンドで遅延作成されます。ノードがツリーで展開されると、Chrome DevTools Protocol(CDP)によってノードの子が取得され、ツリーが再構築されます。

大きなページの結果を示す新しいユーザー補助ツリー。

ライブ

新しいツリービューはライブで、レンダラでユーザー補助ツリーが変更されると動的に更新されます。これは、支援技術にツリーの変更を通知するのと同じ仕組みにフックし、それを使用して、更新されたノードを含む DevTools フロントエンドにイベントを出力します。実際には、CDP バックエンドはツリーの更新をリッスンし、以前にどのノードがリクエストされたかを追跡し、これらのノードが変更されると DevTools のフロントエンドにイベントを送信します。

多くの木々が語る物語

ユーザー補助ツリーとはの説明では、Blink がレンダリングする DOM のユーザー補助ツリーを構築する方法と、DevTools が CDP を介してこのツリーを取得する方法について説明しました。これは事実ですが、この説明では複雑な部分を省略しています。実際には、Chromium のユーザー補助ツリーをさまざまな方法で確認できます。DevTools の新しいツリービューを設計する際に、Chromium のユーザー補助内部のどの部分を表示するかについて、いくつかの選択を行いました。

プラットフォーム

プラットフォームごとに異なるユーザー補助 API があり、ツリーの形はすべてのプラットフォームで同じですが、ツリーを操作する API は異なり、属性名も異なる場合があります。DevTools には Chromium の内部ツリーが表示されます。このツリーでは、ロールと属性は ARIA 仕様で定義されているものと一致する傾向があります。

複数のフレームとサイト分離

Chromium では、すべてのタブのコンテンツを異なるレンダラ プロセスに配置するだけでなく、クロスサイト ドキュメントを異なるレンダラ プロセスで分離するため、CDP を介してプロセス外の各子ドキュメントに個別に接続し、そのユーザー補助ツリーを取得する必要があります。これらのサブツリーは Chromium の異なるレンダラ プロセスに存在しますが、フロントエンドでこれらのサブツリーをつなぎ合わせることで、1 つの連続したツリーのように見せています。

無視されるノードと興味のないノード

デフォルトで一部のノードは非表示になります。無視されるノードと、「generic」ロールを持つ名前のないノードです。これらのノードはセマンティックな意味を持ちません。また、無視された場合、支援技術には触れません。これらのノードは、ツリービューが煩雑にならないように非表示になっています。これがないと、ほとんどのウェブページのユーザー補助ツリーは次のようになります。

すべてのノードが表示された新しいツリービュー。

ただし、これは基本的に、バックエンドで利用可能なツリーとは別のツリーを構築する必要があることを意味します。たとえば、A、B、C、X というノードがあり、A に子 X と B があり、X に子 C があるとします。X が無視されるノードの場合、X はツリーから除外され、代わりに C が A の子であるツリーが作成されます。

ツリーのプルーニング方法を示す図。

フロントエンドでは、無視されるノードを含む完全なツリーを構築し、ノードをレンダリングする直前にのみノードを削除します。これには 2 つの理由があります。

  • 両方のエンドポイントに同じツリー構造があるため、バックエンドからノードの更新を処理するのがはるかに簡単になります。たとえば、この例でノード B が削除された場合、ノード X の更新が届きます(その子のノードが変更されているため)。しかし、そのノードをプルーニングしていた場合、何を更新すればよいか判断するのが難しくなります。
  • これにより、すべての DOM ノードに対応するユーザー補助ノードがあることが保証されます。ツリーが切り替わると、DOM ツリーで現在選択されているノードに対応するノードが選択されます。たとえば、上の例で、X に対応する DOM ノードが選択されているときにユーザーがツリーを切り替えると、ノード A と B の間に X が挿入され、ツリーで X が選択されます。これにより、ユーザーはすべての DOM ノードについてユーザー補助ノードを検証し、そのノードが無視された理由を判断するのに役立ちます。

今後のアイデア

新しいユーザー補助ツリーのリリースは出発点にすぎません。新しいビューをベースに今後構築できるプロジェクトのアイデアはいくつかありますが、皆様からのフィードバックもお待ちしております。

その他のフィルタリング

前述のとおり、現在は興味深くないと判断されたノードを除外しています。この動作を無効にしてすべてのノードを表示する方法や、ランドマーク ノードを表示見出しを表示などの代替フィルタリングを提供できます。

ユーザー補助機能に関する問題をハイライト表示する

ツリーに「ユーザー補助に関するおすすめの方法」の分析を組み込み、問題のあるノードに直接ユーザー補助に関する問題をハイライト表示できます。

DevTools でユーザー補助アクションを表示する

現在表示されているツリーは単方向です。特定のウェブページをブラウジングする際に、どのような情報が支援技術に提供されるかを把握できます。ユーザー補助アクションは、反対方向の通信を表します。ユーザー補助技術が表示された UI に対して動作できるようにします。DevTools にこのようなアクションを表示して、支援技術で利用できる API を使用して、ページ上の「クリック」、「スクロール」、「値の変更」などのアクションを行えるようにできます。