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
35
0
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
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
170
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
360
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
35
17k
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
230
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
970
ChromeでローカルLLM
ryu1013
0
160
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
5
4.2k
dotNET_vulnclicker_intro.pdf
deka_morita
0
150
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
3
1k
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
0
600
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
130
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
160
Featured
See All Featured
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
580
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
580
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
550
HDC tutorial
michielstock
2
960
So, you think you're a good person
axbom
PRO
2
2.2k
Code Review Best Practice
trishagee
74
20k
4 Signs Your Business is Dying
shpigford
187
23k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
310
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Site-Speed That Sticks
csswizardry
13
1.6k
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
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