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
340
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
Transcript
32 slides
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
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
640
Other Decks in Programming
See All in Programming
AI-Powered Domain-Driven Design
ziobrando
0
440
TanStack Vue Query と Pinia Colada から学ぶ非同期状態の型設計
aoshi
0
670
ActionController meets Protocol Buffers
sorah
1
800
TS 7.0 で baseUrl が使えなくなった今、パスエイリアスをどうするか
bicstone
2
640
Enforcing Your Architecture with Unit Tests in the AI Era (Swift Connection X)
steliosf
PRO
1
170
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
1.2k
動画プレイヤーはなぜカクつくのか 〜Flutterのレンダリングとネイティブの境界を解剖する〜
naruogram
0
340
AIが生成したコードは読むべきか?抽象化設計とコードの品質保証 / abstraction-design-and-quality
minodriven
16
9.1k
Secure Your Coding Agent Like It’s Malware (v1.5) 🇬🇧 @Code.talks 2026
richargh
0
150
DroidKnights 2026 Android A2UI Jetpack Compose 기반의 안전한 AI UI 렌더링 - 박제창
itsmedreamwalker
1
230
AI時代のFlutter品質設計 — アプリ品質を守るQuality Layers
omatty198
0
380
Performance Optimization With LLMs
xleitix
0
260
Featured
See All Featured
How Software Deployment tools have changed in the past 20 years
geshan
3
35k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
590
How STYLIGHT went responsive
nonsquared
100
6.4k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
440
Building the Perfect Custom Keyboard
takai
2
960
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7.1k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
610
Code Review Best Practice
trishagee
74
20k