Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Server-Driven UIで frontendの複雑性に立ち向かう
Search
nacal
November 05, 2025
Technology
690
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Server-Driven UIで frontendの複雑性に立ち向かう
nacal
November 05, 2025
More Decks by nacal
See All by nacal
新規プロダクトにおけるシステムマイグレーションの判断
nacal
0
28
Linterからはじめるa11y
nacal
2
3.1k
Other Decks in Technology
See All in Technology
「最後に責任を取るのはチーム」— 人間のPRレビューを最小化してアップデートしたメンタルモデル
jnishime_dresscode
0
940
壊して学ぶAWS CDK: そのcdk deployで消えるもの、残るもの
k_adachi_01
1
420
シンガポールで登壇してきます
yama3133
0
250
Network Firewallやっていき!
news_it_enj
0
170
Webアプリ認証の全体像 / The Big Picture of Web App Authentication
kitano_yuichi
0
220
実践!既存 Project への AI-Driven Development 適用〜 一ヶ月で Project 唯一のフロントエンドエンジニアを作り出せ〜
lycorptech_jp
PRO
0
240
プロダクト開発組織の現在地(Ver.2026/07) / product-organization
kaonavi
0
120
AmplifyHostingConstructからSSRフレームワークのためのホスティング設計を考察する/amplify-hosting-construct
fossamagna
1
250
Playwright × AI Agent でE2Eテストはどう変わるか AI駆動テストの可能性と実用検証の結果
taiga7543
1
490
ruby.wasmとPicoRuby.wasmに対応した仮想DOMライブラリを作ってる話 #kaigieffect_kaigi
sue445
PRO
0
150
AIレビューはどこまで任せられるのか?自動化と人が背負うレビューの境界
sansantech
PRO
3
1.1k
OPENLOGI Company Profile for engineer
hr01
1
74k
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The SEO identity crisis: Don't let AI make you average
varn
0
520
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.6k
Leo the Paperboy
mayatellez
8
1.9k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.7k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
3
1.1k
A Tale of Four Properties
chriscoyier
163
24k
Product Roadmaps are Hard
iamctodd
55
12k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Embracing the Ebb and Flow
colly
88
5.1k
Transcript
1 Server-Driven UIで frontendの複雑性に⽴ち向かう 中⽥ 輝 / nacal 2025.11.05 カバーとGMOペパボが語る、クリエイターの創作‧表現活動を⽀える技術
2 ⾃⼰紹介 ロリポップ‧ムームードメイン事業部 for Gamersチーム 2022年 新卒⼊社 中⽥ 輝 Nakata
Hikaru / nacal • Webアプリケーションエンジニア • フロントエンドがすきです • X : @_nacal
3 - LOLOPOP! for Gamersのゲーム設定管理 にServer-Driven UIを導⼊してみた話 - ビジネスロジックをサーバー側に寄せる ことで、frontendのコード量を削減
- UI変更の作業も簡略化 今⽇話すこと
None
5 - ServerからのResponseでUIを構成する要素を返却する(プレゼンテーションを指⽰) - クライアント側はResponseを元にUIに変換して描画するだけの責務 Server-Driven UIとは https://github.com/csmets/Server-Driven-UI
6 https://github.com/csmets/Server-Driven-UI type NewsCard { image: Image author: String postDate:
String heading: String body: [String] } type Image { url: String description: String } Client-Driven UI
7 https://github.com/csmets/Server-Driven-UI Server-Driven UI
8 https://github.com/csmets/Server-Driven-UI Server-Driven UI type NewsCard { elements: [NewsCardElement] }
type Heading implements Typography { text: String } type Paragraph implements Typography { text: String } ... union NewsCardElement = Button | Image | NewsCardMeta | Heading | Paragraphs
9 - frontendの複雑性 - 多種多様なゲームタイトル/バージョンによって⽣じるビジネスロジックの複雑化 - frontendはなるべく体験の創造に集中責務に集中したい - ゲームのアップデート対応 -
元々の実装ではゲーム単位でそれぞれPRC/Componentsが存在しており、DRYでない - ゲームの最新リリースによる設定項⽬の変更のための作業が⼤変 - schema変更、設定ファイル編集、frontend Component修正... 解決したかった課題 最新アップデートは最速で遊びたいよ!
10 - ゲームの設定項⽬のList/formにServer-Driven UIを導⼊ - 画⾯全体には適⽤しない - 更新頻度/ビジネスロジックによる分岐の複雑性 が⾼い⼀部のView -
UIを構成する要素(attrやElement)をAPIのResponseとする - backend側でビジネスロジックを完結させる - 技術要件:gRPC + Protocol Buffers 導⼊したもの
protobuf schema 11 message GetGameSettingsRequest { string server_id = 1;
} message GetGameSettingsResponse { // 設定グループ(Section) message Group { string group_id = 1; // "gameplay" string title = 2; // "ゲームプレイ設定" repeated Field fields = 3; } repeated Group groups = 1; } サーバーIDからゲーム/バージョン情報の取得 セクションレベルでの配列に格納
protobuf schema 12 // 設定フィールド message Field { string field_id
= 1; // "max_players" string label = 2; // "最大プレイヤー数" optional string description = 3; // ヘルプテキスト SettingValue value = 4; // 現在の値 // フィールドタイプごとの設定 oneof field_config { TextField text_field = 5; SliderField slider_field = 6; ToggleField toggle_field = 7; SelectField select_field = 8; …, etc. } } Fieldの共通要素と各Fieldをoneofで
protobuf schema 13 // テキスト入力フィールド message TextField { optional int32
min_length = 1; optional int32 max_length = 2; optional string pattern = 3; optional string placeholder = 4; } // セレクトフィールド message SelectField { repeated Option options = 1; optional string description = 2; } …, etc. Fieldごとに必要なattrを型として定義
export const DynamicField = ({ field, values, onChange }: Props)
=> { const commonProps = { label: field.label, description: field.description, } switch (field.fieldConfig.case) { case 'textField': { const value = values.get(field.fieldId)?.value return ( <TextField {...commonProps} value={value.case } config={field.fieldConfig.value} onChange={(newValue) => onChange( field.fieldId, new SettingValue({ value: { case: 'stringValue', value: newValue } }), ) } /> ) } case 'sliderField': { … 14 FieldTypeごとに分岐 それぞれのComponentに Responseをそのまま渡す 各Componentの中では Stylingのみのロジック frontendでの変換
15 - コード差分 - (frontend) 共通Component: +12ファイル、+1000Lines - (frontend) 特定ゲームのComponent:
-21ファイル、-1500Lines - 将来的にはこれ×対応ゲームの数削減できる - (backend) RPC: +2個 (List/Update)、共通ロジック: +150Lines、個別ロジック: +500Lines - ゲームのアップデート対応 - Responseの内容を変更するだけでUIの更新が可能になる - schemaの変更も不要、破壊的な変更にならない 「すべてのビジネスロジックはサーバーサイドで管理し、クライアントはUIのレンダリングのみを担当する」 導⼊した結果
16 - 特殊なFiledを扱うか - 現状、特定の設定項⽬にのみ適⽤されるような特殊なUIは対象外としている - 様々なケースを許容することによりschemaの複雑性も増すので判断の基準は必要 - Database-Driven UI?
- DBでUIを構成する要素を管理 - 管理⽤APIなどから項⽬の編集を可能に - アプリケーションのリリースゼロでゲームのバージョンアップ対応が可能になりそう 今後の展望
17 Thank you!