Slide 1

Slide 1 text

7 principles for rich web apps And how next.js achieves these principles @ δϟϜελοΫνϣοτσΩϧΧϯϑΝϨϯε in த໺ yosuke_furukawa / 2023-09-09

Slide 2

Slide 2 text

X(Twitter): @yosuke_furukawa Github: yosuke-furukawa

Slide 3

Slide 3 text

JSConf.jp ticket page is open. ࠓ೥͸ΦϑϥΠϯͱΦϯϥΠϯͷϋ ΠϒϦου։࠵༧ఆ ΦϯϥΠϯ͸10݄ࠒʹެ։͠·͢ɻ ઌߦͯ͠དྷͯ͘ΕΔํ͸ࠓͷϖʔδ ͔Βདྷ͍ͯͩ͘͞ʂ

Slide 4

Slide 4 text

Looong Long time ago... From 2014 ※

Slide 5

Slide 5 text

ϦονͳΞϓϦέʔγϣϯͷͨΊͷ7ͭͷݪଇ ͱ͍͏λΠτϧͰ຋༁هࣄΛग़ͨ͠ • Vercel ݱ CEO ͷ Guillermo Rauch ࢯ͕ॻ͍ͨهࣄΛ຋༁ͨ͠΋ͷ • ࠓͰ΋ࢀߟʹͳΔΑ͏ͳݪଇ

Slide 6

Slide 6 text

ϦονͳΞϓϦέʔγϣϯͷͨΊͷ7ͭͷݪଇ 1.αʔόʔ͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ͸ͳ͍ɻ 2.Ϣʔβʔೖྗʹਝ଎ʹରԠ͠Α͏ 3.σʔλͷมߋʹ൓Ԡ͠Α͏ 4.σʔλมߋΛαʔόʔͱͱ΋ʹίϯτϩʔϧ͠Α͏ 5.historyΛյ͢΂͖͡Όͳ͍ɺhistoryΛ֦ு͠Α͏ 6.ίʔυͷߋ৽ΛPush͠Α͏ 7.ৼΔ෣͍Λ༧ଌ͠Α͏

Slide 7

Slide 7 text

ϦονͳΞϓϦέʔγϣϯͷͨΊͷ7ͭͷݪଇ 1.αʔόʔ͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ͸ͳ͍ɻ 2.Ϣʔβʔೖྗʹਝ଎ʹରԠ͠Α͏ 3.σʔλͷมߋʹ൓Ԡ͠Α͏ 4.σʔλมߋΛαʔόʔͱͱ΋ʹίϯτϩʔϧ͠Α͏ 5.historyΛյ͢΂͖͡Όͳ͍ɺhistoryΛ֦ு͠Α͏ 6.ίʔυͷߋ৽ΛPush͠Α͏ 7.ৼΔ෣͍Λ༧ଌ͠Α͏ /FYUKT͸͜ΕΒͷݪଇΛ͍͔ͭ͘ୡ੒͍ͯ͠Δ

Slide 8

Slide 8 text

αʔόʔ͕ϖʔδΛϨϯμϦ ϯά͢Δͷ͸೚ҙͰ͸ͳ͍

Slide 9

Slide 9 text

αʔό͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ ͸ͳ͍ɻ •೚ҙͰ͸ͳ͍ => ඞਢͰ͋Δ •ͭ·ΓϦονͳ΢ΣϒΞϓϦέʔγϣϯʹ͸ࣄલͷϨϯμϦϯά͕ඞ ਢͰ͋Δͱݴ͍ͬͯΔɻ •ͳ͔ͥʁ

Slide 10

Slide 10 text

αʔό͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ ͸ͳ͍ɻ •ϥ΢ϯυτϦοϓʹ͔͔Δ࣌ؒΛ஌ͬͯ·͔͢ʁ •࣌ؒɿ •Stanford͔ΒBoston·Ͱޫͷ଎͞Ͱ΋43.2ms •ޫϑΝΠόʔͰߦ͘ͱ85ms͔͔Δ

