$30 off During Our Annual Pro Sale. View Details »

Hatena Engineer Seminar #14 Next.js 編 / hatena-engineer-seminar-14-nextjs

mfzy
July 15, 2020

Hatena Engineer Seminar #14 Next.js 編 / hatena-engineer-seminar-14-nextjs

mfzy

July 15, 2020
Tweet

More Decks by mfzy

Other Decks in Programming

Transcript

  1. id:mfzy 2020/7/15
    Next.js ฤ
    ~ ϢʔβʔͱΫϩʔϥʔΛڞʹ΋ͯͳٕ͢ज़ ~
    Hatena Engineer Seminar #14

    View Slide

  2. ൃදͷྲྀΕ
    ຐ๏ͷJΒΜͲ
    /FYUKT
    ϞόΠϧϑΝʔετ
    ίϯϙʔωϯτग़͠෼͚
    ·ͱΊ
    2

    View Slide

  3. ຐ๏ͷiΒΜͲ

    View Slide

  4. ϑΟʔνϟʔϑΥϯ࣌୅͔Βͷ௕͍ྺ࢙
    ϞόΠϧ୺຤͔ΒͷΞΫηε͕໿ׂ
    εϚʔτϑΥϯ΁ͷγϑτ͸͋Γͭͭ΋ґવϞόΠϧ͕ࢧ഑త
    ৢ੒͞ΕͨจԽ
    ࡞඼ͷϖʔδ͝ͱͷจྔ͸গͳΊ͕ͩϖʔδ਺͕ଟ͍
    ಛ௃
    4

    View Slide

  5. ϦχϡʔΞϧ
    ࣌୅ͷҠΓมΘΓͱڞʹϢʔβʔͷ໨͸ං͖͑ͯͨ
    چγεςϜͷϨΨγʔͳٕज़ελοΫ
    ϞμϯͳମݧΛ࣮ݱ͢Δʹ͸ແཧ͕͋Δ
    ٕज़ελοΫͷ࡮৽
    ϑϩϯτΤϯυΛࢧ͑Δٕज़ͱͯ͠αʔϏεͷಛ௃ʹ߹ͬͨ/FYUKTΛબఆ
    5

    View Slide

  6. Next.js

    View Slide

  7. ٕज़ελοΫ
    Next.js Server (BFF)
    GraphQL API
    DB
    7
    Feather is licensed under the MIT License.
    SPA

    View Slide

  8. React
    6*ߏஙϥΠϒϥϦ
    ίϯϙʔωϯτϕʔε
    ΧϓηϧԽ͞Εͨ෦඼Λ૊Έ߹Θͤͯ6*Λߏங
    4JOHMF1BHF"QQMJDBUJPO 41"

    ϖʔδભҠʹࡍͯ͠શମΛ࠶औಘͤͣඞཁͳ৘ใ͚ͩಡΈࠐΉ
    ϒϥ΢βͰ΋ωΠςΟϒΞϓϦͷΑ͏ͳૢ࡞ײΛ
    8

    View Slide

  9. Next.js
    3FBDUΞϓϦέʔγϣϯΛ࡞ΔͨΊͷPQJOJPOBUFEͳϑϨʔϜϫʔΫ
    ࣅͨ΋ͷʹDSFBUFSFBDUBQQ $3"
    ͕͋Δ
    ओͳڧΈ
    `next`ίϚϯυҰͭͰϓϩδΣΫτͷجૅ͕ग़དྷ্͕Δ
    όϯυϥʔ 8FCQBDL
    ౳ͷπʔϧ͕ॳΊ͔Β૊Έࠐ·Ε͍ͯΔ
    ൥ࡶͳઃఆΛඞཁͱ͠ͳ͍ڧྗͳ1SFSFOEFSJOHػߏ
    9

    View Slide

  10. Pre-rendering ͠ͳ͍৔߹
    10
    Server
    Server Server
    API Λୟ͍ͨΓ͋Δ͍͸
    ੩తͳϦιʔε (JSON ౳) Λཁٻ͢Δ
    ίϯςϯπΛ͍ܽͨ
    ϕʔεͷ HTML ͕ฦ٫͞ΕΔ
    ϨεϙϯεΛղऍͯ͠Α͏΍͘
    ίϯςϯπ͕ར༻Մೳʹ

    View Slide

  11. Pre-rendering ͢Δ৔߹
    11
    Server (BFF)
    API / Storage
    ॳΊ͔Β HTML ʹ
    ίϯςϯπ͕ຒΊࠐ·Ε͍ͯΔ

    View Slide

  12. Pre-rendering ͷछྨ
    4UBUJD(FOFSBUJPO
    Ϗϧυ `next build`
    ࣌ʹੜ੒͓͍ͯͨ͠)5.-Λฦ͢
    6($ͷΑ͏ͳಈతίϯςϯπʹ͸ద͞ͳ͍
    4FSWFS4JEF3FOEFSJOH 443

    ϦΫΤετ͝ͱʹ)5.-Λੜ੒
    ຐ๏ͷJΒΜͲͰ1SFSFOEFSJOHΛհ͢ΔՕॴ͸શͯ443
    12

    View Slide

  13. ͳͥ Next.js ͳͷ͔
    6*69ͷ࡮৽
    ࡞඼ͷੑ্࣭ϖʔδભҠ͕ଟ͍ˠ41"
    %FWFMPQFS&YQFSJFODF %9

    Ϟνϕʔγϣϯͱڞʹ඼࣭΋޲্
    ࡞ͬͯऴΘΓͰͳ͍ɺӡ༻্ͷෛ୲ܰݮ΋ظ଴
    4&0ཁ݅ˠ443
    ී௨ͷ41"ͩͱΫϩʔϥʔଆ͕ղऍ͠ʹ͍͘
    13

    View Slide

  14. Ϋϩʔϥʔͱ JavaScript
    Ϋϩʔϥʔ͸ϖʔδ಺ͷίϯςϯπΛಡΈऔͬͯΠϯσοΫεΛ࡞੒͢Δ
    ૉ๿ͳ41"Ͱ͸Ϩεϙϯε )5.-
    ࣗମʹίϯςϯπؚ͕·Εͳ͍
    +BWB4DSJQUΛղऍ͠ͳ͍ݶΓίϯςϯπ͕ར༻Ͱ͖ͳ͍
    ϞμϯͳΫϩʔϥʔ͸+BWB4DSJQUΛղऍͰ͖Δ
    ҰےೄͰ͸͍͔ͳ͍Β͍͠ͷ͕ݱঢ়
    (PPHMF΋ґવͱͯ͠ԿΒ͔ͷϨϯμϦϯάख๏Λ࠾ΔΑ͏קΊ͍ͯΔ
    IUUQTEFWFMPQFSTHPPHMFDPNTFBSDIEPDTHVJEFTEZOBNJDSFOEFSJOH
    14

    View Slide

  15. SEO ͱ SSR
    ΫϩʔϥʔଆͷਐาʹΑͬͯ443͸ෆཁʹͳͬͨͷͰ͸
    ͦ͏Ͱ΋ͳ͍ͷ͕ݱঢ় લड़

    ୯७ͳ41"Ͱ͸ద੾ʹεςʔλείʔυΛฦ٫Ͱ͖ͳ͍ͳͲͷ໰୊΋࢒Δ
    443Λ࠾༻͢Δ্Ͱ஫ҙ͢Δ͜ͱ
    $MJFOU4JEF3FOEFSJOH $43
    Ͱͷग़ྗͱҟͳΔͱϚζ͍ ޙड़

    ϞόΠϧ୺຤ɾͦΕҎ֎Ͱͷ6*ग़͠෼͚ʹۤઓ͢Δ͜ͱʹʜ
    15

    View Slide

  16. ϞόΠϧϑΝʔετ

    View Slide

  17. ϞόΠϧϑΝʔετ
    ࠶ܝϞόΠϧ୺຤͔ΒͷΞΫηε͕ࢧ഑త
    ϞόΠϧ୺຤ͰͷϢʔβʔମݧ͕ॏཁʹ
    ຐ๏ͷJΒΜͲʹݶΒͣੈؒతʹ΋ϞόΠϧ͕େ൒
    ݕࡧΤϯδϯͰ͸ϞόΠϧϑϨϯυϦʔͳ΢ΣϒαΠτ͕༏۰͞ΕΔ܏޲
    17

    View Slide

  18. ։ൃͷྲྀΕ
    ඞવతʹϞόΠϧ͔Β։ൃ͕ਐΉ
    ͱ͸͍͑౰વϞόΠϧҎ֎ͷ୺຤޲͚ͷରԠ΋ඞཁ
    ϞόΠϧϑΝʔετ͔ͩΒͱ͍ͬͯ㚽Ζʹ͸͠ͳ͍
    Ͳ͏΍ͬͯ1$ରԠΛਐΊ͍͔ͯ͘
    18

    View Slide

  19. RWD
    3FTQPOTJWF8FC%FTJHO 38%

    ओʹελΠϧγʔτΛۦ࢖ͯ͠͏·͘ݟͨ໨Λௐ੔͢Δ͜ͱʹͳΔ
    &UIBO.BSDPUUFࢯͷهࣄ͕ॳग़ͱ͞ΕΔ ೥

    ίϯϙʔωϯτϕʔεͷࢥ૝͕޿·Δલͷ࣌୅ͷߟ͑ํ
    ίϯϙʔωϯτϕʔε͕ओྲྀͷ41"Ͱ͸Ͳ͏͔ʁ
    38%Λ࣠ʹͯ͠͠·͏ͷ͸ྑ͘ͳͦ͞͏
    19

    View Slide

  20. SPA ͱ RWD
    IUUQTTDSBQCPYJPTIPLBJ$44ϨεϙϯγϒσβΠϯΛ41"Ͱ࢖͏ͱഁ໓͢Δ
    ελΠϧγʔτ͚ͩͷௐ੔Ͱࡁ·ͤΔʹ͸ແཧΛ൐͏έʔε΋ଟ͍
    දݱྗ͕๛͔ʹͳͬͨ෼ঢ়ଶɾΠϯλϥΫγϣϯ΋ෳࡶʹ
    ୺຤͝ͱͷࠩ෼͸ݟͨ໨ʹݶΒͳ͍
    ͱ͸͍͑ܰඍͳݟͨ໨ͷௐ੔ʹ͸ґવͱͯ͠༗༻
    38%͸ิॿతʹ࢖͏ͱͯ͠୅ΘΓʹ࣠ͱͳΔ࢓૊Έ͕ඞཁ
    20

    View Slide

  21. ίϯϙʔωϯτग़͠෼͚

    View Slide

  22. جຊతͳΞΠσΞ
    ελΠϧγʔτͰͷௐ੔Ͱ͸Ͳ͏ʹ΋ͳΒͳ͍ݟͨ໨Ҏ֎ͷࠩ෼Λѻ͍͍ͨ
    ελΠϧγʔτͰͳ͘ϓϩάϥϜ +BWB4DSJQU
    ͷੈքʹ࣠ΛҠ͢
    ҰͭͷίϯϙʔωϯτͰແཧʹࠩ෼Λѻ͓͏ͱ͢ΔͱόάΛຒΊࠐΈ͔Ͷͳ͍
    ୺຤͝ͱʹผͷίϯϙʔωϯτΛ༻ҙ͢Δ
    ͦΕͧΕʹඞཁͳϩδοΫͷΈʹूதͰ͖ਖ਼ؾ͕อͯΔ
    Ͳ͏࣮ݱ͢Δʁ
    22

    View Slide

  23. ੍໿
    ͜͜Ͱ4&0ཁ͕݅ἝΛṞ͘
    ૉ௚ʹ$44ͷ.FEJB2VFSZΛ฿ͬͯϏϡʔϙʔτΛཔΓʹͨ͘͠ͳΔ
    ࠶ܝ443ͱ$43ͷ݁Ռ͸Ұக͠ͳͯ͘͸ͳΒͳ͍
    ϓϩάϥϜʹ࣠ΛҠ͢ͱ͍͏͜ͱ͸%0.ʹ΋࡞༻Ͱ͖Δͱ͍͏͜ͱ
    ΫϥΠΞϯτଆͰ͔͠ར༻Ͱ͖ͳ͍৘ใΛ͋ͯʹ͸Ͱ͖ͳ͍ʂ
    23

    View Slide

  24. SSR ͱ CSR ݁Ռʹ૬ҧ͕͋Δ৔߹
    24
    Server
    PC ͔ΒͷϦΫΤετʹରͯ͠
    ϞόΠϧ޲͚ͷ಺༰Λ SSR ͯ͠ฦͯ͠͠·͏
    CSR Ͱ PC ޲͚ͷ಺༰ʹ
    ࠶ߏங͞ΕΔ͜ͱʹ
    SEO తʹϖφϧςΟΛ৯Β͏͜ͱ͕͋Δ
    (Cloaking ͱݟ၏͞ΕΔڪΕ͕͋Δ)

    ը໘͕νϥ͍ͭͯମݧ͕ѱ͍

    View Slide

  25. Ұ؏ੑ
    αʔόʔଆͰ΋ΫϥΠΞϯτଆͰ΋Ұ؏ɾ҆ఆͯ͠ར༻Ͱ͖Δ৘ใͱ͍͑͹
    6TFS"HFOU͘Β͍͔͠ͳ͍
    6"จࣈྻ͸ݻఆԽ͞ΕΔͱ͍͏࿩΋
    $MJFOU)JOUT͕࣮༻Խ͞ΕΕ͹ͦͪΒΛ࢖͏͜ͱʹͳΔͩΖ͏
    ͦΕ·Ͱ͸6"จࣈྻΛݟΔ͔͠ͳ͍
    25

    View Slide

  26. UA จࣈྻ͔Βͷ൑ผ
    Ͳ͏΍ͬͯ୺຤Λ൑ผ͢Δ͔
    6"จࣈྻ಺ʹ`Mobile`ͱ͍͏จࣈྻ͕ଘࡏ͢Δ͔֬ೝ
    େࡶ೺ʹϞόΠϧ͔ͦΕҎ֎͔ʹ෼͚Δ͜ͱ͕Ͱ͖Δ
    ͦΜͳ୯७ͳϩδοΫͰ͏·͍͘͘ͷ͔
    ϝδϟʔͳϒϥ΢βͷຆͲ͕͜ͷ҉໧తͳϧʔϧʹै͍ͬͯΔ໛༷
    ΋ͪΖΜ(PPHMFCPU΋
    ϚΠφʔͳ΋ͷ͸ͦ΋ͦ΋αϙʔτ֎ͱ͍͏͜ͱ΋͋Δ
    26

    View Slide

  27. Tier
    `Mobile`͕ଘࡏ͢Ε͹`compact`ɺͦ͏Ͱͳ͚Ε͹`regular`
    ͜ΕΛ5JFSͱݺͿ͜ͱʹ͢Δ
    ϫʔυνϣΠε͸#PPUTUSBQͷ(SJE5JFS΍J04ͷ4J[F$MBTTFTΛࢀߟʹ
    ϢϏΩλεݴޠͱͷ݉Ͷ߹͍΋ߟྀͭͭ͠୯७Ͱ໌ྎͳ໋໊Λ৺͕͚ͨ
    27

    View Slide

  28. ྫ: iPad (Split View)
    28
    `compact` `regular`

    View Slide

  29. ࣮૷
    ΞϓϦέʔγϣϯϫΠυͳঢ়ଶͱͯ͠5JFS͕ࢀরͰ͖ΔΑ͏ʹ
    4JOHMF4PVSDFPG5SVUI 4405
    ͱͳΔΑ͏ߏ੒
    ࣮ࡍʹ͸3FEVYͷঢ়ଶͱͯ͠؅ཧ 3FBDUͷ$POUFYUͰ΋໰୊ͳ͍

    5JFSͷࢉग़ج४͸؆୯ʹࠩ͠ସ͑ΒΕΔΑ͏ʹ
    6"จࣈྻ͕ݻఆԽ͞ΕͨΒ୅ସͷ৘ใ͔Β5JFSΛಋग़͢Ε͹Α͍͚ͩ
    ग़͠෼͚Λखܰʹ࣮ݱ͢ΔͨΊͷϔϧύʔ΍ίϯϙʔωϯτΛ༻ҙ
    29

    View Slide

  30. ίϯϙʔωϯτग़͠෼͚࣮૷ྫʢ1ʣ
    // ڞ௨Ͱར༻͢Δ props ͷܕΛఆ͓ٛͯ͘͠
    interface CommonFooProps {
    bar: string;
    }
    const CompactFoo: React.FC = () => {/* ... */};
    const RegularFoo: React.FC = () => {/* ... */};
    export const Foo = switched({
    compact: CompactFoo,
    regular: RegularFoo,
    });
    export const Page: NextPage = () => (

    {/* ΤʔδΣϯτʹԠͯ͡উखʹ੾ΓସΘΔ */}

    );
    Tier ͝ͱͷίϯϙʔωϯτΛ·ͱΊͯ
    ୯७ͳίϯϙʔωϯτͱͯ͠ѻ͑ΔΑ͏ʹ

    View Slide

  31. ίϯϙʔωϯτग़͠෼͚࣮૷ྫʢ2ʣ
    export const Foo: React.FC<{}> = () => {
    const { isCompact } = useTier();
    return (
    <>

    {/* regular ͷ৔߹ͷΈݱΕΔ */}


    {`<br/>.bar {<br/>width: ${isCompact ? '100px' : '300px'};<br/>}<br/>`}
    >
    );
    };
    એݴతΞϓϩʔνΛ׆͔͢
    ίϯϙʔωϯτΛग़͠෼͚Δ·Ͱ΋ͳ͍
    ܰඍͳௐ੔͸৚݅෼ذͰ

    View Slide

  32. ·ͱΊ

    View Slide

  33. ·ͱΊ
    ͳͥ/FYUKTͳͷ͔
    6*69ͱ4&0ཁ݅Λຬ্ͨͨ͠Ͱ%9ͷ޲্·Ͱ΋͕ݟࠐΊ͔ͨΒ
    5JFSʹΑΔίϯϙʔωϯτग़͠෼͚Ͱ͓΋ͯͳ͠
    Ϣʔβʔʹ͸σόΠεʹదͨ͠ϞμϯͰϦονͳମݧΛ
    Ϋϩʔϥʔʹ͸6"ʹదͨ͠Ұ؏ੑͷ͋Δग़ྗΛ
    33

    View Slide