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 プロトコル(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 を使用して、ページ上での「クリック」やスクロール、値の変更などのアクションを可能にできます。