Slide 11

Slide 11 text

αʔό͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ ͸ͳ͍ɻ •ϥ΢ϯυτϦοϓճ਺Λ஌ͬͯ·͔͢ʁ •CSRͱSSRͰൺֱ͢Δ 4FSWFS CSR ۭͷHTMLऔಘ JavaScriptऔಘ API fetch 4FSWFS SSR HTMLऔಘ JavaScriptऔಘ

Slide 12

Slide 12 text

αʔό͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ ͸ͳ͍ɻ •ϥ΢ϯυτϦοϓճ਺Λ஌ͬͯ·͔͢ʁ •CSRͱSSRͰൺֱ͢Δ 4FSWFS CSR ۭͷHTMLऔಘ JavaScriptऔಘ API fetch 4FSWFS SSR HTMLऔಘ $43ճ443ճ ˞ݫີͳ਺Ͱ͸ͳ͍ɻ5$1ͷϥ΢ϯυτϦοϓͱ͍͏ҙຯͰ͸ճ਺͸ҟͳΔɻ

Slide 13

Slide 13 text

αʔό͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ ͸ͳ͍ɻ •ݴ͍͍ͨͷ͸: •ࣄલʹϨϯμϦϯά͠ͳ͍ͱϢʔβʔͷ଴ͪ࣌ؒ͸௕͘ͳͬͯ͠· ͏ͱ͍͏͜ͱ •SEOͱ͔ͦ͏͍͏͜ͱͱ͸ແؔ܎ʹ࠷దͳUXΛఏڙ͢ΔͳΒࣄલʹ ϨϯμϦϯάΛ͢Δํ͕ྑ͍

Slide 14

Slide 14 text

αʔό͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ ͸ͳ͍ɻ •Next.js͸͢Ͱʹ͜ͷ෦෼ΛϨϯμϦϯάʹؔ͢ΔιϦϡʔγϣϯΛ͍ ͔ͭ͘ఏڙ͢Δ͜ͱͰୡ੒͍ͯ͠Δɻ •SSR •SSG •ISR •͞Βʹ Vercel ͱ૊Έ߹ΘͤΔͱCDNͰͷΩϟογϡ΋༗ޮʹɻ

Slide 15

Slide 15 text

Ϣʔβͷೖྗʹਝ଎ʹ൓Ԡ͠ Α͏

Slide 16

Slide 16 text

Ϣʔβʔͷೖྗʹਝ଎ʹ൓Ԡ͠Α͏ •͖ͬ͞ͷϨϯμϦϯά͕දࣔ͢Δ·Ͱͷ࣌ؒʹରͯ͠ͷ࿩ͩͱ͢Δͱ ͬͪ͜͸ૢ࡞ʹରͯ͠ͷ࿩ •ૢ࡞ͨ͜͠ͱʹରͯ͠ͷϑΟʔυόοΫΛૣ͘Ͱ͖ΔΑ͏ʹ͢Δ࿩

Slide 17

Slide 17 text

Ϣʔβʔͷೖྗʹਝ଎ʹ൓Ԡ͠Α͏ •࣮͸਎ͷճΓʹ͋ΔΞϓϦέʔγϣϯ͸ΠϯλϥΫγϣϯʹରͯ͠ߴ ଎ʹ൓Ԡ͢ΔΑ͏ʹग़དྷ͍ͯΔɻGoogleͷྫ

Slide 18

Slide 18 text

Ϣʔβʔͷೖྗʹਝ଎ʹ൓Ԡ͠Α͏ •્֐ͯ͠͠·͏ཁҼʹͳΔ΋ͷ͸ͳʹ͔ •ڊେͳ JavaScript ϑΝΠϧ͕͋Δͱ࣮͸ૢ࡞Ͱ͖ΔΑ͏ʹͳΔ·Ͱ ͷ͕࣌ؒඇৗʹ௕͘ͳΔ •ͦ΋ͦ΋͜͏͍͏շదͳϑΟʔυόοΫΛ΋ͨΒ͢ͷ΋JSͷ࡞༻ʹ ΑΔӨڹ͕େ͖͍ •ͳͷʹͰ͔͍JS͕͋ΔͱίϯύΠϧ=>࣮ߦͰ௕͘଴ͨ͞Εͯ͠·͏

