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
7 principles for rich web apps And how next.js ...
Search
Yosuke Furukawa
PRO
September 09, 2023
Programming
6
3.6k
7 principles for rich web apps And how next.js achieves these principles
ジャムスタックチョットデキル 2023/09/09
Yosuke Furukawa
PRO
September 09, 2023
Tweet
Share
More Decks by Yosuke Furukawa
See All by Yosuke Furukawa
Welcome JSConf.jp 2024
yosuke_furukawa
PRO
1
3.8k
tc39 x jsconf.jp Panel Discussion 2024
yosuke_furukawa
PRO
0
190
Removing Corepack
yosuke_furukawa
PRO
9
1.5k
JavaScript Runtime とはなにか
yosuke_furukawa
PRO
15
2.6k
Strip Types と Storage
yosuke_furukawa
PRO
4
370
Module Harmony について
yosuke_furukawa
PRO
3
1.6k
LTのやり方
yosuke_furukawa
PRO
16
2.4k
AppRouter Panel Talk
yosuke_furukawa
PRO
3
750
Node.js v22 で変わること
yosuke_furukawa
PRO
13
5.8k
Other Decks in Programming
See All in Programming
楽しく向き合う例外対応
okutsu
0
580
React 19アップデートのために必要なこと
uhyo
8
1.4k
ナレッジイネイブリングにAIを活用してみる ゆるSRE勉強会 #9
nealle
0
140
コミュニティ駆動 AWS CDK ライブラリ「Open Constructs Library」 / community-cdk-library
gotok365
2
230
dbt Pythonモデルで実現するSnowflake活用術
trsnium
0
250
GAEログのコスト削減
mot_techtalk
0
130
ソフトウェアエンジニアの成長
masuda220
PRO
12
2.1k
Kotlinの開発でも AIをいい感じに使いたい / Making the Most of AI in Kotlin Development
kohii00
4
750
Rails アプリ地図考 Flush Cut
makicamel
1
130
CSS Linter による Baseline サポートの仕組み
ryo_manba
1
150
Go 1.24でジェネリックになった型エイリアスの紹介
syumai
2
270
CI改善もDatadogとともに
taumu
0
190
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
51
7.4k
A Tale of Four Properties
chriscoyier
158
23k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Agile that works and the tools we love
rasmusluckow
328
21k
The Invisible Side of Design
smashingmag
299
50k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Navigating Team Friction
lara
183
15k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
Why Our Code Smells
bkeepers
PRO
336
57k
Visualization
eitanlees
146
15k
BBQ
matthewcrist
87
9.5k
Transcript
7 principles for rich web apps And how next.js achieves
these principles @ δϟϜελοΫνϣοτσΩϧΧϯϑΝϨϯε in த yosuke_furukawa / 2023-09-09
X(Twitter): @yosuke_furukawa Github: yosuke-furukawa
JSConf.jp ticket page is open. ࠓΦϑϥΠϯͱΦϯϥΠϯͷϋ ΠϒϦου։࠵༧ఆ ΦϯϥΠϯ10݄ࠒʹެ։͠·͢ɻ ઌߦͯ͠དྷͯ͘ΕΔํࠓͷϖʔδ ͔Βདྷ͍ͯͩ͘͞ʂ
Looong Long time ago... From 2014 ※
ϦονͳΞϓϦέʔγϣϯͷͨΊͷ7ͭͷݪଇ ͱ͍͏λΠτϧͰ༁هࣄΛग़ͨ͠ • Vercel ݱ CEO ͷ Guillermo Rauch ࢯ͕ॻ͍ͨهࣄΛ༁ͨ͠ͷ
• ࠓͰࢀߟʹͳΔΑ͏ͳݪଇ
ϦονͳΞϓϦέʔγϣϯͷͨΊͷ7ͭͷݪଇ 1.αʔόʔ͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰͳ͍ɻ 2.ϢʔβʔೖྗʹਝʹରԠ͠Α͏ 3.σʔλͷมߋʹԠ͠Α͏ 4.σʔλมߋΛαʔόʔͱͱʹίϯτϩʔϧ͠Α͏ 5.historyΛյ͖͢͡Όͳ͍ɺhistoryΛ֦ு͠Α͏ 6.ίʔυͷߋ৽ΛPush͠Α͏ 7.ৼΔ͍Λ༧ଌ͠Α͏
ϦονͳΞϓϦέʔγϣϯͷͨΊͷ7ͭͷݪଇ 1.αʔόʔ͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰͳ͍ɻ 2.ϢʔβʔೖྗʹਝʹରԠ͠Α͏ 3.σʔλͷมߋʹԠ͠Α͏ 4.σʔλมߋΛαʔόʔͱͱʹίϯτϩʔϧ͠Α͏ 5.historyΛյ͖͢͡Όͳ͍ɺhistoryΛ֦ு͠Α͏ 6.ίʔυͷߋ৽ΛPush͠Α͏ 7.ৼΔ͍Λ༧ଌ͠Α͏ /FYUKT͜ΕΒͷݪଇΛ͍͔ͭ͘ୡ͍ͯ͠Δ
αʔόʔ͕ϖʔδΛϨϯμϦ ϯά͢ΔͷҙͰͳ͍
αʔό͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰ ͳ͍ɻ •ҙͰͳ͍ => ඞਢͰ͋Δ •ͭ·ΓϦονͳΣϒΞϓϦέʔγϣϯʹࣄલͷϨϯμϦϯά͕ඞ ਢͰ͋Δͱݴ͍ͬͯΔɻ •ͳ͔ͥʁ
αʔό͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰ ͳ͍ɻ •ϥϯυτϦοϓʹ͔͔Δ࣌ؒΛͬͯ·͔͢ʁ •࣌ؒɿ •Stanford͔ΒBoston·Ͱޫͷ͞Ͱ43.2ms •ޫϑΝΠόʔͰߦ͘ͱ85ms͔͔Δ
αʔό͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰ ͳ͍ɻ •ϥϯυτϦοϓճΛͬͯ·͔͢ʁ •CSRͱSSRͰൺֱ͢Δ 4FSWFS CSR ۭͷHTMLऔಘ JavaScriptऔಘ API fetch
4FSWFS SSR HTMLऔಘ JavaScriptऔಘ
αʔό͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰ ͳ͍ɻ •ϥϯυτϦοϓճΛͬͯ·͔͢ʁ •CSRͱSSRͰൺֱ͢Δ 4FSWFS CSR ۭͷHTMLऔಘ JavaScriptऔಘ API fetch
4FSWFS SSR HTMLऔಘ $43ճ443ճ ˞ݫີͳͰͳ͍ɻ5$1ͷϥϯυτϦοϓͱ͍͏ҙຯͰճҟͳΔɻ
αʔό͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰ ͳ͍ɻ •ݴ͍͍ͨͷ: •ࣄલʹϨϯμϦϯά͠ͳ͍ͱϢʔβʔͷͪ࣌ؒ͘ͳͬͯ͠· ͏ͱ͍͏͜ͱ •SEOͱ͔ͦ͏͍͏͜ͱͱແؔʹ࠷దͳUXΛఏڙ͢ΔͳΒࣄલʹ ϨϯμϦϯάΛ͢Δํ͕ྑ͍
αʔό͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰ ͳ͍ɻ •Next.js͢Ͱʹ͜ͷ෦ΛϨϯμϦϯάʹؔ͢ΔιϦϡʔγϣϯΛ͍ ͔ͭ͘ఏڙ͢Δ͜ͱͰୡ͍ͯ͠Δɻ •SSR •SSG •ISR •͞Βʹ Vercel ͱΈ߹ΘͤΔͱCDNͰͷΩϟογϡ༗ޮʹɻ
ϢʔβͷೖྗʹਝʹԠ͠ Α͏
ϢʔβʔͷೖྗʹਝʹԠ͠Α͏ •͖ͬ͞ͷϨϯμϦϯά͕දࣔ͢Δ·Ͱͷ࣌ؒʹରͯ͠ͷͩͱ͢Δͱ ͬͪ͜ૢ࡞ʹରͯ͠ͷ •ૢ࡞ͨ͜͠ͱʹରͯ͠ͷϑΟʔυόοΫΛૣ͘Ͱ͖ΔΑ͏ʹ͢Δ
ϢʔβʔͷೖྗʹਝʹԠ͠Α͏ •࣮ͷճΓʹ͋ΔΞϓϦέʔγϣϯΠϯλϥΫγϣϯʹରͯ͠ߴ ʹԠ͢ΔΑ͏ʹग़དྷ͍ͯΔɻGoogleͷྫ
ϢʔβʔͷೖྗʹਝʹԠ͠Α͏ •્ͯ͠͠·͏ཁҼʹͳΔͷͳʹ͔ •ڊେͳ JavaScript ϑΝΠϧ͕͋Δͱ࣮ૢ࡞Ͱ͖ΔΑ͏ʹͳΔ·Ͱ ͷ͕࣌ؒඇৗʹ͘ͳΔ •ͦͦ͜͏͍͏շదͳϑΟʔυόοΫΛͨΒ͢ͷJSͷ࡞༻ʹ ΑΔӨڹ͕େ͖͍ •ͳͷʹͰ͔͍JS͕͋ΔͱίϯύΠϧ=>࣮ߦͰͨ͘͞Εͯ͠·͏
ϢʔβʔͷೖྗʹਝʹԠ͠Α͏ •Next.jsίʔυεϓϦοτϖʔδ୯ҐͰεϓϦοτͯ͘͠Ε͍ͯΔ •/settings ʹඞཁͳίʔυͱ /login ʹඞཁͳίʔυΛ͚ͯඞཁͳϖʔ δʹ͚ͩඞཁͳίʔυؚ͕·ΕΔΑ͏ʹ͍ͯ͠Δ •͔݁͠ߏ಄͕ྑ͍ɻ React /
react-dom ͳͲͷසग़͢ΔϥΠϒϥϦͷ ͷͲ͜Ͱར༻͞ΕΔͷͰͦΕڞ௨Խ͞Εͨίʔυͱͯ͠࠶ར ༻͞Εׂ͘͢͞Ε͍ͯΔɻ
σʔλͷมߋʹԠ͠Α͏
σʔλͷมߋʹԠ͠Α͏ •ϢʔβϏϦςΟͷ •σʔλ͕มߋ͞Ε͍ͯΔͷʹΘ͟Θ͟ϦϩʔυϘλϯΛԡ͞ͳ͍ͱ͍ ͚ͳ͍Α͏ͳ࡞Γʹ͢Δ͖Ͱͳ͍ •Guillermo Rauchࢯͷ͏Ұͭͷஶ໊ϥΠϒϥϦ socket.io ͳͲΛར༻ ͯ͠σʔλͷมߋʹଈ࠲ʹԠ͢Δ͖ͱ͍͏ •͋Μ·ΓNext.jsؔͳ͍
σʔλͷมߋʹԠ͠Α͏ •ݴ͏қ͘ߦ͏͠ •Firestoreͱ͔socket.ioͱ͔Λۦ͢Δײ͡ʹͳΔ
σʔλมߋΛαʔόʔͱͱ ʹίϯτϩʔϧ͠Α͏
σʔλมߋΛαʔόʔͱͱʹίϯτ ϩʔϧ͠Α͏ •͜ΕϢʔβϏϦςΟͷ •Service Worker ܥ •σʔλૹ৴ͱ͔ʹࣦഊͯ͠ϦτϥΠ͢ΔΈΛ࡞ͬͨΓ •όοΫάϥϯυͰσʔλಉظͯ͠ΩϟογϡΛΦϑϥΠϯͰ͑Δ Α͏ʹ͠Α͏ͱ͍͏ •Next.js͋Μ·Γؔͳ͍
σʔλมߋΛαʔόʔͱͱʹίϯτ ϩʔϧ͠Α͏ •͜͏͍͏ʮ͓ͯͳ͠ʯ͕͋Δͱྑ͍ͱ͍͏খ͍͚͞Ͳେࣄͳ •ྫ͑ɿ •Ϣʔβʔ͕ΦϑϥΠϯʹͳ͔ͬͨͲ͏͔ navigator.onLine ͰଌΕΔɻΦϑϥΠϯʹ ͳͬͯΔͳΒͦΕΛදࣔͯ͋͛͠Δ͖ •APIͷλΠϜΞτͱ͔ϒϥβͤʹͯ͠ͳ͍͔ʁࣗͨͪͰࣄલʹλΠϜΞτ ΩϟϯηϧΛ࣮ͨ͠΄͏͕ྑ͍
•403ΤϥʔʢೝূΤϥʔʣ͕ൃੜ͍ͯ͠ΔͳΒϩάΠϯը໘Λݟͤͯ͋͛Δ͖ •͏͔ͬΓϒϥβดͨ࣌͡ʹ beforeUnload ͰҰճ֬ೝ͢Δͱ͔
ɾσʔλͷมߋʹԠ͠Α͏ ɾσʔλมߋΛαʔόʔͱͱʹίϯτϩʔϧ ͠Α͏ ͜ͷ̎ͭͷݪଇNext.jsؔͳ͍ ͚ͩͲɺ࣮ͷ্ͰؾΛ͚ͭΔ͖ϙΠϯτ
historyΛյ͖͢͡Όͳ͍ɺ historyΛ֦ு͠Α͏
historyΛյ͖͢͡Όͳ͍ɺhistoryΛ ֦ு͠Α͏ •Single Page Application ͋Δ͋Δɺhistory͕յΕͨUI • FYBNQMFDPN FYBNQMFDPN FYBNQMFDPN
εΫϩʔϧ͢Δ ϦϯΫΛΫϦοΫͯ͠ભҠ ͢Δ ભҠޙʹΔ εΫϩʔϧҐஔ͕ ࠷ॳʹΔ
historyΛյ͖͢͡Όͳ͍ɺhistoryΛ ֦ு͠Α͏ •ଞʹ: •͍͍Ͷ͚ͨ͠Ͳɺ͍͍Ͷ͕ͬͨΒফ͑ͯͨʢ࣮ࡍʹՃ͞Εͯ Δʣ •ΞίʔσΟΦϯ։͍ͨޙʹϖʔδભҠͯͬͨ͠ΒΞίʔσΟΦϯ ดͯͯ͡ભҠ͕յΕΔͱ͔
historyΛյ͖͢͡Όͳ͍ɺhistoryΛ ֦ு͠Α͏ •͜ΕԿͰى͖Δ͔ͱݴ͏ͱɿෳ߹తͳཁҼ •ϖʔδભҠલʹ͍ΔҐஔΛϒϥβຊͳΒ֮͑ͯΔ •͚ͩͲͬͨ࣌ʹ history api ΛͬͯͯΔͷ͕ૣͯ͘ίϯςϯπ ͕·ͩͳ͍ͱ͔ͦ͏͍͏࣌ʹى͖Δ •BFCacheͱ͔Navigation
API ͱ͔ Scroll Resolution API ͱ͔ͦ͏͍ ͏ϒϥβ͔Βͷαϙʔτ૿͑ͯΔ͕·ͩ͑ͳ͍ڥଟ͍ͷ Ͱɺ࣮ࡍʹ݁ߏͪ͜ΒଆͰͳΜͱ͔͠ͳ͍ͱ͍͚ͳ͍
historyΛյ͖͢͡Όͳ͍ɺhistoryΛ ֦ு͠Α͏ •Next.jsͩͱεΫϩʔϧҐஔΛ͢ͱ͍͏ҙຯͰɾɾɾ •Page router εΫϩʔϧҐஔΛ֮͑ͯ͘Εͯͯɺϖʔδ͕ϨϯμϦϯά͞Ε͔ͯΒεΫϩʔϧͯ͠ ͘ΕΔ •Experimental Ͱ Scroll
Restoration ϓϩύςΟͰͷ੍ޚͯ͘͠ΕΔɻ •App routerݱ࣌ͩͱͦͷ͋ͨΓͷ͜ͱΩϟογϡʹͤͯΔʢϒϥβʹͤͯΔײ͡ʁʣ •εΫϩʔϧճؼҎ֎ͷ͜ͱԿͯ͠ͳ͍ͷͰɺ࣮ʹؾΛ͚ͭͳ͍ͱ͍͚ͳ͍ •ࣾͰOSSͰϥΠϒϥϦ࡞ͬͯղܾ͢Δਓͨͪνϥϗϥ •https://github.com/recruit-tech/location-state
ίʔυͷมߋΛPush͠Α͏
ίʔυͷมߋΛPush͠Α͏ •σʔλ͕ߋ৽͞Εͨʹ͔͔ΘΒͣɺίʔυ͕ͦͷ··ͩͱͲ͏ͳΔ ͔ •ϨϯμϦϯά͕͏·͘ߦ͔ͳ͍Մೳੑ͕͋Δ •ը໘͕ΤϥʔʹͳΔ •த్ͳঢ়ଶͰϨϯμϦϯά͞ΕΔՄೳੑ͕͋Δ •͜͏͍͏ͷΛආ͚ͳ͚Ε͍͚ͳ͍ɻ
ίʔυͷมߋΛPush͠Α͏ •։ൃڥͩͱ Hot code reload ͳͲͷํ๏ͰίʔυͷมߋΛpushͯ͘͠ ΔͷͰΘ͔Γ͍͢ •ຊ൪ڥͩͱ࣮ͳ͔ͳ͔͍͠ •Τϥʔʹͳͬͨ࣌ʹҰճ৽͘͠ϖʔδΛϋʔυϦϩʔυͤ͞Δͱ͔ͷख ͋ΔͬͪΌ͋Δɻ
•ਅ໘ʹΖ͏ͱ͢ΔͱversionͷࠩҟΛݕͯ͠Ͳ͏͢Δ͔Λ࣮͠ ͳ͍ͱ͍͚ͳ͍ɻΤϥʔ͕ى͖͚ͨͩͰஅ͢ΔͱϦϩʔυ͕ଟ͘ͳΔ
ίʔυͷมߋΛPush͠Α͏ •Next.js ͩͱ getServerSideProps ͳͲͷΈࠐΈͷσʔλ fetch ؔΛͬͯΔ߹ʹෆ ߹͕͋ΔͱversionࠩҟΛݕͯ͠Ϧϩʔυͯ͘͠ΕΔ •ͨͩ͜ͷػೳͪΖΜ PageRouter
ͷΈ •App Router ͩͱ Vercel ͕ఏڙͯ͘͠Ε͍ͯΔ Skew Protection Λ͏ඞཁ͕͋Δʢ͘͠ ࣗલͰ࣮ʣ •
ৼΔ͍Λ༧ଌ͠Α͏
ৼΔ͍Λ༧ଌ͠Α͏ •Ϣʔβʔ͕࣍ʹԿΛ͢Δͷ͔Λ༧ଌͯ͠proactiveʹৼΔ͏ •ྫ͑ Google Map ɺͱਐΉͱ࣍ʹͷํʹϦΫΤετ ͕དྷΔͱ༧ଌͯ͠ઌճΓͯ͠σʔλΛऔಘ͢Δ •Google ݕࡧ༧ଌݕࡧͷ݁ՌΛ prefetch
ͯ͠Δ •͜͏͍͏ಈ͖ΛೖΕΔ͖ͩͱ͍͏ɹ
ৼΔ͍Λ༧ଌ͠Α͏ •एׯͦ͠͏ʹݟ͑Δ •Γ͗͢ΔͱσʔλΛ༨ʹऔΓͦ͏͕ͩɺαʔόͷϦιʔεΛ ػతʹ͍ͭͭɺϢʔβͷ͓ͯͳ͠Λߦ͏ͱ͍͏όϥϯεΛͲ͏ औΔ͔ •ͪͳΈʹ Next.js େϢʔβʔͷ͓ͯͳ͠ʹدͬͯΔɻ
ৼΔ͍Λ༧ଌ͠Α͏ •Next.js next/link Λ͏ͱϢʔβͷviewportʹೖͬͨॠؒʹ prefetch͠ʹ͍͘ •େػత͕ͩɺͦΕ͕ Next.js ΛͬͨαʔϏε͕ߴʹݟ͑Δཧ༝ ͩͬͨΓ͢Δ
•ҰํͰؾΛ͚ͭͳ͍ͱϢʔβͷΪΨୣͬͯͦ͏ͩ͠ɺαʔόʹෛ ՙ͔͔ͬͯΔɺαʔόͷϦΫΤετ͕૿͑ͯͯίετ͕͔͔ͬͯ ͳ͍͔֬ೝ͓ͯ͘͠ͱྑ͍
·ͱΊ
·ͱΊ 1.αʔόʔ͕ϖʔδΛϨϯμϦϯά͢ΔͷҙͰͳ͍ɻ => SSR/SSG/ISRͳͲιϦϡʔγϣϯଟ 2.ϢʔβʔೖྗʹਝʹରԠ͠Α͏ => ίʔυεϓϦοτ͕σϑΥϧτͰ࣮͞ΕͯΔ 3.σʔλͷมߋʹԠ͠Α͏
=> Next.js ͰͷରԠͳ͍͕ɺsocket.ioͳͲͱΈ߹Θ࣮ͤͯͰ͖ Δ
·ͱΊ 4.σʔλมߋΛαʔόʔͱͱʹίϯτϩʔϧ͠Α͏ => Next.js ͰͷରԠͳ͍͕ɺService WorkerͳͲͱΈ߹ΘͤΑ͏ 5.historyΛյ͖͢͡Όͳ͍ɺhistoryΛ֦ு͠Α͏ =>
Page Router ͷ߹ɺ࠷ݶͷεΫϩʔϧҐஔΛ֮͑ͯΔɺ App Router Ωϟογϡ͕ڧ͍ͷͰ ͦΕʹͤͯΔ 6.ίʔυͷߋ৽ΛPush͠Α͏ => Next.js page router ͰΈࠐΈͷσʔλϑΣονؔΛ͑ݕͯ͘͠ΕΔ͕ɺ app router ͷ߹ vercel ʹཔΔܗʹͳΔ͔ʢSkew Protectionʣ 7.ৼΔ͍Λ༧ଌ͠Α͏ => next/link ͰػతʹσʔλΛprefetchͯ͘͠ΕΔ
·ͱΊ • ϦονͳΞϓϦέʔγϣϯͷͨΊͷ7ͭͷݪଇΛվΊͯհͭͭ͠ɺ Next.jsͷػೳΛհͨ͠ɻ • Next.js ͳΜͰ͏Μ͚ͩͬʁͬͯͳͬͨ࣌ʹʮϦονͳΞϓϦέʔγϣ ϯͷͨΊͷݪଇʯʹै͏ͨΊͩͱ͍͏ҙݟͰઆಘࡐྉʹ͑Δͱࢥ͏ɻ • ͪΖΜࣗͨͪͰ͜ΕΒΛ࣮Ͱ͖Δͱࢥ͏ͷͰઈରͷඞཁ݅ʹ
ͳΓಘͳ͍ɻ • ͜Ε͔Β৭ʑΞοϓσʔτ͞Ε͍ͯ͘ͱࢥ͏ͷͰࢹ͍ͯ͘͠༧ఆ