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
10周年を迎えたZEN Study Webフロントエンドの次の10年へ向けた工夫
Search
tris
May 25, 2026
Programming
120
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
10周年を迎えたZEN Study Webフロントエンドの次の10年へ向けた工夫
TSKaigi 2026 スポンサーセッション
https://2026.tskaigi.org/talks/85
tris
May 25, 2026
Transcript
23 slides
10周年を迎えた ZEN Study Webフロントエンドの 次の10年へ向けた工夫 株式会社ドワンゴ 教育事業 (小松) 2026/05/23 TSKaigi 2026
スポンサーセッション
自己紹介 • ドワンゴ 教育事業本部 e-learningプロダクト開発部 ZEN Study Webフロントエンドセクション 小松(こまつ) • ここ2年ほど
ZEN Study の開発に従事 • 趣味の1つ: ドライブ【距離ガバ】 日本本土の海沿いを走破+α 2 ニコニコ超会議の 配信に映り込む 不審なスタッフ
本セッションのサマリー • ドワンゴ教育事業とZEN Studyの概要 ◦ 事業・サービス ◦ これまでの10年のごく簡単な振り返り • 次の10年に向けてメンテナンス性を向上するために行なっている取り組みの一
部を、主にTypeScriptの観点から紹介 ◦ 外部とのやり取りの結果として、判別可能なユニオン型を活用し、状態を詳細にモ デリング (お昼休憩中なので、頭を使う難しい話ではなく、基本的な話をします) 3
ドワンゴの教育事業とは (1) • 主にN高グループとZEN大学に対して、教育に関するシステムを提供 N高グループ(N・S・R高) KADOKAWAとドワンゴが創るネットの高校 2016年4月開校(N高) 生徒数 3万人規模 ZEN大学
日本財団とドワンゴが創るオンライン大学 2025年4月開学 学生数 7千人規模 4
ドワンゴの教育事業とは (2) • 生徒・学生が直接使用するアプリや、学校の運営に関するシステムを提供 ◦ 学習アプリ ZEN Study ▪ 各学校向けだけではなく、一般向けにも月額課金で提供
◦ 教材作成・学校運営に関連するシステム 5
ZEN Study 10周年 🎉 • 2016年4月に「N予備校」としてサービス開始 10周年記念サイト https://www.nnn.ed.nico/pages/10th_anniversary サービスの歴史 ドワンゴ教育サービス開発者ブログ
https://blog.nnn.dev/ 10年を技術面から振り返る記事 6
10年の歴史がある = 10年の積み重ねがある • 最初の構築が急ピッチで行なわれた ◦ N高の開校と同時にリリースする必要があった ▪ 期限が決まっている中で、完全新規プロダクトの構築が行なわれた ◦
開発スピードを優先した選択が行なわれた ▪ メンテナンス性の優先度は低かった • 複雑性が積み重なっている ◦ 新機能の追加 ◦ 対象となる学校の増加 ▪ S高・R高の開校、大学の開学 ◦ リファクタリングが追い付いていないコード 7
ZEN Study 関連の開発体制 • フロントエンドはプラットフォームごとに分かれている • バックエンドは別チーム 8
ZEN Study Webフロントエンドの主な技術スタック • TypeScript + React SPA ◦ (Reactを10年使っているサービスは古参と言えそう)
• TanStack Query • React Router • React Redux 9
ZEN Study Webフロントエンド 10年間の技術変遷 次の10年を見据えて、コードベースの改善を継続して行なっている 10
次の10年に向けて メンテナンス性を向上するための 取り組み(の一部) 11 判別可能なユニオン型を利用して、状態を正確にモデリングする
判別可能なユニオン型を利用する方法の概要 • 外部 API 呼び出しの結果は、成功/失敗のケースがある • それなら汎用的な Result<T, E> を使うのが良さそう
😊 ◦ みんな Result を好きすぎて無限に Result の話をしている • でも Result<T, E> だけではツラいケースがある 😰 ◦ ローディング状態をどう表現する? ◦ エラーの中身をどうやって分ける? ◦ 使う側(コンポーネント)で細かい判定が必要で扱いにくい? ⇩ 判別可能なユニオン型を利用して、状態を正確にモデリングする方法を採用 (本質的には、外部への依存と内部実装とを切り分けている) 12
パターン1. コンポーネントで直接データを取得する • 🔥 データ取得と表示の責務が分離されていない • 🔥 コンポーネントのテストが大変 ◦ 通信をモックする必要がある
13
パターン2. データ取得をカスタムフックに分離する • 👍 データ取得と表示の責務が分離された • 👍 コンポーネントのテストが楽になった ◦ 通信ではなくカスタムフックをモックすれば良い
• 🔥 コンポーネントでの表示のために相変わらず色々と気にする必要がある ◦ 例:ローディングの判定のために特定のフラグを見る必要がある 14
パターン3. 汎用 Result (neverthrow) を使ってみる • 👍 コンポーネントでの表示時に気にすることが減った ◦ 特定の値(フラグ)を元にした判定が不要
• 🔥 ユニオン型と Result の使い分けが必要 ◦ 成功/失敗は Result だが、それ以外はユニオン型なので扱い方が異なる 15 ローディング中は undefined を 返すこととする
パターン4. カスタムフックが返す型としてユニオン型を利用 • この方式を我々は採用 • 👍 データ取得などの外部とのやり取りと表示の責務がより分離された • 👍 数々の嬉しさがある(後述)
判別可能なユニオン 16
ユニオン型を使う嬉しさ (1) • コンポーネントで switch 文によって状態ごとに容易に出し分けられる ◦ 複数の値を元にした状態の判別が不要 ◦ データの取得状態/結果とコンポーネントの表示を明確に関連付けられる
• 網羅性チェックを行える ◦ パターン追加時の堅牢性が上がる 網羅性チェックを実施可能 switch 文により単純に出し分け可能 判別可能なユニオン 17
ユニオン型を使う嬉しさ (2) • データ取得成功時のみ値があることが型で保証される ◦ 値を取得できていない状態のときは、値にアクセスできない • SUCCESS のときのみ値がある •
LOADING や ERROR のときには値がない ERROR などの状態で 値にアクセスを試みると 型エラーになる 18
ユニオン型を使う嬉しさ (3) • エラーの状態を細かく表現可能 その1 ◦ 例:リロードによる復旧可否を分ける リロードしても意味がないエラーと リロードにより復旧できるエラーを 別の型にする
リロードボタンの表示を容易に出し分けられる 19
ユニオン型を使う嬉しさ (4) • エラーの状態を細かく表現可能 その2 ◦ 例:HTTPステータスコードからコンポーネントを分離 ▪ エラーコードへ依存しないので、REST API
から GraphQL へ切り替えるような 場合も、コンポーネントに手を入れる必要がない HTTPステータスコードを直接利用するのではなく、 エラー種別ごとに型を作って、ステータスコードに 依存しないようにする 20
ユニオン型を使う嬉しさ (5) • エラーの状態を細かく表現可能 その3 ◦ 例:追加読み込みを行う API/コンポーネントにおいて、初回読込み時のエラーと追 加読込み時のエラーを区別する ▪
状況によりエラーの表示方法を変えるのが容易(初回読込み時だとエラーペー ジ、追加読込み時だとスナックバー、など) ▪ 単純に useInfiniteQuery を使うより複雑になっているとも言えるが、何を 優先するかのトレードオフ次第 21
ユニオン型を使う嬉しさ (6) • 実現方法の切替をコンポーネントと分離可能 ◦ 例:状態(履歴など)をサーバーに保存して全クライアントで同期したいが、ひと まず暫定的にローカルストレージへ保存して最低限改善する ▪ まずは暫定対応として、ローカルストレージへ保存するカスタムフックを実装 ▪
バックエンドの準備が完了し次第、API 呼び出しによりサーバーへ保存するカ スタムフックを実装 ▪ この前後で、カスタムフックの型シグネチャ(特に成功/失敗を表す戻り値の ユニオン型)が変わらなければ、コンポーネントの実装ではこの切替を意識す る必要がない 22 Webフロントエンド バックエンド まずは暫定的に ローカル保存 バックエンドの準備完了後、 サーバーへ保存 コンポーネント 呼び出しの型シグネチャに変更がなければ 意識せずに切替可能
まとめ • ZEN Study は10周年を迎えることができた 🎉 • 10年の積み重ねを踏まえつつ、次の10年に向けて改善を重ねている • TypeScriptの強力な機能である、判別可能なユニオン型を活用して、データ取
得などの状態(外部への依存)を正確にモデリングすることにより、堅牢でメ ンテナンスしやすくできた • 他にも様々な工夫・改善を行なっています! 23 めでたし めでたし 🤟
More Decks by tris
See All by tris
TypeScript だけを書いて Tauri でデスクトップアプリを作ろう / Tauri with only TypeScript
tris5572
2
3.6k
Other Decks in Programming
See All in Programming
Growing PicoRuby's Ecosystem on ESP32
yuuu
2
100
S3 TablesのIcebergデータに、AIエージェントからアクセスしてみた / 20261016developersio2026joetsu-accessing-iceberg-in-s3tables-via-agent
kasacchiful
PRO
0
300
Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / lets learn vue custom renderer by making 3d library
drumath2237
1
130
SODA - FACT BOOK(EN)
sodainc
1
230
地方こそサーバーレス — 10年続けた、顔が見えるチームで確かな基盤を / Serverless Matters Most in Regional Areas — 10 Years of Building Reliable Foundations with Close-Knit Teams
seike460
PRO
1
350
protojson における文字化けの扱い
kazuki1023
0
350
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
370
作れるエンジニアから、価値を届けるエンジニアへ
ryunakayama
1
260
AWS CDKを理解するために公式の定義を深掘って解説してみる / Understanding AWS CDK by Digging into Its Official Definition
akihisaikeda
3
300
プロジェクトコードをキレイキレイしよう!暗黙的な参照を読み解く静的解析
ostk0069
0
210
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
3
1.5k
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
210
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
What does AI have to do with Human Rights?
axbom
PRO
1
2.5k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
630
How Software Deployment tools have changed in the past 20 years
geshan
3
35k
Paper Plane (Part 1)
katiecoart
PRO
3
12k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
820
So, you think you're a good person
axbom
PRO
2
2.3k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.2k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
560
Being A Developer After 40
akosma
PRO
92
590k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
610