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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
190
フロントエンドエキスパートチームの解散は 「いい話」なのか?
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
一人だけ、Kiroが静止する日
hideg
0
140
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
9.2k
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
320
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
1
680
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
460
テストを司るデーモンに会いに行く 〜隔離した仮想マシンでテストを通すまで〜
h1d3mun3
1
600
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1.2k
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
120
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
430
Security issues being discussed on Web Platforms
petamoriken
0
1.4k
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
410
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
220
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Mobile First: as difficult as doing things right
swwweet
225
10k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
WENDY [Excerpt]
tessaabrams
14
40k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
[SF Ruby Conf 2025] Rails X
palkan
3
1.4k
Facilitating Awesome Meetings
lara
57
7.2k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
510
Darren the Foodie - Storyboard
khoart
PRO
4
4k
Testing 201, or: Great Expectations
jmmastey
46
8.3k
GraphQLとの向き合い方2022年版
quramy
50
15k
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/ αΠϘζͷϑϩϯτΤϯυΛ࠷ߴʹ͢ΔؒΛืूதͰ͢ʂ