Slide 19

Slide 19 text

Ϣʔβʔͷೖྗʹਝ଎ʹ൓Ԡ͠Α͏ •Next.js͸ίʔυεϓϦοτ΋ϖʔδ୯ҐͰεϓϦοτͯ͘͠Ε͍ͯΔ •/settings ʹඞཁͳίʔυͱ /login ʹඞཁͳίʔυΛ෼͚ͯඞཁͳϖʔ δʹ͚ͩඞཁͳίʔυؚ͕·ΕΔΑ͏ʹ͍ͯ͠Δ •͔͠΋݁ߏ಄͕ྑ͍ɻ React / react-dom ͳͲͷසग़͢ΔϥΠϒϥϦͷ ΋ͷ͸Ͳ͜Ͱ΋ར༻͞ΕΔͷͰͦΕ͸ڞ௨Խ͞Εͨίʔυͱͯ͠࠶ར ༻͞Ε΍͘͢෼ׂ͞Ε͍ͯΔɻ

Slide 20

Slide 20 text

σʔλͷมߋʹ൓Ԡ͠Α͏

Slide 21

Slide 21 text

σʔλͷมߋʹ൓Ԡ͠Α͏ •ϢʔβϏϦςΟͷ࿩ •σʔλ͕มߋ͞Ε͍ͯΔͷʹΘ͟Θ͟ϦϩʔυϘλϯΛԡ͞ͳ͍ͱ͍ ͚ͳ͍Α͏ͳ࡞Γʹ͢Δ΂͖Ͱ͸ͳ͍ •Guillermo Rauchࢯͷ΋͏Ұͭͷஶ໊ϥΠϒϥϦ socket.io ͳͲΛར༻ ͯ͠σʔλͷมߋʹଈ࠲ʹ൓Ԡ͢Δ΂͖ͱ͍͏࿩ •͋Μ·ΓNext.js͸ؔ܎ͳ͍

Slide 22

Slide 22 text

σʔλͷมߋʹ൓Ԡ͠Α͏ •ݴ͏͸қ͘ߦ͏͸೉͠ •Firestoreͱ͔socket.ioͱ͔Λۦ࢖͢Δײ͡ʹͳΔ

Slide 23

Slide 23 text

σʔλมߋΛαʔόʔͱͱ΋ ʹίϯτϩʔϧ͠Α͏

Slide 24

Slide 24 text

σʔλมߋΛαʔόʔͱͱ΋ʹίϯτ ϩʔϧ͠Α͏ •͜Ε΋ϢʔβϏϦςΟͷ࿩ •Service Worker ܥ •σʔλૹ৴ͱ͔ʹࣦഊͯ͠΋ϦτϥΠ͢Δ࢓૊ΈΛ࡞ͬͨΓ •όοΫάϥ΢ϯυͰσʔλಉظͯ͠ΩϟογϡΛΦϑϥΠϯͰ࢖͑Δ Α͏ʹ͠Α͏ͱ͍͏࿩ •Next.js͸͋Μ·Γؔ܎ͳ͍

Slide 25

Slide 25 text

