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
Deep Dive into React Stream/Serialize
Search
mugi / Hajime Mugishima
April 30, 2024
Programming
2.3k
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
450
サイボウズフロントエンドの活動から考える探究と発信
mugi_uno
1
170
フロントエンドエキスパートチームの解散は 「いい話」なのか?
mugi_uno
8
2.5k
サイボウズフロントエンドの横断活動から考える AI時代にできること
mugi_uno
4
2.1k
令和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
490
Toyama.rb
mugi_uno
1
230
Other Decks in Programming
See All in Programming
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
160
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
360
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.8k
What's New in Android 2026
veronikapj
0
250
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
210
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
960
Built Our Own Background Agent at LayerX #aidevex_findy
layerx
PRO
9
4.8k
Foundation Models frameworkで画像分析
ryodeveloper
1
510
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
140
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
170
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
18k
Featured
See All Featured
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.2k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
440
What does AI have to do with Human Rights?
axbom
PRO
1
2.3k
Are puppies a ranking factor?
jonoalderson
1
3.8k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
230
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
Deep Space Network (abreviated)
tonyrice
0
250
Optimising Largest Contentful Paint
csswizardry
37
3.9k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
210
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
190
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
45k
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/ αΠϘζͷϑϩϯτΤϯυΛ࠷ߴʹ͢ΔؒΛืूதͰ͢ʂ