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
Hatena Engineer Seminar #14 Next.js 編 / hatena-...
Search
mfzy
July 15, 2020
Programming
1.8k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Hatena Engineer Seminar #14 Next.js 編 / hatena-engineer-seminar-14-nextjs
mfzy
July 15, 2020
More Decks by mfzy
See All by mfzy
Hatena Engineer Seminar #19 フロントエンド編
mfzy
0
2.2k
Other Decks in Programming
See All in Programming
「AI時代、配布するPythonコードをどう守るか: 難読化の実験と判断軸」 #PyconJP2026
pkshadeck
PRO
2
200
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
130
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
150
Webの地図
yosuke_furukawa
PRO
6
4.1k
AIを上手に使っていこうとしたら越境せざるを得なくなった話 〜実践1年で見えた境界を越えなければならない理由と進め方〜 / Crossing borders with AI
tomoyakitaura
4
1.1k
テストを司るデーモンに会いに行く 〜隔離した仮想マシンでテストを通すまで〜
h1d3mun3
1
160
How I Stole PSI from Android Studio - DroidKaigi2026
worker8
0
110
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
150
AI駆動開発にグラフDBを重ねてみた
satoshi256kbyte
2
780
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
170
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.5k
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
140
Featured
See All Featured
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
450
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
830
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.1k
Designing Powerful Visuals for Engaging Learning
tmiket
1
540
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
270
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
510
Unsuck your backbone
ammeep
672
58k
Building Applications with DynamoDB
mza
96
7.2k
Deep Space Network (abreviated)
tonyrice
0
300
Six Lessons from altMBA
skipperchong
29
4.5k
Transcript
id:mfzy 2020/7/15 Next.js ฤ ~ ϢʔβʔͱΫϩʔϥʔΛڞʹͯͳٕ͢ज़ ~ Hatena Engineer Seminar
#14
ൃදͷྲྀΕ ຐ๏ͷJΒΜͲ /FYUKT ϞόΠϧϑΝʔετ ίϯϙʔωϯτग़͚͠
·ͱΊ 2
ຐ๏ͷiΒΜͲ
ϑΟʔνϟʔϑΥϯ͔࣌Βͷ͍ྺ࢙ ϞόΠϧ͔ΒͷΞΫηεׂ͕ εϚʔτϑΥϯͷγϑτ͋ΓͭͭґવϞόΠϧ͕ࢧత ৢ͞ΕͨจԽ ࡞ͷϖʔδ͝ͱͷจྔগͳΊ͕ͩϖʔδ͕ଟ͍
ಛ 4
ϦχϡʔΞϧ ࣌ͷҠΓมΘΓͱڞʹϢʔβʔͷං͖͑ͯͨ چγεςϜͷϨΨγʔͳٕज़ελοΫ ϞμϯͳମݧΛ࣮ݱ͢Δʹແཧ͕͋Δ ٕज़ελοΫͷ৽
ϑϩϯτΤϯυΛࢧ͑Δٕज़ͱͯ͠αʔϏεͷಛʹ߹ͬͨ/FYUKTΛબఆ 5
Next.js
ٕज़ελοΫ Next.js Server (BFF) GraphQL API DB 7 Feather is
licensed under the MIT License. SPA
React 6*ߏஙϥΠϒϥϦ ίϯϙʔωϯτϕʔε ΧϓηϧԽ͞Εͨ෦ΛΈ߹Θͤͯ6*Λߏங 4JOHMF1BHF"QQMJDBUJPO 41"
ϖʔδભҠʹࡍͯ͠શମΛ࠶औಘͤͣඞཁͳใ͚ͩಡΈࠐΉ ϒϥβͰωΠςΟϒΞϓϦͷΑ͏ͳૢ࡞ײΛ 8
Next.js 3FBDUΞϓϦέʔγϣϯΛ࡞ΔͨΊͷPQJOJPOBUFEͳϑϨʔϜϫʔΫ ࣅͨͷʹDSFBUFSFBDUBQQ $3" ͕͋Δ ओͳڧΈ
`next`ίϚϯυҰͭͰϓϩδΣΫτͷجૅ͕ग़དྷ্͕Δ όϯυϥʔ 8FCQBDL ͷπʔϧ͕ॳΊ͔ΒΈࠐ·Ε͍ͯΔ ࡶͳઃఆΛඞཁͱ͠ͳ͍ڧྗͳ1SFSFOEFSJOHػߏ 9
Pre-rendering ͠ͳ͍߹ 10 Server Server Server API Λୟ͍ͨΓ͋Δ͍ ੩తͳϦιʔε (JSON
) Λཁٻ͢Δ ίϯςϯπΛ͍ܽͨ ϕʔεͷ HTML ͕ฦ٫͞ΕΔ ϨεϙϯεΛղऍͯ͠Α͏͘ ίϯςϯπ͕ར༻Մೳʹ
Pre-rendering ͢Δ߹ 11 Server (BFF) API / Storage ॳΊ͔Β HTML
ʹ ίϯςϯπ͕ຒΊࠐ·Ε͍ͯΔ
Pre-rendering ͷछྨ 4UBUJD(FOFSBUJPO Ϗϧυ `next build` ࣌ʹੜ͓͍ͯͨ͠)5.-Λฦ͢
6($ͷΑ͏ͳಈతίϯςϯπʹద͞ͳ͍ 4FSWFS4JEF3FOEFSJOH 443 ϦΫΤετ͝ͱʹ)5.-Λੜ ຐ๏ͷJΒΜͲͰ1SFSFOEFSJOHΛհ͢ΔՕॴશͯ443 12
ͳͥ Next.js ͳͷ͔ 6*69ͷ৽ ࡞ͷੑ্࣭ϖʔδભҠ͕ଟ͍ˠ41" %FWFMPQFS&YQFSJFODF %9
Ϟνϕʔγϣϯͱڞʹ্࣭ ࡞ͬͯऴΘΓͰͳ͍ɺӡ༻্ͷෛ୲ܰݮظ 4&0ཁ݅ˠ443 ී௨ͷ41"ͩͱΫϩʔϥʔଆ͕ղऍ͠ʹ͍͘ 13
Ϋϩʔϥʔͱ JavaScript ΫϩʔϥʔϖʔδͷίϯςϯπΛಡΈऔͬͯΠϯσοΫεΛ࡞͢Δ ૉͳ41"ͰϨεϙϯε )5.- ࣗମʹίϯςϯπؚ͕·Εͳ͍ +BWB4DSJQUΛղऍ͠ͳ͍ݶΓίϯςϯπ͕ར༻Ͱ͖ͳ͍
ϞμϯͳΫϩʔϥʔ+BWB4DSJQUΛղऍͰ͖Δ ҰےೄͰ͍͔ͳ͍Β͍͠ͷ͕ݱঢ় (PPHMFґવͱͯ͠ԿΒ͔ͷϨϯμϦϯάख๏Λ࠾ΔΑ͏קΊ͍ͯΔ IUUQTEFWFMPQFSTHPPHMFDPNTFBSDIEPDTHVJEFTEZOBNJDSFOEFSJOH 14
SEO ͱ SSR ΫϩʔϥʔଆͷਐาʹΑͬͯ443ෆཁʹͳͬͨͷͰ ͦ͏Ͱͳ͍ͷ͕ݱঢ় લड़
୯७ͳ41"ͰదʹεςʔλείʔυΛฦ٫Ͱ͖ͳ͍ͳͲͷΔ 443Λ࠾༻͢Δ্Ͱҙ͢Δ͜ͱ $MJFOU4JEF3FOEFSJOH $43 Ͱͷग़ྗͱҟͳΔͱϚζ͍ ޙड़ ϞόΠϧɾͦΕҎ֎Ͱͷ6*ग़͚͠ʹۤઓ͢Δ͜ͱʹʜ 15
ϞόΠϧϑΝʔετ
ϞόΠϧϑΝʔετ ࠶ܝϞόΠϧ͔ΒͷΞΫηε͕ࢧత ϞόΠϧͰͷϢʔβʔମݧ͕ॏཁʹ ຐ๏ͷJΒΜͲʹݶΒͣੈؒతʹϞόΠϧ͕େ ݕࡧΤϯδϯͰϞόΠϧϑϨϯυϦʔͳΣϒαΠτ͕༏۰͞ΕΔ 17
։ൃͷྲྀΕ ඞવతʹϞόΠϧ͔Β։ൃ͕ਐΉ ͱ͍͑વϞόΠϧҎ֎ͷ͚ͷରԠඞཁ ϞόΠϧϑΝʔετ͔ͩΒͱ͍ͬͯ㚽Ζʹ͠ͳ͍ Ͳ͏ͬͯ1$ରԠΛਐΊ͍͔ͯ͘ 18
RWD 3FTQPOTJWF8FC%FTJHO 38% ओʹελΠϧγʔτΛۦͯ͠͏·͘ݟͨΛௐ͢Δ͜ͱʹͳΔ &UIBO.BSDPUUFࢯͷهࣄ͕ॳग़ͱ͞ΕΔ
ίϯϙʔωϯτϕʔεͷࢥ͕·Δલͷ࣌ͷߟ͑ํ ίϯϙʔωϯτϕʔε͕ओྲྀͷ41"ͰͲ͏͔ʁ 38%Λ࣠ʹͯ͠͠·͏ͷྑ͘ͳͦ͞͏ 19
SPA ͱ RWD IUUQTTDSBQCPYJPTIPLBJ$44ϨεϙϯγϒσβΠϯΛ41"Ͱ͏ͱഁ໓͢Δ ελΠϧγʔτ͚ͩͷௐͰࡁ·ͤΔʹແཧΛ͏έʔεଟ͍ දݱྗ͕๛͔ʹͳͬͨঢ়ଶɾΠϯλϥΫγϣϯෳࡶʹ
͝ͱͷࠩݟͨʹݶΒͳ͍ ͱ͍͑ܰඍͳݟͨͷௐʹґવͱͯ͠༗༻ 38%ิॿతʹ͏ͱͯ͠ΘΓʹ࣠ͱͳΔΈ͕ඞཁ 20
ίϯϙʔωϯτग़͚͠
جຊతͳΞΠσΞ ελΠϧγʔτͰͷௐͰͲ͏ʹͳΒͳ͍ݟͨҎ֎ͷࠩΛѻ͍͍ͨ ελΠϧγʔτͰͳ͘ϓϩάϥϜ +BWB4DSJQU ͷੈքʹ࣠ΛҠ͢ ҰͭͷίϯϙʔωϯτͰແཧʹࠩΛѻ͓͏ͱ͢ΔͱόάΛຒΊࠐΈ͔Ͷͳ͍
͝ͱʹผͷίϯϙʔωϯτΛ༻ҙ͢Δ ͦΕͧΕʹඞཁͳϩδοΫͷΈʹूதͰ͖ਖ਼ؾ͕อͯΔ Ͳ͏࣮ݱ͢Δʁ 22
੍ ͜͜Ͱ4&0ཁ͕݅ἝΛṞ͘ ૉʹ$44ͷ.FEJB2VFSZΛ฿ͬͯϏϡʔϙʔτΛཔΓʹͨ͘͠ͳΔ ࠶ܝ443ͱ$43ͷ݁ՌҰக͠ͳͯ͘ͳΒͳ͍ ϓϩάϥϜʹ࣠ΛҠ͢ͱ͍͏͜ͱ%0.ʹ࡞༻Ͱ͖Δͱ͍͏͜ͱ
ΫϥΠΞϯτଆͰ͔͠ར༻Ͱ͖ͳ͍ใΛ͋ͯʹͰ͖ͳ͍ʂ 23
SSR ͱ CSR ݁Ռʹ૬ҧ͕͋Δ߹ 24 Server PC ͔ΒͷϦΫΤετʹରͯ͠ ϞόΠϧ͚ͷ༰Λ SSR
ͯ͠ฦͯ͠͠·͏ CSR Ͱ PC ͚ͷ༰ʹ ࠶ߏங͞ΕΔ͜ͱʹ SEO తʹϖφϧςΟΛ৯Β͏͜ͱ͕͋Δ (Cloaking ͱݟ၏͞ΕΔڪΕ͕͋Δ) &ɹ ը໘͕νϥ͍ͭͯମݧ͕ѱ͍
Ұ؏ੑ αʔόʔଆͰΫϥΠΞϯτଆͰҰ؏ɾ҆ఆͯ͠ར༻Ͱ͖Δใͱ͍͑ 6TFS"HFOU͘Β͍͔͠ͳ͍ 6"จࣈྻݻఆԽ͞ΕΔͱ͍͏ $MJFOU)JOUT͕࣮༻Խ͞ΕΕͦͪΒΛ͏͜ͱʹͳΔͩΖ͏
ͦΕ·Ͱ6"จࣈྻΛݟΔ͔͠ͳ͍ 25
UA จࣈྻ͔Βͷผ Ͳ͏ͬͯΛผ͢Δ͔ 6"จࣈྻʹ`Mobile`ͱ͍͏จࣈྻ͕ଘࡏ͢Δ͔֬ೝ େࡶʹϞόΠϧ͔ͦΕҎ֎͔ʹ͚Δ͜ͱ͕Ͱ͖Δ ͦΜͳ୯७ͳϩδοΫͰ͏·͍͘͘ͷ͔
ϝδϟʔͳϒϥβͷຆͲ͕͜ͷ҉తͳϧʔϧʹै͍ͬͯΔ༷ ͪΖΜ(PPHMFCPU ϚΠφʔͳͷͦͦαϙʔτ֎ͱ͍͏͜ͱ͋Δ 26
Tier `Mobile`͕ଘࡏ͢Ε`compact`ɺͦ͏Ͱͳ͚Ε`regular` ͜ΕΛ5JFSͱݺͿ͜ͱʹ͢Δ ϫʔυνϣΠε#PPUTUSBQͷ(SJE5JFSJ04ͷ4J[F$MBTTFTΛࢀߟʹ ϢϏΩλεݴޠͱͷ݉Ͷ߹͍ߟྀͭͭ͠୯७Ͱ໌ྎͳ໋໊Λ৺͕͚ͨ 27
ྫ: iPad (Split View) 28 `compact` `regular`
࣮ ΞϓϦέʔγϣϯϫΠυͳঢ়ଶͱͯ͠5JFS͕ࢀরͰ͖ΔΑ͏ʹ 4JOHMF4PVSDFPG5SVUI 4405 ͱͳΔΑ͏ߏ ࣮ࡍʹ3FEVYͷঢ়ଶͱͯ͠ཧ 3FBDUͷ$POUFYUͰͳ͍
5JFSͷࢉग़ج४؆୯ʹࠩ͠ସ͑ΒΕΔΑ͏ʹ 6"จࣈྻ͕ݻఆԽ͞ΕͨΒସͷใ͔Β5JFSΛಋग़͢ΕΑ͍͚ͩ ग़͚͠Λखܰʹ࣮ݱ͢ΔͨΊͷϔϧύʔίϯϙʔωϯτΛ༻ҙ 29
ίϯϙʔωϯτग़͚࣮͠ྫʢ1ʣ // ڞ௨Ͱར༻͢Δ props ͷܕΛఆ͓ٛͯ͘͠ interface CommonFooProps { bar: string;
} const CompactFoo: React.FC<CommonFooProps> = () => {/* ... */}; const RegularFoo: React.FC<CommonFooProps> = () => {/* ... */}; export const Foo = switched({ compact: CompactFoo, regular: RegularFoo, }); export const Page: NextPage = () => ( <SomeContainer> <Foo bar="baz" /> {/* ΤʔδΣϯτʹԠͯ͡উखʹΓସΘΔ */} </SomeContainer> ); Tier ͝ͱͷίϯϙʔωϯτΛ·ͱΊͯ ୯७ͳίϯϙʔωϯτͱͯ͠ѻ͑ΔΑ͏ʹ
ίϯϙʔωϯτग़͚࣮͠ྫʢ2ʣ export const Foo: React.FC<{}> = () => { const
{ isCompact } = useTier(); return ( <> <RegularOnly> {/* regular ͷ߹ͷΈݱΕΔ */} </RegularOnly> <div className="bar"></div> <style jsx>{` .bar { width: ${isCompact ? '100px' : '300px'}; } `}</style> </> ); }; એݴతΞϓϩʔνΛ׆͔͢ ίϯϙʔωϯτΛग़͚͠Δ·Ͱͳ͍ ܰඍͳௐ݅ذͰ
·ͱΊ
·ͱΊ ͳͥ/FYUKTͳͷ͔ 6*69ͱ4&0ཁ݅Λຬ্ͨͨ͠Ͱ%9ͷ্·Ͱ͕ݟࠐΊ͔ͨΒ 5JFSʹΑΔίϯϙʔωϯτग़͚͠Ͱ͓ͯͳ͠ ϢʔβʔʹσόΠεʹదͨ͠ϞμϯͰϦονͳମݧΛ
Ϋϩʔϥʔʹ6"ʹదͨ͠Ұ؏ੑͷ͋Δग़ྗΛ 33