<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ilker Altin</title>
    <description>The latest articles on DEV Community by ilker Altin (@ilker).</description>
    <link>https://dev.to/ilker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F125678%2F7b7b0938-f053-4d42-b45e-c394e9d17454.jpg</url>
      <title>DEV Community: ilker Altin</title>
      <link>https://dev.to/ilker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ilker"/>
    <language>en</language>
    <item>
      <title>Server-Side Rendering with React, Redux, and React-Router</title>
      <dc:creator>ilker Altin</dc:creator>
      <pubDate>Fri, 07 Jun 2019 13:09:23 +0000</pubDate>
      <link>https://dev.to/itnext/server-side-rendering-with-react-redux-and-react-router-2en7</link>
      <guid>https://dev.to/itnext/server-side-rendering-with-react-redux-and-react-router-2en7</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;tl;dr&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There is a huge discussion about Server-Side Rendering these days. Everyone says It’s hard to implement and maintain. I have created a &lt;strong&gt;React&lt;/strong&gt; News web application with &lt;strong&gt;3 different approaches&lt;/strong&gt; to be able to understand performance and implementation differences between each other. I wanted to make this application as close as possible to a real-world use case. I used; &lt;strong&gt;React, React-Router, Redux, Node.js,&lt;/strong&gt; and &lt;strong&gt;Express&lt;/strong&gt;. You can check each application from the links below;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;Single Page Application&lt;/em&gt;&lt;/strong&gt; &lt;a href="http://bit.ly/spa-react" rel="noopener noreferrer"&gt;&lt;strong&gt;bit.ly/spa-react&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;Server-Side Rendering (Universal)&lt;/em&gt;&lt;/strong&gt; &lt;a href="http://bit.ly/ssr-react" rel="noopener noreferrer"&gt;&lt;strong&gt;bit.ly/ssr-react&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;Server-Side Rendering with Redis&lt;/em&gt;&lt;/strong&gt; &lt;a href="http://bit.ly/ssr-cached" rel="noopener noreferrer"&gt;&lt;strong&gt;bit.ly/ssr-cached&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  WHY?
&lt;/h3&gt;

&lt;p&gt;I saw a lot of discussions online especially on Twitter also at the conferences about Server-side rendering. I know there are a lot of universal rendering frameworks for React but &lt;strong&gt;I wanted to build it by myself from scratch without any black-box solution.&lt;/strong&gt; But first It’s good to understand what is server-side and client-side rendering is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2A0AIrrQHAhke2mny9VfDmdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2A0AIrrQHAhke2mny9VfDmdw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Javascript Revolution
&lt;/h3&gt;

&lt;p&gt;Browsers are more powerful than 5–10 years ago. We started to create entire websites and web apps with client-side JavaScript. We started to call this method &lt;strong&gt;“Single Page Application”&lt;/strong&gt;. This leads us to create more interactive real-time updated web applications.&lt;/p&gt;

&lt;p&gt;But there is a problem with this approach, our initial HTML no longer contains all the data related to that URL.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Google and Social Media crawlers are not happy with this at all&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2AJsylByinmaPMMQmeHzO2lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2AJsylByinmaPMMQmeHzO2lg.png" alt="Client-Side Rendering (CSR)"&gt;&lt;/a&gt;&lt;br&gt;
Client-Side Rendering (CSR)&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Client Side Rendering? (CSR)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Rendering an app in a browser, generally using the DOM&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The initial HTML rendered by the server is a placeholder and the entire user interface and data rendered in the browser once all your scripts load.&lt;/p&gt;

&lt;h4&gt;
  
  
  How Client-Side Rendering works?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2AbFkE292yNaxErbbhJ8Ee-w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2AbFkE292yNaxErbbhJ8Ee-w.png" alt="A general overview of how Client-Side Rendering works"&gt;&lt;/a&gt;&lt;br&gt;
A general overview of how Client-Side Rendering works&lt;/p&gt;

&lt;h4&gt;
  
  
  PROS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  Rich site interactions&lt;/li&gt;
