Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Vapor Mode でアクセシビリティは 壊れないか検証した話
Search
fuqda
October 24, 2026
Programming
50
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Vapor Mode でアクセシビリティは 壊れないか検証した話
https://vuefes.jp/2026/speaker/Shigeyuki-fukuda
fuqda
October 24, 2026
More Decks by fuqda
See All by fuqda
Composition API時代の Pub/Subパターンでの状態管理
fuqda
4
4.2k
RubyでPrettierを使ってみた
fuqda
0
430
RSpecによるOpen API自動テスト
fuqda
3
1.2k
OSSへの プルリクエスト作成の手引き
fuqda
1
380
Rails Girls Tokyo 13th Sponsor LT by STORES
fuqda
0
290
黒歴史リポジトリを使ったリファクタリング勉強法のススメ
fuqda
2
1.2k
OSS初心者がつまづきながらOSSマナーを学んでいく話
fuqda
4
3.5k
Ruby2.7の新機能で簡易版Rubyインタプリタを実装してみる
fuqda
0
680
カンファレンスで技術的お土産を 増やすために出来ることを考えた
fuqda
2
630
Other Decks in Programming
See All in Programming
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
1.7k
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.3k
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.6k
Seven New Principles of Software Engineering
yegor256
0
200
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
270
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
190
最近”作らせてる” ローカルAIアプリの話
akit37
0
490
npm との違いを手がかりにGo の依存管理を理解したい
optim
0
1k
Simple Storage Service(S3) is not simple
iwatsukayura
0
310
phperだってパンチカードでコーディングしたい
o0h
PRO
0
380
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
230
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
35
17k
Featured
See All Featured
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
610
Six Lessons from altMBA
skipperchong
29
4.5k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
570
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.4k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
430
Visualization
eitanlees
153
17k
YesSQL, Process and Tooling at Scale
rocio
174
15k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
640
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Transcript
Vue Fes Japan 2026 LT 枠 Vapor Mode でアクセシビリティは 壊れないか検証した話
2026/10/24 @fuqda 01
自己紹介 fuqda Web エンジニア@mov inc. GitHub Shigeyuki-fukuda X @fuqda90 普段は⼝コミコムを開発しています
02
Vue Fes Japan 2026 目次 1. 2. 3. 4. 5.
この発表の前提とその補足 どう測ったか 自動テストによる検証 スクリーンリーダーによる手動検証 まとめ 03
1. この発表の前提とその補足 04
1. この発表の前提とその補⾜ 検証のコードと調査ログは、GitHub で公開しています github.com/Shigeyuki-fukuda/vue-vapor-a11y-experiment(調査ログは Issues にあります) 05
1. この発表の前提とその補⾜ Vapor Mode とは? 06
1. この発表の前提とその補⾜ Vue 3.6 の Vapor Mode は、仮想 DOM を介さず
DOM を直接組み立てる、 Vue 公式の新しいレンダリング方式です 速さが話題になりがちですが、DOM の更新のしかたも変わります 07
1. この発表の前提とその補⾜ この発表での呼び分け classic vapor 従来のレンダリング(仮想 DOM を使う、今までの Vue) Vapor
Mode でのレンダリング(仮想 DOM を使わない) 08
1. この発表の前提とその補⾜ classic と vapor で、 アクセシビリティに差は出るのでしょうか? ⽬が⾒えない‧⾒えにくい⼈は、スクリーンリーダー(読み上げソフト)で Web を使っています
09
1. この発表の前提とその補⾜ スクリーンリーダーは何を読んでいるのでしょうか? 10
1. この発表の前提とその補⾜ スクリーンリーダーはアクセシビリティツリーを読んでいます アクセシビリティツリー ← スクリーンリーダーが読む DOM(書いたもの) region "フォーカス管理 :
…" <section aria-labelledby="focus-heading"> <h2 id="focus-heading">フォーカス管理: …</h2> heading "フォーカス管理 : …" <button>設定を開く</button> button "設定を開く " <div role="dialog" ブラウザ が変換 dialog "設定" [modal] aria-modal="true" aria-labelledby="focus-dialog-heading"> ▪ ロール(要素の種類) ▪ 名前 [ ] = 状態やプロパティ region = 名前の付いた section そのもの heading = その中の⾒出しの 1 ⾏ 11
2. どう測ったか 12
2. どう測ったか 同じ Vue ファイルを、フラグで 2 系統にビルドしました Vite の Vue
プラグインの features.vapor を false / true に切り替え、Vue のコンパイラが出す JS を分けています apps/classic vapor: false source/ components/ pnpm run sync apps/vapor vapor: true 13
2. どう測ったか アクセシビリティの差が出そうな 11 場面を選びました 1 トースト通知を出す 2 モーダルダイアログを開く 3
アコーディオンを開閉する 4 フォームの⼊⼒エラーを出す 5 ヒント⽂を出し⼊れする 6 リストを並べ替える 14
2. どう測ったか アクセシビリティの差が出そうな 11 場面を選びました 7 ⼊⼒欄と⽂字数カウンタ 8 Teleport を利⽤したモーダルダイアログ
10 表⽰中のパネルを差し替える 11 簡易的な SSR での検証 9 アニメーションでの表⽰切り替え 15
2. どう測ったか 11 場面を 2 つのやり方で検証 ⾃動テストによる検証 Playwright で、アクセシビリティツリーを⽐べます 11
場⾯ スクリーンリーダーによる⼿動検証 Mac 標準の VoiceOver で、読み上げを聞き⽐べます 16
3. 自動テストによる検証 17
3. ⾃動テストによる検証 スナップショットテストでアクセシビリティツリーを比較しました Playwright の ariaSnapshot() で、状態ごとに撮影 - 'region "フォーカス管理
: モーダルダイアログの検証 "': - button "設定を開く " - dialog "設定": - heading "設定" [level=3] - button "閉じる" この yaml を classic と vapor で⽐べます 18
3. ⾃動テストによる検証 差は 0 件でした 57 通りすべてで、classic と vapor の
ariaSnapshot の結果が完全に⼀致しました 差 # 57 通りの ariaSnapshot を比べる $ diff -r snapshots/classic snapshots/vapor $ echo $? 0 0 57 / 57 ⼀致 19
3. ⾃動テストによる検証 ここまでで、ブラウザが作るアクセシビリティツリーは同じだと分かりました 実際にスクリーンリーダーが何と読み上げるかは、まだ分かっていません ? DOM アクセシビリティ ツリー スクリーン リーダー
57 通り⼀致 まだ測っていない 何と読み上げる? 20
4. スクリーンリーダーによる手動検証 21
4. スクリーンリーダーによる⼿動検証 同じ操作をして、読み上げた文を並べて比べます 11 場⾯を、classic → vapor の順に確かめました 1. 2.
3. classic と vapor で、同じキー操作を行います VO + → で 1 つずつ読み進め、 Tab でボタン間を移動します 読み上げた文を、クリップボードにコピーして残します VO + Shift + C で、直前に読み上げた文をコピーします 2 つの文字列を、操作ごとに並べて比べます 22
4. スクリーンリーダーによる⼿動検証 11 場面すべてをスクリーンリーダーで読み上げた結果 1. ⼀致 トースト通知 2. 差あり モーダルダイアログ
3. ⼀致 アコーディオン 4. ⼀致 フォームの⼊⼒エラー 5. ⼀致 ヒント⽂の出し⼊れ 6. ⼀致 リストの並べ替え 7. ⼀致 ⽂字数カウンタ 8. ⼀致 Teleport を利⽤した モーダルダイアログ 9. ⼀致 アニメーションでの 表⽰切り替え 10. ⼀致 パネルの差し替え 11. ⼀致 簡易的な SSR ⼀致は、classic と vapor の読み上げが⼀字⼀句同じだったものです 23
4. スクリーンリーダーによる⼿動検証 モーダルダイアログの検証コード(抜粋) <section aria-labelledby="focus-heading"> <h2 id="focus-heading">フォーカス管理 : モーダルダイアログの検証 </h2>
… <div v-if="isOpen" ref="dialogRef" role="dialog" aria-modal="true" aria-labelledby="focus-dialog-heading" tabindex="-1"> <!-- tabindex="-1": 開いたときにダイアログ自体へフォーカスを置くため --> … </div> </section> モーダルダイアログは名前の付いた section の中です。読み上げカーソルをモーダルダイアログの外へ出し、この section の名前を読むかを検証しました 24
4. スクリーンリーダーによる⼿動検証 CLASSIC モーダルダイアログの親の section の名前を読み上げています 25
4. スクリーンリーダーによる⼿動検証 VAPOR section の名前を読み上げていません。リロードから 3 回やり直しても同じでした 26
4. スクリーンリーダーによる⼿動検証 vapor は、section の名前を消してしまった…? 27
4. スクリーンリーダーによる⼿動検証 アクセシビリティツリーには、ちゃんと残っていた! モーダルダイアログを開いた状態で、Safari の Web インスペクタで親の section を⾒ました CLASSIC
VAPOR ロール region(デフォルト) ラベル フォーカス管理: モーダルダイアログの検証 ロール region(デフォルト) ラベル フォーカス管理: モーダルダイアログの検証 ✓ ✓ 28
4. スクリーンリーダーによる⼿動検証 vapor のアクセシビリティツリーも classic と同じでした スクリーンリーダー の読み上げだけが違いました 読み上げの差の原因は、特定できませんでしたが... ?
少なくとも今回のUIパターン 11 場⾯では、 アクセシビリティは担保されていることがわかりました 🎉 ✨ 29
5. まとめ 30
5. まとめ この発表で紹介したやり方 検証結果は環境とバージョンで変わることがあるので、やり方を紹介します 1. 1 ソース 2 系統 vapor
フラグの false / true で 2 系統に分けます 2. ariaSnapshot で比較 状態ごとに撮った yaml を比べます 3. 差が出たときの切り分け ① 毎回リロードから 3 回やり直して、再現するか見ます ② Web インスペクタで、ブラウザのアクセシビリティツリーを直接見ます ③ 両方に名前があれば、アクセシビリティツリーより先( Safari から VoiceOver まで)を疑います github.com/Shigeyuki-fukuda/vue-vapor-a11y-experiment 31
5. まとめ Vapor Mode は、パフォーマンスだけではありません アクセシビリティ も、ちゃんと守られていました! まずは⼿元のコンポーネントから、試していきましょう 32