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
Deep Dive into React Stream/Serialize
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
mugi / Hajime Mugishima
April 30, 2024
Programming
2.4k
8
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Deep Dive into React Stream/Serialize
2024/04/30 Node学園
https://nodejs.connpass.com/event/315443/
mugi / Hajime Mugishima
April 30, 2024
More Decks by mugi / Hajime Mugishima
See All by mugi / Hajime Mugishima
AIと乗り切った1,500ページ超のヘルプサイト基盤刷新とさらにその先の話
mugi_uno
2
490
サイボウズフロントエンドの活動から考える探究と発信
mugi_uno
1
200
フロントエンドエキスパートチームの解散は 「いい話」なのか?
mugi_uno
8
2.5k
サイボウズフロントエンドの横断活動から考える AI時代にできること
mugi_uno
4
2.2k
令和7年版 あなたが使ってよいフロントエンド機能とは
mugi_uno
14
7.3k
New Order in Cascade Sorting Order
mugi_uno
3
4.4k
Next.js App Router での MPA フロントエンド刷新
mugi_uno
40
26k
コロナ禍 Frontend おさらい
mugi_uno
1
500
Toyama.rb
mugi_uno
1
240
Other Decks in Programming
See All in Programming
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.3k
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
190
Web Framework Benchmark Battle 2026, Any%
a_matsuda
2
2.7k
気持ちぃ〜角丸 Squircle
ryu1013
0
320
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
170
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
890
APNsからLive Activityを開始する話
yumnumm
0
170
dotNET_vulnclicker_intro.pdf
deka_morita
0
150
PumaからFalconに移行したRailsアプリケーションでの実践
falcon8823
0
190
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.2k
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
190
Featured
See All Featured
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
4
4.4k
The Pragmatic Product Professional
lauravandoore
37
7.5k
BBQ
matthewcrist
90
10k
Crafting Experiences
bethany
1
390
Prompt Engineering for Job Search
mfonobong
0
520
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.9k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
580
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
330
Practical Orchestrator
shlominoach
192
12k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
400
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Git: the NoSQL Database
bkeepers
PRO
433
67k
Transcript
%FFQ%JWFJOUP3FBDU4USFBN4FSJBMJ[F /PEFֶԂ )BKJNF.VHJTIJNB$ZCP[V*OD
!NVHJ@VOP )BKJNF.VHJTIJNB $ZCP[V*OD 'SPOUFOE&YQFSU5FBN
લఏࣝ
3FBDUͱ4USFBN w 3FBDUWҎ߱ɺ4USFBNܦ༝ͰͷϨϯμϦϯάΛαϙʔτ w /PEF4USFBNSFOEFS5P1JQFBCMF4USFBN w 8FC4USFBNSFOEFS5P3FBEBCMF4USFBN w "QQ3PVUFSͰ෦తʹར༻͍ͯ͠Δ vercel/next.js
- src/server/app-render/app-render.tsx
34$1BZMPBEͱ4FSJBMJ[F%FTFSJBMJ[F w 4FSWFS$PNQPOFOUͷϨϯμϦϯά݁Ռ 34$1BZMPBEͱݺΕΔܗͰ4USFBNʹ͞ΕΔ w Ұ෦ͷσʔλಠࣗͷܗࣜͰ4FSJBMJ[F%FTFSJBMJ[F͞ΕΔ FH$MJFOU$PNQPOFOUʹ͞ΕΔ1SPQTͳͲ createFromReadableStream() renderToReadableStream() Server
Browser 34$ϨϯμϦϯά݁Ռ 34$1BZMPBE Stream Serialize Deserialize 34$1BZMPBE ϨϯμϦϯάIZESBUF
؆୯ͳαϯϓϧΞϓϦΛ༻ҙͯ͠ΈΔ w "TZOD$PNQPOFOUͷϖʔδ w ͭͷ$MJFOU$PNQPOFOU w 1SPNJTFΛ͢ w ยํޭɺยํࣦഊ w
VTF Ͱ1SPNJTFΛػ w 3FGSFTI#VUUPO ˠSPVUFSSFGSFTI ΛݺͿϘλϯ
w SPVUFSSFGSFTI ͷޙʹ%FW5PPMTͰ֬ೝ 4USFBNͷதʁ
4USFBNͷதʁ ढจʜʁ w SPVUFSSFGSFTI ͷޙʹ%FW5PPMTͰ֬ೝ
͜ͷηογϣϯͷςʔϚ w 4USFBNͷத͕ͳΜͱͳ͘ಡΊΔΑ͏ʹͳΔ w 4FSJBMJ[F%FTFSJBMJ[F͕ԿΛͬͯΔ͔ͪΐͬͱΘ͔Δ w ࢲ࠷ۙ·Ͱढจʹݟ͑ͯͨͷͰ͖ͬͱେৎ
ҙ w "QQ3PVUFSճͰ͕͢ɺ࣮΄΅3FBDUͷͰ͢ w ͓ͦΒ࣮͘Ͱ͙͢ʹཱͭͰ͋Γ·ͤΜ ʢσόοάͱ͔Ͱͨ·ʹ͑Δ͔ʣ
4USFBNσʔλͷجૅࣝ
4USFBNσʔλͷجૅࣝ
$IVOL w جຊߦʹ$IVOL w *% 5BH 3PXͷߏ 4USFBNσʔλͷجૅࣝ
w ߦʹෳ$IVOLؚ͕·ΕΔέʔε͋Δ w όΠφϦσʔλͷ߹αΠζ͕ࢦఆ͞Ε͓ͯΓɺ ޙଓνϟϯΫ͕࿈͍݁ͯ͠Δ w %FW5PPMTͳͲͰݟΔ߹ʹҙ͕ඞཁ 4USFBNσʔλͷجૅࣝ *%ͷ$IVOL͕*%ͷ$IVOLͷඌͱ࿈݁
*% w $IVOLΛҰҙʹಛఆ͢ΔΩʔ w ਐ w ࢀর࣌ͷඥ͚ͮʹར༻ w ॱংෆఆ 4USFBNσʔλͷجૅࣝ
5BH w σʔλͷछผऔΓѻ͍ํΛද͢ w * ) 5 & % 8
3 1ͳͲଟ͕͘ଘࡏ w ଟ͘಄จࣈʢ**NQPSU %%FCVHͳͲ w ແ͍߹3FBDUπϦʔؔ࿈͔୯७ͳσʔλ ίʔυ্Ͱl.PEFMzͱݺΕΔ 4USFBNσʔλͷجૅࣝ
w σʔλຊମ w 5BHʹԠͯ͡ॲཧ͞ΕΔ w େ+40/4USJOH 4USFBNσʔλͷجૅࣝ 3PX PS$IVOL
;FSP$IVOL ศ্ٓɺຊࢿྉͰ͜͏ݺͼ·͢ʣ w *%ͷ.PEFM$IVOL͕ϨϯμϦϯάͷى w $MJFOUଆͰͷඳը˺;FSP$IVOLͷඳը w ಡΉͱ͖*%ͷ$IVOL͔Βݟ͍ͯ͘ͱྑ͍
4USFBN5BHͷྫ
*ˠ*NQPSU w ΫϥΠΞϯτίϯϙʔωϯτͷ*NQPSU༻$IVOL w XFCQBDLͰ͋Ε@@XFCQBDL@SFRVJSF@@͕ݺΕΔ w *NQPSU͖͢ϑΝΠϧίϯϙʔωϯτใΛؚΉ 7:I[9842,["360","static/chunks/app/sample/ page-7f3480f94493b7cb.js"],"SuccessClient"] [
9842, ["360", "static/chunks/app/sample/page-7f3480f94493b7cb.js"], "SuccessClient" ] ※rowΛܗͨ͠ͷ
&ˠ&SSPS w Τϥʔใ$IVOL w 1SPEVDUJPO࣌EJHFTUͷΈͱͳΔ b:E{"digest":"193452068"} b:E{"digest":"193452068","message":"Error: PROMISE REJECTED","stack":""} Development
Production
5ˠ5FYU w CZUFΑΓେ͖͍จࣈྻผͷ$IVOLͱͳΔ w 5ͷޙʹαΠζ͕ਐͰ༩͞ΕΔ w ˣQBE4UBSU BCDEF Λ1SPQTʹͨ͠߹ͷྫ
8:T7d0,abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeab cdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdea bcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde....(লུ) ※"7d0" → 2000
5ˠ5FYU w $IVOLΛ͚Δཧ༝ίʔυ্ʹίϝϯτʹॻ͍ͯ͋Δ w +40/ͱͷೋॏΤϯίʔυύʔεΛආ͚ΔͨΊ w Τεέʔϓ͕ଟ͍จࣈྻͷ߹ʹίϯύΫτʹ͢ΔͨΊ
4USFBNͱ4FSJBMJ[F
4FSJBMJ[F%FTFSJBMJ[Fͷجຊ w .PEFM$IVOLͷ4FSJBMJ[F%FTFSJBMJ[Fɺ ࣮+40/TUSJOHJGZ͓Αͼ+40/QBSTFΛݺΜͰ͍Δ͚ͩ w ͦΕͧΕSFQMBDFSSFWJWFSΛͯ͠มॲཧΛΧελϚΠζ͍ͯ͠Δ packages/react-client/src/ReactFlightClient.js ※Deserializeଆ packages/react-server/src/ReactFlightServer.js ※Serializeଆ
;FSP$IVOLΛ͍ͯΈΔ [ "Hd4i-EanmGD0JpIffHyHC", [ [ [ "", { "children": ["sample",
{ "children": ["__PAGE__", {}] }] }, "$undefined", "$undefined", true ], [ "", { "children": [ "sample", { "children": ["__PAGE__", {}, ["$L1", "$L2", null]] }, [ "$", "$L3", null, { ... ˞ՄಡੑͷͨΊܗͨ͠ͷ
[ "Hd4i-EanmGD0JpIffHyHC", [ [ [ "", { "children": ["sample", {
"children": ["__PAGE__", {}] }] }, "$undefined", "$undefined", true ], [ "", { "children": [ "sample", { "children": ["__PAGE__", {}, ["$L1", "$L2", null]] }, [ "$", "$L3", null, { ... w શମ+40/4USJOH ;FSP$IVOLΛ͍ͯΈΔ
[ "Hd4i-EanmGD0JpIffHyHC", [ [ [ "", { "children": ["sample", {
"children": ["__PAGE__", {}] }] }, "$undefined", "$undefined", true ], [ "", { "children": [ "sample", { "children": ["__PAGE__", {}, ["$L1", "$L2", null]] }, [ "$", "$L3", null, { ... #VJME*% w Ϗϧυ͝ͱͷ*% w ݱࡏͷϏϧυͱࠩҟ͕͋Δ߹ɺ .1"φϏήʔγϣϯʹΓସΘΔ ;FSP$IVOLΛ͍ͯΈΔ
[ "Hd4i-EanmGD0JpIffHyHC", [ [ [ "", { "children": ["sample", {
"children": ["__PAGE__", {}] }] }, "$undefined", "$undefined", true ], [ "", { "children": [ "sample", { "children": ["__PAGE__", {}, ["$L1", "$L2", null]] }, [ "$", "$L3", null, { ... w จࣈྻͰ͔Β࢝·Δͷ ಛघͳ4FSJBMJ[F%FTFSJBMJ[F͕ඞཁͳͷ ;FSP$IVOLΛ͍ͯΈΔ
ͷಡΈํ $L3
ͷಡΈํ $L3 ಛघͳ4FSJBMJ[FΛࣔ͢ϚʔΧʔ
ͷಡΈํ $L3 4FSJBMJ[F%FTFSJBMJ[Fͷछྨ
ͷಡΈํ $L3 छྨʹԠͨ͡มʹ༻͍Δσʔλ ଞ$IVOLͷ*%ͳͲ
ಛघͳ4FSJBMJ[F%FTFSJBMJ[F
4FSJBMJ[FՄೳͳͷ IUUQTKBSFBDUEFWSFGFSFODFSFBDUVTFDMJFOUTFSJBMJ[BCMFUZQFT 3FBDUυΩϡϝϯτVTFDMJFOUͷઆ໌ΑΓൈਮ ɾ'PSN%BUB ɾ#MPC ɾ3FBEBCMF4USFBN ɾ"TZOD*UFSBUPS ࢀߟ কདྷతʹαϙʔτ͞Εͦ͏ͳͷ
4FSJBMJ[FՄೳͳͷ IUUQTKBSFBDUEFWSFGFSFODFSFBDUVTFDMJFOUTFSJBMJ[BCMFUZQFT 3FBDUυΩϡϝϯτVTFDMJFOUͷઆ໌ΑΓൈਮ ɾ'PSN%BUB ɾ#MPC ɾ3FBEBCMF4USFBN ɾ"TZOD*UFSBUPS ࢀߟ কདྷతʹαϙʔτ͞Εͦ͏ͳͷ ୯७ͳ+40/͚ͩͰରԠෆՄͳͷΛؚΉ
ˠಛघͳ4FSJBMJ[F%FTFSJBMJ[F͕ඞཁ
4FSJBMJ[F%FTFSJBMJ[Fͷ۩ମྫ
3FBDU&MFNFOU w 3FBDU&MFNFOU5VQMFͷܗʹ4FSJBMJ[F͞ΕΔ w ઌ಄ཁૉ͕ͷΈͷ5VQMF͕3FBDU&MFNFOUͱஅ͞ΕΔ w 5VQMFɺˠ5ZQFˠ,FZˠ1SPQTͷॱং [ "$", "$L7",
"key-1", { "description": "abcde", "date": "$D2024-04-24T15:01:40.265Z", "promise": "$@8" } ] Ͱݻఆ EJWͳͲͷ5ZQFPS *NQPSU$IVOLͷࢀর Ϧετඳը࣌ͳͲͷLFZ 1SPQT
Ұ෦ͷݻఆ w +BWB4DSJQUݻ༗ͷͰ+40/ͰදݱͰ͖ͳ͍ͷ $Infinity $-Infinity $NaN $-0 $undefined Infinity -Infinity
NaN -0 undefined ˞ ͪͳΈʹɺϩδοΫ্Ͱͷ࣍ͷ̍จࣈͰఆ͞Ε͓ͯΓɺ ্هͷ߹*/Vͷ࣌Ͱॲཧ͕ذ͍ͯ͠Δɻ
%BUF w % %BUFΦϒδΣΫτͷUP+40/ ࣮ߦ݁Ռ w %FTFSJBMJ[F࣌OFX%BUF Ͱ%BUFΦϒδΣΫτʹ͞ΕΔ $D2024-04-13T08:10:15.385Z
$MJFOU$PNQPOFOU -B[Z w - *NQPSU$IVOL*% w 4FSWFSଆͰɺ4FSJBMJ[Fͱಉ࣌ʹ*NQPSU$IVOLඞͣ࡞ΒΕΔ $L7 7:I[9842,["360","static/chunks/app/sample/ page-7f3480f94493b7cb.js"],"SuccessClient"]
Chunk ReactFlightServer - serializeClientReference *NQPSU$IVOLͷ࡞ૹ৴ - *%ͷܗʹγϦΞϥΠζ
$MJFOU$PNQPOFOU -B[Z w $MJFOUଆͰ3FBDUMB[ZͰ *NQPSU$IVOLΛػ͢Δܗʹ%FTFSJBMJ[F ReactFlightClient - parseModelString
'VODUJPO 4FSWFS"DUJPO w ' 4FSWFS"DUJPOใͷ$IVOL*% w Ϗϧυ࣌Ͱ4FSWFS3FGFSFODFͱͯؔ͠ʹ*%͕ൃߦ͞Ε͍ͯΔ $F8 .next/server/server-reference-manifest.json 8:{"id":"7de9e92d780a000fa18feb74a7ec9a83a73ddc8f","bound":null}
{ "node": { "7de9e92d780a000fa18feb74a7ec9a83a73ddc8f": { "workers": { "app/page": "(rsc)/./node_modules/(লུ)" }, ... Chunk
'VODUJPO 4FSWFS"DUJPO w $MJFOUଆͰɺ֘*%Λͱʹ 4FSWFSଆʹϦΫΤετΛ͛Δ৽ͨͳؔͱͯ͠%FTFSJBMJ[F DSFBUF4FSWFS3FGFSFODF1SPYZ ܦ༝Ͱ $MJFOUଆͰ࣮ߦՄೳͳؔΛऔಘ
1SPNJTF w ! 1SPNJTFใͷ$IVOL*% w ࢀরઌ$IVOLʹ3FTPMWF3FKFDUͷใؚ͕·ΕΔ $@9 9:"PROMISE RESOLVED" Chunk
1SPNJTF w 4FSWFSଆͰ4FSJBMJ[Fରͷ1SPNJTF͕ղܾ͢Δͱ4USFBNʹૹ৴ w $MJFOUଆͰ*%͕߹க͢Δ$IVOLΛػ͢Δ ReactFlightServer - serializeThenable() ReactFlightClient -
parseModelString() ※chunkࣗମ͕thenable
কདྷతʹ͑Δ͔͠Εͳ͍ػೳ
$POTPMFͷ4FSWFSˠ$MJFOUϦϨʔ w <'MJHIU>*OTUSVNFOUUIF$POTPMFJOUIF34$&OWJSPONFOUBOE3FQMBZ -PHTPOUIF$MJFOU 🔗IUUQTHJUIVCDPNGBDFCPPLSFBDUQVMM w FOBCMF4FSWFS$PNQPOFOU-PHTϑϥά͕ඞཁͰ͋Γɺ /FYUKTW࣌Ͱඇαϙʔτ w
։ൃ࣌ͷརศੑ্ͷͨΊͷػೳ w 4FSWFSଆͰͷDPOTPMF࣮ߦ࣌ʹ4USFBNܦ༝Ͱ$MJFOUଆʹྲྀ͢ ˠ$MJFOUଆͰಉ͡DPOTPMFͷϝιουΛ࣮ߦ͠ϩάΛग़ྗ͢Δ w 4USFBN5BH8ʢ$͡Όͳ͍ͷʜʁʣ
packages/react-server/src/ReactFlightServer.js w 4FSWFSଆͰDPOTPMFͷϝιουʹύονΛ͍ͯͯΔ $POTPMFͷ4FSWFSˠ$MJFOUϦϨʔ
3FBEBCMF4USFBN"TZOD*UFSBUPSͷ4FSJBMJ[F w <'MJHIU>&ODPEF3FBEBCMF4USFBNBOE"TZOD*UFSBCMFT 🔗IUUQTHJUIVCDPNGBDFCPPLSFBDUQVMM w FOBCMF'MJHIU3FBEBCMF4USFBNϑϥά͕ඞཁͰ͋Γɺ /FYUKTW࣌Ͱඇαϙʔτ w 4USFBN5BHʹ3
S 9 Y $͕Ճ͞Ε͍ͯΔ w 3 94USFBNͷ։࢝ S Y#:0#4USFBNͷαϙʔτ࣌ $4USFBNͷऴྃΛද͢ w 4FSWFS$PNQPOFOU4FSWFS"DUJPOͰ 4USFBNΛऔΓճͤΔΑ͏ʹͳΔ͔ʁ
·ͱΊ
w গ͠ಡΊΔΑ͏ʹͳͬͨΑ͏ͳؾ͕͢Δ ಄ͷ4USFBNΛ͏Ұ
·ͱΊ w 4USFBN5BHʹҙ͢Δͱ$IVOLͷछྨͷผ͕ͭ͘ w 4FSJBMJ[F͞ΕͨσʔλΛݟΔͱछྨඥ͚ͮͷ͕ͭ͘͠ w ͋ͱ3FBDUࣗମͷίʔυΛಡΊͳΜͱ͔ͳΔؾ͕͢Δ w 4FSJBMJ[F%FTFSJBMJ[FͷίʔυΛݟͯΈΔͱɺ ࠓޙ"QQ3PVUFSʹདྷͦ͏ͳػೳ͕ಁ͚ͯݟָ͖͍͑ͯͯ͠
https://cybozu.co.jp/recruit/ αΠϘζͷϑϩϯτΤϯυΛ࠷ߴʹ͢ΔؒΛืूதͰ͢ʂ