&lt;li&gt;  Fast rendering after the initial load&lt;/li&gt;
&lt;li&gt;  Partial real-time updates&lt;/li&gt;
&lt;li&gt;  Cheaper to host &amp;amp; scale&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  CONS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  SEO and index issues&lt;/li&gt;
&lt;li&gt;  Mostly initial bundle.js load duration&lt;/li&gt;
&lt;li&gt;  Performance issues on old mobile devices/slow networks&lt;/li&gt;
&lt;li&gt;  Social Media crawlers and sharing problems (SMO)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2Aqe37Y5guIZpo2ODJMBjBUw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2Aqe37Y5guIZpo2ODJMBjBUw.png" alt="Server-Side Rendering (SSR)"&gt;&lt;/a&gt;&lt;br&gt;
Server-Side Rendering (SSR)&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Server Side Rendering? (SSR)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Server rendering generates the full HTML for a page on the server in response to navigation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For our use case with React or with any other Javascript library/framework; Server-side rendering is a technique for rendering a normally client-side only single page app (SPA) on the server and then sending a fully rendered page to the browser.&lt;/p&gt;

&lt;h4&gt;
  
  
  How Server-side Rendering works?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2ASKOU13Gu35WJDL1X35rUaA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2ASKOU13Gu35WJDL1X35rUaA.png" alt="A general overview of how Server-Side Rendering works"&gt;&lt;/a&gt;&lt;br&gt;
A general overview of how Server-Side Rendering works&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;PROS&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  Consistent SEO&lt;/li&gt;
&lt;li&gt;  Performance, initial page load&lt;/li&gt;
&lt;li&gt;  Works well with Social Media crawlers and platforms (SMO)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  CONS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  Frequent requests&lt;/li&gt;
&lt;li&gt;  Slow page rendering (TTFB — Time to first byte)&lt;/li&gt;
&lt;li&gt;  Complex architecture (For universal approach)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Google indexes?
&lt;/h3&gt;

&lt;p&gt;We mentioned about SEO problems of Single Page Javascript Applications. It’s important to understand how Google index system works to solve this problem with Server-side Rendering.&lt;/p&gt;

&lt;p&gt;At Google I/O 2018 JavaScript session, John Mueller and Tom Greenaway gave some clarity on how the search engine indexes JavaScript. We learned that there are two waves of indexing, and this is how they work:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2AadAxURmASBsBzL14A9xhvQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2AadAxURmASBsBzL14A9xhvQ.png" alt="Google’s 2 wave indexing system"&gt;&lt;/a&gt;&lt;br&gt;
Google’s 2 wave indexing system&lt;/p&gt;

&lt;h3&gt;
  
  
  How to SSR?
&lt;/h3&gt;

&lt;p&gt;We have talked about almost all theoretical parts. Let’s focus on the implementation part and how we are going to achieve Server-side Rendering with React.&lt;/p&gt;