σʔλมߋΛαʔόʔͱͱ΋ʹίϯτ ϩʔϧ͠Α͏ •͜͏͍͏ʮ͓΋ͯͳ͠ʯ͕͋Δͱྑ͍ͱ͍͏খ͍͚͞Ͳେࣄͳ࿩ •ྫ͑͹ɿ •Ϣʔβʔ͕ΦϑϥΠϯʹͳ͔ͬͨͲ͏͔͸ navigator.onLine ͰଌΕΔɻΦϑϥΠϯʹ ͳͬͯΔͳΒͦΕΛදࣔͯ͋͛͠Δ΂͖ •APIͷλΠϜΞ΢τͱ͔ϒϥ΢β೚ͤʹͯ͠ͳ͍͔ʁࣗ෼ͨͪͰࣄલʹλΠϜΞ΢τ΍ ΩϟϯηϧΛ࣮૷ͨ͠΄͏͕ྑ͍ •403ΤϥʔʢೝূΤϥʔʣ͕ൃੜ͍ͯ͠ΔͳΒϩάΠϯը໘Λݟͤͯ͋͛Δ΂͖ •͏͔ͬΓϒϥ΢βดͨ࣌͡ʹ beforeUnload ͰҰճ֬ೝ͢Δͱ͔

Slide 26

Slide 26 text

ɾσʔλͷมߋʹ൓Ԡ͠Α͏ ɾσʔλมߋΛαʔόʔͱͱ΋ʹίϯτϩʔϧ ͠Α͏ ͜ͷ̎ͭͷݪଇ͸Next.jsؔ܎ͳ͍ ͚ͩͲɺ࣮૷ͷ্ͰؾΛ͚ͭΔ΂͖ϙΠϯτ

Slide 27

Slide 27 text

historyΛյ͢΂͖͡Όͳ͍ɺ historyΛ֦ு͠Α͏

Slide 28

Slide 28 text

historyΛյ͢΂͖͡Όͳ͍ɺhistoryΛ ֦ு͠Α͏ •Single Page Application ͋Δ͋Δɺhistory͕յΕͨUI • FYBNQMFDPN FYBNQMFDPN FYBNQMFDPN εΫϩʔϧ͢Δ ϦϯΫΛΫϦοΫͯ͠ભҠ ͢Δ ભҠޙʹ໭Δ εΫϩʔϧҐஔ͕ ࠷ॳʹ໭Δ

Slide 29

Slide 29 text

historyΛյ͢΂͖͡Όͳ͍ɺhistoryΛ ֦ு͠Α͏ •ଞʹ΋: •͍͍Ͷ͚ͨ͠Ͳɺ͍͍Ͷ͕໭ͬͨΒফ͑ͯͨʢ࣮ࡍʹ͸௥Ճ͞Εͯ Δʣ •ΞίʔσΟΦϯ։͍ͨޙʹϖʔδભҠͯ͠໭ͬͨΒΞίʔσΟΦϯ ดͯͯ͡ભҠ͕յΕΔͱ͔

Slide 30

Slide 30 text

historyΛյ͢΂͖͡Όͳ͍ɺhistoryΛ ֦ு͠Α͏ •͜ΕԿͰى͖Δ͔ͱݴ͏ͱɿෳ߹తͳཁҼ •ϖʔδભҠલʹ͍ΔҐஔΛϒϥ΢β͸ຊ౰ͳΒ֮͑ͯΔ •͚ͩͲ໭ͬͨ࣌ʹ history api Λ࢖ͬͯͯ໭Δͷ͕ૣͯ͘ίϯςϯπ ͕·ͩͳ͍ͱ͔ͦ͏͍͏࣌ʹى͖Δ •BFCacheͱ͔Navigation API ͱ͔ Scroll Resolution API ͱ͔ͦ͏͍ ͏ϒϥ΢β͔Βͷαϙʔτ͸૿͑ͯΔ͕·ͩ࢖͑ͳ͍؀ڥ΋ଟ͍ͷ Ͱɺ࣮ࡍʹ͸݁ߏͪ͜ΒଆͰͳΜͱ͔͠ͳ͍ͱ͍͚ͳ͍໰୊

Slide 31

Slide 31 text

