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
はじめてのSSR
Search
Taketoshi Aono(青野健利 a.k.a brn)
August 31, 2017
Programming
1.3k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
はじめてのSSR
React + ReduxでSSR+Isomorphicなアプリケーションを作ったときにつまづいた点をまとめました。
Node学園27時限目
Taketoshi Aono(青野健利 a.k.a brn)
August 31, 2017
More Decks by Taketoshi Aono(青野健利 a.k.a brn)
See All by Taketoshi Aono(青野健利 a.k.a brn)
document.write再考
brn
6
3.2k
Parsing Javascript
brn
14
9.6k
JSON & Object Tips
brn
1
590
CA 1Day Youth Bootcamp for Frontend LT
brn
0
1.1k
Modern TypeScript
brn
2
890
javascript - behind the scene
brn
3
820
tc39 proposals
brn
0
1k
プロダクト開発とTypeScript
brn
7
3k
React-Springでリッチなアニメーション
brn
1
780
Other Decks in Programming
See All in Programming
高専キャリア LT 発表内容
crysta1221
6
5.6k
ソフトウェアラスタライザ
fadis
1
790
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
150
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
440
Claude Codeを組織的に動かして月400PRを実現した話
happy_ryo
0
260
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
3
500
MIZARU@SPAJAM2026 第二回予選
1901drama
0
110
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
4
2.8k
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
120
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
920
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
130
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
260
Featured
See All Featured
Paper Plane
katiecoart
PRO
2
53k
Are puppies a ranking factor?
jonoalderson
2
3.9k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.3k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
Git: the NoSQL Database
bkeepers
PRO
432
67k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Rails Girls Zürich Keynote
gr2m
96
14k
Building AI with AI
inesmontani
PRO
1
1.2k
Chasing Engaging Ingredients in Design
codingconduct
0
300
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.3k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Transcript
ⴱ ג ך S S R
せ: @brn (ꫬꅿ⨳ⵃa.k.a ـٕ٦ظ) 耵噟: ؿٗٝزؒٝسؒٝآص،٥iOSؒٝآص، ⠓爡: Cyberagent ،سذؙأةآؔRightSegment٥AI Messenger
ـؚٗ: http://abcdef.gets.b6n.ch/ Twitter: https://twitter.com/brn227 GitHub: https://github.com/brn
⡦⠗ְִךַ ְׂSSR׃״ֲהׅהꬊ䌢ח넝䏝זֿה׃גְ鎸✲כ״ֻ 鋅ַֽךָծ ⴱ娄涸ז㉏겗ח瘶ִגְךָ㼰זְ״ֲח䙼ִկ זךדծSSR+Isomorphicז圓䧭ד،فٔ⡲♳ד䝢ֿהծ 㹋ꥷח鍑寸׃倯岀⚛ץגկ
Language ְא鸐typescript鼅䫛׃կ ֿ荈⡤כNodeJS⩎הـٓؐؠ⩎דٌرٕךinterface㹀纏ָ⢪ְת ׇגꬊ䌢ח葺ַկַזىأָ幾կ 暴חAPIךٖأهٝأךأؗ٦وⰟ鸐ךٌآُ٦ٕחInterfaceה ׃ג㹀纏ׅהծ 涸חAPIךؒٓ٦鋅אֽךד葺ְկ
Library/Framework ـٓؐؠ⩎כReact(v16.0β) + Redux + React-Router v4 ؟٦غ؟؎سכExpress + Sequelize
+ MySQL NodeJSך湊鋔כsupervisord
Structure ֿֿכꬊ䌢ח䝢կָծ 如ل٦آך״ֲז圓䧭ח׃կ
server NodeJSך؟٦غ٦㹋鄲 DB،ؙإأהַ client ـٓؐؠ⩎ך㹋鄲 React + Redux isomorphic NodeJSהـٓؐؠ⩎דⰟ鸐ׅ㘗㹀纏הַ
Root rendering SSR欽ך؟٦غ٦
HTML Rendering Reactך؝ٝه٦طٝزכ֮ךָծHTMLةؚろⰋ⡤ךٖ ٝتؚٔٝוֲַׅ䝢կ 穠㽷HTMLةؚװHeadةؚReactד㹋鄲׃גծ؟٦غ؟؎سדٖ ٝتؚׅٔٝة؎ىؚٝךծך؝ٝه٦طٝز⢪կ
data-reactid HTMLⰋ⡤Reactדٖٝتؚׅٔٝהـٓؐؠ⩎דmountׅה ֹחdata-reactidָ׆גWarningָדָծ React v16ַכdata-reactid涪遤׃זֻזךדWarningָ嶊 ִկ
Redux State of SSR SSRדⴱ劍朐䡾ٖٝتؚׅٔٝחծ 剑ⴱכ؟٦غ؟؎سדdbַ《䖤׃ؒٝذ؍ذ؍湫䱸床׃גְ կ ׃ַ׃ծֿהAPIؒٝسه؎ٝزך✳ꅾ盖椚ָ涪欰ׅկ
viewָ《䖤ׅر٦ةָ㢌הֹחծ ؟٦غ⩎ךؒٝذ؍ذ؍《䖤鿇ⴓ⥜姻ָ䗳銲ד✳ꅾ盖椚חזկ APIエンドポイント DB React ؒٝذ؍ذ؍湫䱸《䖤 Reactח床ׅ ブラウザ
Redux State of SSR DRYחװծ 㹋ꥷחredux-saga⹛⡲ׇׁג؟٦غ٦ⰻדlocalhostד荈魦ךؒٝ سه؎ٝز〨ְկ fetch⢪גְךדծisomorphic-fetchػح؛٦آⵃ欽կ
ٖؔٝآ葿ך鿇ⴓָRedux-Sagaַךؿٗ٦ 㹋ꥷחlocalhostח،ؙإأ׃גծ ⰻ鿇דֲ♧䏝ずׄؒٝسه؎ٝز〨ֻկ APIエンドポイント DB React Redux-Saga⹛ַׅ X-Rest-Requestقحت➰♷׃ 㹋ꥷחAPIؒٝسه؎ٝز localhostחぢַג〨ֻ
ブラウザ JSON ؒٝذ؍ذ؍ך《䖤
Redux State of SSR ؟٦غ٦כ鵤ׅ⦼SSRךٖٝتؚٔٝ穠卓הծJSON勴⟝ח״ ג㢌ִזֽלזזְկ 剑ⴱכGetػًٓ٦ة⢪גְָծ 植㖈כقحتחX-Rest-Request: 1鏣㹀ֿׅהד㔐鼘׃גְկ ֮הծأومהPCד鵤ׅⰻ㺁ָ麩ֲךדծ
User-Agentقحتח䩛⹛ד؟٦غ٦ַ䒷ֹ竰ְUserAgent إحزׅկ
Redux Initial state SSRׅהׅדח歗חכStateָٖٝتׁؚٔٝגְ朐䡾זך דծⴱ劍朐䡾ך《䖤כأؗحف׃ְկ
State as JSON ת׆ծ؟٦غ؟؎سדٖٝتؚٔٝ׃穠卓ךReduxךStatehtml חJSONה׃ג㙵鴥דծinitialStateה׃גⵃ欽׃կ
const initialState = JSON.stringify(state);! ! <script type="text/javascript"! dangerouslySetInnerHTML={{! __html: `window.__INITIAL_STATE__
= ${initialState}}`! }} />!
State as JSON 如חծcomponentDidMountךة؎ىؚٝדhistory.stateָ瑞 ⴱ㔐ٖٝتؚٔٝהⴻ㹀׃גծ 植㖈ךstatehistory.replaceדhistory.stateח鏣㹀׃կ
Page1 history Page2 history state Page3 history state state וךل٦آחٓٝر؍ؚٝ׃גhistory.stateָ搀ְل٦آָծ
SPAך饯挿הזل٦آחזկ Page2 history Page1 history state Page3 history state state
React-Router V4 㹋ꥷח؟٦غ؟؎سדוך؝ٝه٦طٝز䲽歗ַׅծ וךAPI〨ַֻ寸חכծ React-Router v3דכmatch⢪ֲ鎸✲כְםְ֮ךָծ React-Router v4דכmatchָ䐖姺ׁגְկ זךד➿חmatchPath⢪ֲկ
import {! matchPath! } from 'react-router';! ! const match =
matchPath("/article/1", {! path: '/articel/:articleId',! exact: true! });! ! if (match) {! console.log(match.params)! // Object { articleId: 1 }! }!
React-Router V4 ׃ծֿך倯岀הـٓؐؠךٕ٦ذ؍ؚٝהNodeJSךٕ٦ذ؍ ؚٝד✳ꅾ盖椚חזג׃תֲךדזהַ׃ְ…
Webpack typescriptד㹋鄲׃ծNodeJS⩎typescriptד㹋鄲׃ְկ ׁחWebpackדcss-modules⢪גְךדծWebpack⢪ זְהSSRָ⹛ַזְկ זךדWebpackדכtargetnodeח䭷㹀ֿׅהדծ__dirname 笝䭯׃אאnode_modules⟃㢩ך؝٦سbundle׃կ
module.exports = { entry: { server: './server/index.ts' }, target: 'node',
externals: /^(?!^\.\.?\/)/, output: { path: `${__dirname}/dist`, filename: "[name].js", libraryTarget: "commonjs2" }, resolve: { extensions: [".js", ".ts"] } }
Watch Webpackדwatch׃גְךָծ♧אךؿ؋؎ָٕ㢌刿ׁ ֽד؟٦غ٦ծؙٓ؎،ٝز⚕倯ָⰋגⱄ؝ٝػ؎ׁٕג礵牞遹 欰♳״ֻזְךהծ SSR遤ֲ鿇ⴓך頾蚚ֽ넝ְךדծSSRֽׁח؟٦غג גفٗإأⴓꨄ׃կ
Requst SSR Response HTML Supervisord Renderingサーバ Renderingサーバ Renderingサーバ Supervisord APIサーバ
APIサーバ APIサーバ
Cache ⽃秪חNginxהAppךחmemcached 䮠דծ $request_uri--$is_mobile ְז䠬 ׄךؗ٦ד⥂㶷׃גⱄⵃ欽կ
Nginx memcached Node $host$request_uri--$is_mobile ؗ٦חٍؗحءُ嗚稊 זֽלٖٝتؚٔٝ x-memcached-keyח memcachedךؗ٦إحز x-memcached-keyقحت ך⦼ؗ٦ח⥂㶷
SEO react-lazyload⢪גְךדծ GoogleװBotך،ؙإأך㜥さכ lazyload㐣תׇזְ穠卓鵤ׅ״ֲ חծ react-lazyloadٓحف׃؝ٝه٦ طٝز⢪կ
public render() {! return !this.props.shouldRenderStatic! && this.props.isMobile ? (! <LazyLoad
{...this.props}>! {this.props.children}! </LazyLoad>! ) : this.props.children;! }!
תה SSRכװםזח؝أزָ䱦ַז֭הְֲ䠬䟝կ 葿ղ孡⢪ֲֿה㢳ְ׃ծ 劤䔲ח䗳銲חזתדכװץֹדכזְկ 暴חؿٗٝزؒٝسך؝٦سָ؟٦غד⹛ֻךדծ䌢ח➙ـٓؐ ؠזךַNodeJSזךַ䠐陎ׅךָ⦜կ ׀幠耮ָ֮הֲ׀ְׂת׃կ