&lt;h4&gt;
  
  
  Methodology
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  Initial render on the server&lt;/li&gt;
&lt;li&gt;  Show fully formed HTML&lt;/li&gt;
&lt;li&gt;  JS executions&lt;/li&gt;
&lt;li&gt;  React takes over / re-render&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Challenges
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  JSX on Node.js&lt;/li&gt;
&lt;li&gt;  Redux on server&lt;/li&gt;
&lt;li&gt;  Routing&lt;/li&gt;
&lt;li&gt;  Rehydration&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Rehydration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;“Booting up” JavaScript views on the client such that they reuse the server-rendered HTML’s DOM tree and data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2Ax8OYUF7Ns8TdvD1euYHE9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2Ax8OYUF7Ns8TdvD1euYHE9w.png" alt="Rehydration [Image Source](https://developers.google.com/web/updates/2019/02/rendering-on-the-web)"&gt;&lt;/a&gt;&lt;br&gt;
Rehydration &lt;a href="https://developers.google.com/web/updates/2019/02/rendering-on-the-web" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2Ay_PcmZ0zI6geGResdNmd6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2Ay_PcmZ0zI6geGResdNmd6g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  News Web Application with React
&lt;/h3&gt;

&lt;p&gt;I have created a News application with React based on &lt;a href="https://newsapi.org/" rel="noopener noreferrer"&gt;News API&lt;/a&gt; with 3 different approaches. I created my custom implementation to understand how it works under the hood. Custom webpack configurations can be tricky with Create-React-App.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Single Page Application (Yellow)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Classic single page application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="http://bit.ly/spa-react" rel="noopener noreferrer"&gt;bit.ly/spa-react&lt;/a&gt; &lt;br&gt;&lt;br&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="http://bit.ly/spa-repo" rel="noopener noreferrer"&gt;bit.ly/spa-repo&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Server-Side Rendering — Universal (Red)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Initial render happens on the server (Node.js / Express). After first render and bundle.js load, React rehydrates and takes over the application. This means that each click after the first load will be handled by React-Router and it will work like a Single-page application. If you check the source code you will see the complete dom-tree with all data in it. If you refresh the same page or press enter on the URL bar, the current page will be handled by the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="http://bit.ly/ssr-react" rel="noopener noreferrer"&gt;bit.ly/ssr-react&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="http://bit.ly/ssr-repo" rel="noopener noreferrer"&gt;bit.ly/ssr-repo&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Server-Side Rendering with Redis (Blue)
&lt;/h4&gt;

&lt;p&gt;Works almost the same with Server-side version. I tried to cache HTML result just before sending to browser to see performance improvements. So the first response from a server will be cached at Redis for a certain URL, the second response will come from memory. To test this actually you can enter a URL, copy that URL and visit again on incognito or another browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="http://bit.ly/ssr-cached" rel="noopener noreferrer"&gt;bit.ly/ssr-cached&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Comparisons
&lt;/h3&gt;

&lt;p&gt;First of all, I wanted to check if Google would be able to index my universal application. As you can see below, &lt;strong&gt;it was able to see&lt;/strong&gt; all the page content without any problem. This also means that &lt;strong&gt;Social media crawlers&lt;/strong&gt; also can crawl my page content without a problem.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/S_TABJ4t_d8"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Google Search Console index check for Server-Side Rendering&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My second test was about performance. I did a couple of performance tests with Lighthouse tool and WepageTest.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZturEfmeqV0"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Desktop Load Comparison&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We can see how SSR shines under slow network conditions in the video below.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/yxMlvjTPwZw"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Mobile comparison on Moto G4 — Chrome — Slow Network&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Lighthouse Tests
&lt;/h4&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/UsnC1aScnng"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Single Page Application — Lighthouse result&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/lIvPXQLXWNc"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Server-Side Rendering Application — Lighthouse result&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Results Comparison
&lt;/h4&gt;

&lt;p&gt;Keep in mind, all these tests happened without a heavy load. So in the real world circumstances, results may change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2A3Su6M8LrK0NKVEvlmJUMEA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F1%2A3Su6M8LrK0NKVEvlmJUMEA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I really enjoyed and learned a lot while developing these applications. I didn’t mention a lot about the code part but all you can check implementations on the GitHub repos. I should mention that these implementations are just for proof-of-concept so far from production quality.&lt;/p&gt;

&lt;p&gt;So far I can say that Server-Side Rendering is not a magic implementation. It’s important to check if your business really needs it or not. You can see my opinionated decide list below.&lt;/p&gt;

&lt;h4&gt;
  
  
  When to use Single-Page Applications?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  Rich site interactions&lt;/li&gt;
&lt;li&gt;  The network is fast&lt;/li&gt;
&lt;li&gt;  Minimal server recourses&lt;/li&gt;
&lt;li&gt;  Main scripts are small or lazy loaded/split&lt;/li&gt;
&lt;li&gt;  Real-time / partial updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When to use Server-Side Rendering (Universal)?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  SEO is important&lt;/li&gt;
&lt;li&gt;  The network is slow&lt;/li&gt;
&lt;li&gt;  Enough server recourses&lt;/li&gt;
&lt;li&gt;  Main scripts are large and loads slowly&lt;/li&gt;
&lt;li&gt;  Social sharing is important&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Further Reading
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/web/updates/2019/02/rendering-on-the-web" rel="noopener noreferrer"&gt;&lt;strong&gt;Rendering on the Web | Web | Google Developers&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/dev-channel/a-netflix-web-performance-case-study-c0bcde26a9d9" rel="noopener noreferrer"&gt;&lt;strong&gt;A Netflix Web Performance Case Study&lt;/strong&gt;&lt;/a&gt;&lt;a href="https://medium.com/dev-channel/a-netflix-web-performance-case-study-c0bcde26a9d9" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/brillout/awesome-universal-rendering" rel="noopener noreferrer"&gt;https://github.com/brillout/awesome-universal-rendering&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>serversiderendering</category>
      <category>redux</category>
    </item>
  </channel>
</rss>