historyΛյ͢΂͖͡Όͳ͍ɺhistoryΛ ֦ு͠Α͏ •Next.jsͩͱεΫϩʔϧҐஔΛ໭͢ͱ͍͏ҙຯͰ͸ɾɾɾ •Page router ͸εΫϩʔϧҐஔΛ֮͑ͯ͘Εͯͯɺϖʔδ͕ϨϯμϦϯά͞Ε͔ͯΒεΫϩʔϧͯ͠ ͘ΕΔ •Experimental Ͱ Scroll Restoration ϓϩύςΟͰͷ੍ޚ΋ͯ͘͠ΕΔɻ •App router͸ݱ࣌఺ͩͱͦͷ͋ͨΓͷ͜ͱ͸Ωϟογϡʹ೚ͤͯΔʢϒϥ΢βʹ೚ͤͯΔײ͡ʁʣ •εΫϩʔϧճؼҎ֎ͷ͜ͱ͸Կ΋ͯ͠ͳ͍ͷͰɺ࣮૷ʹ͸ؾΛ͚ͭͳ͍ͱ͍͚ͳ͍ •ࣾ಺Ͱ͸OSSͰϥΠϒϥϦ࡞ͬͯղܾ͢Δਓͨͪ΋νϥϗϥ •https://github.com/recruit-tech/location-state

Slide 32

Slide 32 text

ίʔυͷมߋΛPush͠Α͏

Slide 33

Slide 33 text

ίʔυͷมߋΛPush͠Α͏ •σʔλ͕ߋ৽͞Εͨʹ΋͔͔ΘΒͣɺίʔυ͕ͦͷ··ͩͱͲ͏ͳΔ ͔ •ϨϯμϦϯά͕͏·͘ߦ͔ͳ͍Մೳੑ͕͋Δ •ը໘͕ΤϥʔʹͳΔ •த్൒୺ͳঢ়ଶͰϨϯμϦϯά͞ΕΔՄೳੑ͕͋Δ •͜͏͍͏ͷΛආ͚ͳ͚Ε͹͍͚ͳ͍ɻ

Slide 34

Slide 34 text

ίʔυͷมߋΛPush͠Α͏ •։ൃ؀ڥͩͱ Hot code reload ͳͲͷํ๏ͰίʔυͷมߋΛpushͯ͘͠ ΔͷͰΘ͔Γ΍͍͢ •ຊ൪؀ڥͩͱ࣮͸ͳ͔ͳ͔೉͍͠ •Τϥʔʹͳͬͨ࣌ʹҰճ৽͘͠ϖʔδΛϋʔυϦϩʔυͤ͞Δͱ͔ͷख ΋͋ΔͬͪΌ͋Δɻ •ਅ໘໨ʹ΍Ζ͏ͱ͢ΔͱversionͷࠩҟΛݕ஌ͯ͠Ͳ͏͢Δ͔Λ࣮૷͠ ͳ͍ͱ͍͚ͳ͍ɻΤϥʔ͕ى͖͚ͨͩͰ൑அ͢ΔͱϦϩʔυ͕ଟ͘ͳΔ

Slide 35

Slide 35 text

ίʔυͷมߋΛPush͠Α͏ •Next.js ͩͱ getServerSideProps ͳͲͷ૊ΈࠐΈͷσʔλ fetch ؔ਺Λ࢖ͬͯΔ৔߹ʹෆ੔ ߹͕͋ΔͱversionࠩҟΛݕ஌ͯ͠Ϧϩʔυͯ͘͠ΕΔ •ͨͩ͜ͷػೳ͸΋ͪΖΜ PageRouter ͷΈ •App Router ͩͱ Vercel ͕ఏڙͯ͘͠Ε͍ͯΔ Skew Protection Λ࢖͏ඞཁ͕͋Δʢ΋͘͠ ͸ࣗલͰ࣮૷ʣ •

Slide 36

Slide 36 text

ৼΔ෣͍Λ༧ଌ͠Α͏

Slide 37

Slide 37 text

