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

Johan Bay
Johan Bay

Chrome DevTools のフルアクセシビリティ ツリーがリリースされ、デベロッパーがツリー全体の概要を簡単に確認できるようになります。この投稿では、このツリーの作成方法と、作業での使用方法について説明します。

アクセシビリティ ツリーとは

スクリーン リーダーなどの支援技術では、Chromium の Accessibility 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>

前のツリービューでは、単一のノードとその祖先を調べることしかできません。

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 ノードのユーザー補助ノードを検証し、そのノードが無視された理由を判断するのに役立ちます。

今後のアイデア

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

代替フィルタリング

前述したように、現在のところ、重要でないと思われるノードは除外しています。この動作を無効にしてすべてのノードを表示する方法を提供するか、[ランドマーク ノードを表示] や [見出しを表示] などの代替フィルタを提供することができます。

a11y 問題をハイライト表示

ツリーに「ユーザー補助のベスト プラクティス」分析を組み込んで、不適切なノードでユーザー補助の問題を直接ハイライト表示することもできます。

DevTools でのユーザー補助アクションの表示

現在表示しているツリーは純粋に一方向です。ツリーを見ると、特定のウェブページを閲覧するときに支援技術に送られる情報を把握できます。ユーザー補助アクションは、逆方向のコミュニケーションを表します。ユーザー補助アクションを使用すると、表示された UI で支援技術を機能させることができます。DevTools にこのようなアクションを表示して、支援技術で利用できる API を使用して、ページ上の「クリック」、「スクロール」、「値の変更」などのアクションを行えるようにできます。