Slide 1

Slide 1 text

Server Side Rendering Tuning with Next.js Server Side Rendering Tuning with Next.js Mercari x Merpay Frontend Tech Talk vol.2 @vwxyuratoooo

Slide 2

Slide 2 text

Yutaro Miyazaki (@vwxyutarooo) Yutaro Miyazaki (@vwxyutarooo) 2012~ Jobless 2013~ Freelance 2016~ Startup 2018~ Mercari

Slide 3

Slide 3 text

My Talk is About... My Talk is About... Our new architecture of Mercari Web The performance issue of Server Side Rendering with Next.js

Slide 4

Slide 4 text

Topics Topics Mercari Web Re-Architecture Apollo Next.js Performance Tuning Conclusion

Slide 5

Slide 5 text

What Web Re-Architecture is What Web Re-Architecture is

Slide 6

Slide 6 text

Ancient Huge PHP Code ↓ Modern Architecture

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Topics Topics Mercari Web Re-Architecture Apollo Next.js Performance Tuning Conclusion

Slide 12

Slide 12 text

Apollo Apollo

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Topics Topics Mercari Web Re-Architecture Apollo Next.js Performance Tuning Conclusion

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Next.js Upside Next.js Upside Build System Smart Chunk System Various Practices

Slide 18

Slide 18 text

Next.js Downside Next.js Downside Folder Structure Router We hit the Server Side Rendering Performance issue...?

Slide 19

Slide 19 text

Server Side Rendering Performance?

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

100 requests per second. 40 CPU cores were waste. It still doesn't reaches to 100 requests per second On the production environment It's supposed to spend 800 CPU cores.

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Topics Topics Mercari Web Re-Architecture Apollo Next.js Performance Tuning Conclusion

Slide 24

Slide 24 text

Performance Tuning Performance Tuning How can we solve this catastrophic performance issue

Slide 25

Slide 25 text

Render method tuning renderToNodeStream for example. Cache

Slide 26

Slide 26 text

Investigation Investigation

Slide 27

Slide 27 text

What We Learned is What We Learned is Styled Components CategoryLists component Contained regular expression. renderToStaticMarkup and renderToHTML .

Slide 28

Slide 28 text

Things we've adopted: Prevent HTML from rendering twice. Client Side Render Component.

Slide 29

Slide 29 text

1. Prevent HTML From Rendered Twice 1. Prevent HTML From Rendered Twice

Slide 30

Slide 30 text

Why Why It's rendered twice by renderToStaticMarkup and renderToHTML ?

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

The case of React Apollo const Dogs = ({ onDogSelected }) => ( {({ loading, error, data }) => { if (loading) return 'Loading...'; if (error) return `Error! ${error.message}`; return ( {data.dogs.map(dog => ( {dog.breed} ))} ); }} );

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

For general purpose, React Apollo needs to correct all queries from component tree.

Slide 36

Slide 36 text

Our Solution Our Solution Fragments + React Apollo Fragments + Apollo Client

Slide 37

Slide 37 text

Fragments: query GetPerson { people(id: "7") { firstName lastName avatar(size: LARGE) } } fragment NameParts on Person { firstName lastName } query GetPerson { people(id: "7") { ...NameParts avatar(size: LARGE) } }

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

const data = (await apolloClientInstance.query(queryOptions)).data;

Slide 40

Slide 40 text

Measuring Performance (again) Measuring Performance (again)

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

2. Client Side Render Component 2. Client Side Render Component

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

By DynamicComponent: import dynamic from 'next/dynamic'; const DynamicComponentWithNoSSR = dynamic( () => import('../components/hello3'), { ssr: false } ); export default const Index = () =>
;

Slide 46

Slide 46 text

Measuring Performance (again) Measuring Performance (again)

Slide 47

Slide 47 text

Topics Topics Mercari Web Re-Architecture Apollo Next.js Performance Tuning Conclusion

Slide 48

Slide 48 text

Additionally The Latency Duration has Improved P50: 1,000ms -> 600ms

Slide 49

Slide 49 text

Also we saved nearly 1.5 million yen per month.

Slide 50

Slide 50 text

It doesn't matter which frame work you choose, the performance needs to be considered by application.

Slide 51

Slide 51 text

Don't Guess, Measure.