ৼΔ෣͍Λ༧ଌ͠Α͏ •Ϣʔβʔ͕࣍ʹԿΛ͢Δͷ͔Λ༧ଌͯ͠proactiveʹৼΔ෣͏ •ྫ͑͹ Google Map ͸੢΁ɺ੢΁ͱਐΉͱ࣍ʹ੢ͷํ޲ʹϦΫΤετ ͕དྷΔͱ༧ଌͯ͠ઌճΓͯ͠σʔλΛऔಘ͢Δ •Google ݕࡧ͸༧ଌݕࡧͷ݁ՌΛ prefetch ͯ͠Δ •͜͏͍͏ಈ͖ΛೖΕΔ΂͖ͩͱ͍͏࿩ɹ

Slide 38

Slide 38 text

ৼΔ෣͍Λ༧ଌ͠Α͏ •एׯ೉ͦ͠͏ʹݟ͑Δ •΍Γ͗͢ΔͱσʔλΛ༨෼ʹऔΓͦ͏͕ͩɺαʔό΁ͷϦιʔεΛ౤ ػతʹ࢖͍ͭͭɺϢʔβ΁ͷ͓΋ͯͳ͠Λߦ͏ͱ͍͏όϥϯεΛͲ͏ औΔ͔ •ͪͳΈʹ Next.js ͸େ෼Ϣʔβʔ΁ͷ͓΋ͯͳ͠ʹدͬͯΔɻ

Slide 39

Slide 39 text

ৼΔ෣͍Λ༧ଌ͠Α͏ •Next.js ͸ next/link Λ࢖͏ͱϢʔβͷviewport಺ʹೖͬͨॠؒʹ prefetch͠ʹ͍͘ •େ෼౤ػత͕ͩɺͦΕ͕ Next.js Λ࢖ͬͨαʔϏε͕ߴ଎ʹݟ͑Δཧ༝ ͩͬͨΓ͢Δ •ҰํͰؾΛ͚ͭͳ͍ͱϢʔβͷΪΨ͸ୣͬͯͦ͏ͩ͠ɺαʔόʹ΋ෛ ՙ͸͔͔ͬͯΔɺαʔό΁ͷϦΫΤετ͕૿͑ͯͯίετ͕͔͔ͬͯ ͳ͍͔֬ೝ͓ͯ͘͠ͱྑ͍

Slide 40

Slide 40 text

·ͱΊ

Slide 41

Slide 41 text

·ͱΊ 1.αʔόʔ͕ϖʔδΛϨϯμϦϯά͢Δͷ͸೚ҙͰ͸ͳ͍ɻ 
 => SSR/SSG/ISRͳͲιϦϡʔγϣϯଟ਺ 2.Ϣʔβʔೖྗʹਝ଎ʹରԠ͠Α͏ 
 => ίʔυεϓϦοτ͕σϑΥϧτͰ࣮૷͞ΕͯΔ 3.σʔλͷมߋʹ൓Ԡ͠Α͏ 
 => Next.js ͰͷରԠ͸ͳ͍͕ɺsocket.ioͳͲͱ૊Έ߹Θ࣮ͤͯ૷Ͱ͖ Δ

Slide 42

Slide 42 text

·ͱΊ 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ͯ͘͠ΕΔ

Slide 43

Slide 43 text

·ͱΊ • ϦονͳΞϓϦέʔγϣϯͷͨΊͷ7ͭͷݪଇΛվΊͯ঺հͭͭ͠ɺ Next.jsͷػೳΛ঺հͨ͠ɻ • Next.js ͳΜͰ࢖͏Μ͚ͩͬʁͬͯͳͬͨ࣌ʹʮϦονͳΞϓϦέʔγϣ ϯͷͨΊͷݪଇʯʹै͏ͨΊͩͱ͍͏ҙݟͰઆಘࡐྉʹ࢖͑Δͱࢥ͏ɻ • ΋ͪΖΜࣗ෼ͨͪͰ͜ΕΒΛ࣮૷Ͱ͖Δͱࢥ͏ͷͰઈରͷඞཁ৚݅ʹ͸ ͳΓಘͳ͍ɻ • ͜Ε͔Β΋৭ʑΞοϓσʔτ͞Ε͍ͯ͘ͱࢥ͏ͷͰ஫ࢹ͍ͯ͘͠༧ఆ