React + Node: Thoughts about Performance, Search Engines and User Experience

Vygandas Pliasas
4 min readJul 23, 2018

--

Intro

React allows you to create great applications. They are fast performing, easy to develop, easily read, with tons of features. Browser doesn’t need to reload because of router and how React renders things. Redux adds even more power for larger applications.

TypeScript makes your JavaScript look more like C# or Java code with interfaces and types. This allows to strict all types, have objects with properties, avoid mistypings.

Node has huge power and potential. With Node you can build everything — from assets rendering, TypeScript compilation, builds to fully featured backend web server with databases, ORM, sessions, api routes and so on.

Such apps have one html endpoint and routes all urls to same point (not always of course 🙂). This is a case that I’m talking about here. Other solutions are possible too. E.g. you have index.html and _redirects file which tells that every route goes to the same index.html. This way we can use React router and determine what components we need to render. This is ok so far as we don’t need this app to be SEO and scrapers friendly.

When there’re no meta tags from server

Why this is important

Google and other major search engines are able to render JS and scrape content. Any error might break this. If you want people to be able to share your pages and they would look ok on social media pages you must have meta data with description, image, title and other things. You can include all these things in your main html file but these will stay hardcoded if you use only React and some distant APIs. You can change this data via JS when you load your app but it will not be visible to social media scrapers because they are not actually rendering JS.

When there’re proper tags and content

What can be done

Best option is to push meta data to to html file while rendering it. EJS can be used for templating and Node can have various routes listening for requests. Web apps doesn’t have many different route patterns usually so that won’t be a big overhead. So instead of routing everything to the same file we should route everything to corresponding node server routes so it could handle data needed. This approach allows not only set meta tags but add other data needed for particular pages. For example you can add user object when user is logged in, because every time it will be needed and you have to make an api call.

Example

/ — get homepage title, description, image, link to meta tags

/:username — get same data from database and fill to the placeholders

/:username/:repository — do the same selection, format text and fill

We are talking about all these lines

Optimising performance

So when we have separated routes we are still serving all JS build in all routes. If you have traffic like 100k visitors / month it ok, but if you have same count per day you can notice very big change. Lets count: build.min.js weights 300KB. 100k visitors per day uses 30GB for JS downloads. Lets assume that we have 5 different views so that’s roughly 5 times overhead. Of course search forms, other components may go through all pages so we could have a common.js with these components and separate JS builds for different pages. This can be built as one pack per page or one common.min.js and additionally one pack per page. Having 2 JS includes has it’s bonus — common.min.js will get cached in user browser. This will reduce download traffic!

Don’t forget that visitors browsers caches things!

Bonus feature

With approach when you aggregate every request you are able to use things like A/B testing, better tracking, caching, data passing to pages that are only needed to that page. You won’t need to make any additional AJAX requests for that!

Ultimate solution

In my opinion that would solve all traffic, meta data and performance issues.

Example rough architecture of components

I hope you like it and find it useful in some way. If you have anything to add please feel free to leave a comment 😉

--

--