Slide 1

Slide 1 text

Move over, Gatsby React Static in Practice

Slide 2

Slide 2 text

Hello  I'm Nikas nikas.praninskas.com github.com/nikaspran @nikaspran Tech Lead @ Hostmaker

Slide 3

Slide 3 text

Hostmaker.com - 6 months ago ● Slow-ish ● Legacy stack ○ Slow builds (20+ min) ○ Difficult deployment ● Needed a brand refresh It was time for a rewrite

Slide 4

Slide 4 text

Challenges (1) ● Tons of unique content ○ 9 cities + 6 country hubs ○ 2+ languages each ○ 15+ "templates" ● Dynamically generated content ○ PhraseApp ○ Cosmic JS ○ Greenhouse ○ Our own API ○ ... 1500+ unique pages

Slide 5

Slide 5 text

Challenges (2) ● Search Engine Optimisation ● Page Speed ○ Don't want to be fetching all that dynamic content on every load ● Avoid the big switch-over ○ Tight deadlines ○ Difficult sell

Slide 6

Slide 6 text

We were looking for something... ⬚ React based ○ Just like all of our other products ⬚ Flexible ○ Had to integrate with our existing codebase ○ Had to support iterative migration ⬚ Simple ○ We were finishing our migration to React ○ Did not want new tools (i.e. GraphQL) to be a barrier ⬚ Long term ○ Simplicity === we can change fetching strategies, add caching, etc.

Slide 7

Slide 7 text

Why not use a static site generator?

Slide 8

Slide 8 text

Static Site Generators

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

"Next.js is a lightweight framework for static and server‑rendered applications." ● Originally for Isomorphic JavaScript Apps ● `next export` - prebuilt apps ● Hey, we're already using this!

Slide 11

Slide 11 text

● Great framework ● Well documented ● Large community ● Great framework - Next.js more than React ● Predefined structure ● Slow and difficult to optimise But...

Slide 12

Slide 12 text

We were looking for something... ✓ ⬚ React based ○ Just like all of our other products ⬚ Flexible ○ Had to integrate with our existing codebase ○ Had to support iterative migration ⬚ Simple ○ We were finishing our migration to React ○ Did not want new tools (i.e. GraphQL) to be a barrier ⬚ Long term ○ Simplicity === we can change fetching strategies, add caching, etc.

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

"Gatsby is a blazing fast modern site generator for React." ● The de facto static site generator for React

Slide 15

Slide 15 text

● Well documented ● Large community ● Fast & Powerful ● GraphQL everywhere ● Plugins for everything ● Need to write a plugin to use custom sources But...

Slide 16

Slide 16 text

We were looking for something... ✓ ✓ ✓ ⬚ React based ○ Just like all of our other products ⬚ Flexible ○ Had to integrate with our existing codebase ○ Had to support iterative migration ⬚ Simple ○ We were finishing our migration to React ○ Did not want new tools (i.e. GraphQL) to be a barrier ⬚ Long term ○ Simplicity === we can change fetching strategies, add caching, etc.

Slide 17

Slide 17 text

Static Site Generators - two clear options

Slide 18

Slide 18 text

Static Site Generators - React Static Why are we talking about this then?

Slide 19

Slide 19 text

"React-Static is a fast, lightweight, and powerful framework for building static-progressive React applications and websites." ● The promise of the power of Gatsby without the complexity ● It's just React

Slide 20

Slide 20 text

Gatsby - "Programatically create pages from data"

Slide 21

Slide 21 text

React Static - just like, getRoutes(), lol

Slide 22

Slide 22 text

How it works - 2 main concepts /src App.js package.json static.config.js index.js /components

Slide 23

Slide 23 text

How it works - static.config.js (1) Routes ● static.config.js ● App.js

Slide 24

Slide 24 text

How it works - static.config.js (2) Generate a route for each locale ● static.config.js ● App.js

Slide 25

Slide 25 text

App.js static.config.js

Slide 26

Slide 26 text

How it works - App.js Dynamic routes (Signup) React-static routes ● static.config.js ● App.js

Slide 27

Slide 27 text

We were looking for something... ✓ ✓ ✓ ✓ ⬚ React based ○ Just like all of our other products ⬚ Flexible ○ Had to integrate with our existing codebase ○ Had to support iterative migration ⬚ Simple ○ We were finishing our migration to React ○ Did not want new tools (i.e. GraphQL) to be a barrier ⬚ Long term ○ Simplicity === we can change fetching strategies, add caching, etc.

Slide 28

Slide 28 text

The drawback A little scary

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

What went well

Slide 31

Slide 31 text

What went well - Very customisable ● Integrated pretty well with our existing codebase ● Tailored to our needs: ○ CSS modules ○ Imgix ○ Translations and localized content ○ Custom webpack config

Slide 32

Slide 32 text

What went well - Great development experience ● Hot reloading ● Detailed logging when something goes wrong

Slide 33

Slide 33 text

What went well - Great performance ● Pretty great out of the box ● Gives us a lot of options long term ○ Code splitting ○ Dynamic loading

Slide 34

Slide 34 text

What went well - Did everything it had to ● Started with 500 pre-built pages, now up to 1500+ ● Loading data from 12+ endpoints at build time ● Around 3 minute build time ● Can scale long term

Slide 35

Slide 35 text

What did not go well

Slide 36

Slide 36 text

What did not go well - Documentation ● Covers everything, but we often had to read the source ● On the bright side, the source is easy to understand

Slide 37

Slide 37 text

What did not go well - Client/Server is still a thing ● Even though there's no "server", there's still a build step run via Node ● Can't always use the obvious solution

Slide 38

Slide 38 text

Main Takeaway Stay in React-land

Slide 39

Slide 39 text

Main Takeaway - getLocale() ● Need to get the current locale (city, language) for rendering data ● Used everywhere ● One of the most important parts of “plumbing”

Slide 40

Slide 40 text

● Works great in dev and for regular users ● Does not work when pre-building ● The bug is hidden at dev time ○ All pre-built files use the default fallback ○ Gets the correct value during runtime Main Takeaway - standard approach localeService.getLocale()

Slide 41

Slide 41 text

Main Takeaway - possible solution? ● Need some data globally ● Need to be able to instantiate via props why not use React Context?

Slide 42

Slide 42 text

Main Takeaway - the React-land approach (1) A context provider From getRoutes()

Slide 43

Slide 43 text

Main Takeaway - the React-land approach (2) HoC wrapper Injected via props

Slide 44

Slide 44 text

React-land everywhere ● No more mismatches between build and runtime ● We've since started using providers and context in other projects too

Slide 45

Slide 45 text

A Different Kind of Context

Slide 46

Slide 46 text

JAMstack "Modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup." JS API .html build .css .js Markup - jamstack.org

Slide 47

Slide 47 text

JAMstack Benefits ● Easy deployment ○ Just upload everything to a CDN (i.e. AWS S3) ● Blazing fast ○ Scaling -> just "add more CDN" ○ No waiting for content, no loading screens ● Great dev experience ○ Can't beat free - Github Pages, Netlify etc.. ○ Reproducible builds -> easy debugging

Slide 48

Slide 48 text

We are not alone "SmashingMagazine.com is now much faster, they went from 800 ms time to first load to 80ms." - www.netlify.com/case-studies/smashing/

Slide 49

Slide 49 text

In summary ● Mostly ● Would we do it again?

Slide 50

Slide 50 text

In summary ● Mostly ● Would we do it again? Yes!

Slide 51

Slide 51 text

nikas.praninskas.com github.com/nikaspran @nikaspran Let's keep in touch: Thank you! Live Demo @ hostmaker.com/careers