<?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: Mladen Stojanovic</title>
    <description>The latest articles on DEV Community by Mladen Stojanovic (@mladenstojanovic).</description>
    <link>https://dev.to/mladenstojanovic</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%2F3560%2F17693602.jpeg</url>
      <title>DEV Community: Mladen Stojanovic</title>
      <link>https://dev.to/mladenstojanovic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mladenstojanovic"/>
    <language>en</language>
    <item>
      <title>Get 100 lighthouse performance score with a React app</title>
      <dc:creator>Mladen Stojanovic</dc:creator>
      <pubDate>Tue, 07 May 2024 19:35:50 +0000</pubDate>
      <link>https://dev.to/mladenstojanovic/get-100-lighthouse-performance-score-with-a-react-app-hc6</link>
      <guid>https://dev.to/mladenstojanovic/get-100-lighthouse-performance-score-with-a-react-app-hc6</guid>
      <description>&lt;p&gt;⁠In this article, I will lead you through a high-level setup on what is needed to achieve those always-eluding high scores in your lighthouse metrics, even if you use a proper React app, and fetch everything from a CMS!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In subsequent posts, I might dive deeper into the details of each individual component of this setup&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What are we looking at?
&lt;/h3&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9irqpzot2tpvqacwlp9.jpeg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9irqpzot2tpvqacwlp9.jpeg" alt="Chrome network tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You probably looked at your network tab numerous times debugging some API calls and looking at your requests and responses, but I bet you haven't paid too much attention to the Waterfall column of this table, and that one can paint almost a full picture of a website from a performance perspective, and we'll refer back to it from our sections below.&lt;/p&gt;

&lt;p&gt;What can we observe from this waterfall example?&lt;/p&gt;

&lt;p&gt;First of all, you can notice that the home page loaded extremely fast, it took just 708ms for it to completely load (but not fully finish - more on that later) and the total downloaded content is just 162kBs, which is insane compared to a whopping 490MBs of just node modules this small project has!&lt;/p&gt;

&lt;p&gt;We can group this waterfall into roughly 3 parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;HTML Document&lt;/li&gt;
&lt;li&gt;Assets &amp;amp; JS&lt;/li&gt;
&lt;li&gt;Other files that are not needed for the initial render (but important for performance otherwise!)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;HTML document pretty much lays down the "plan" and tells our browser that the assets and JS files are needed next and that they should be downloaded in parallel. You can observe this behavior in the waterfall by noticing this group of files that started to download at the same time, and the third group of documents, downloaded after everything has been completed which serve the purpose of "preloading" the pages from the navigation bar and speed up subsequent linking to them.&lt;/p&gt;

&lt;p&gt;Let's talk about the 2 things that make this happen: building and serving&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the app
&lt;/h3&gt;

&lt;p&gt;Even though there is now a variety of frameworks that can do somewhat of a similar thing, I always keep coming back to Next.js as I believe it is the most mature React server-side-rendering option out there. The time this framework has been out really can be seen by the amount of optimization these guys did to bring this framework to the best light possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cool, but the only time I previously managed to get 100 performance score is when I deployed a static html + css website, how the hell did you manage it with Next.js?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Someone on the internet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, we're pretty much doing the same thing :) &lt;/p&gt;

&lt;p&gt;If you set in your &lt;code&gt;next.config.js&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nextConfig = {
  output: 'export'
}

module.exports = nextConfig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;it will generate an out folder with static html, css, and js!&lt;br&gt;
Not only that but Next.js magic will split all your code per page, and optimize as much as it can, therefore shrinking your js files to a minimum!&lt;/p&gt;

&lt;p&gt;Using the Next router will also enable prefetching of your next pages so when you click on another page, it will appear almost instantly!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;First of all, you can notice that the home page loaded extremely fast, it took just 708ms for it to completely load (but not fully finish - more on that later)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you get back to this paragraph and the waterfall graph, you can notice a couple of files downloaded after the red line which marks the loaded event, and those are metadata for about and blog pages, which are in my navbar! &lt;br&gt;
⁠&lt;br&gt;
⁠Next.js loaded everything needed for this page, rendered it fully thus making it blazing fast, and then after that, loaded some metadata for other pages without blocking anything else. Having to set up something like this ~5 years ago required having a team of webpack and JS gurus and ninjas so I'm in awe that we get configurations like this out of the box today.&lt;/p&gt;

&lt;p&gt;But wait a minute, I told you about fetching the data from a CMS, how is that being handled?&lt;/p&gt;

&lt;p&gt;Using Next.js generateStaticParams function in combination with dynamic route segments will fetch all your CMS content in build time, and generate each blog post page to a static html file,  as well as the blog post list, therefore losing another set of API calls from the client! &lt;br&gt;
⁠&lt;br&gt;
⁠Here is all the magic in the code snippet from my page @ &lt;code&gt;src/app/posts/[slug]/page.jsx&lt;/code&gt;&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const AllPosts = &lt;code&gt;&lt;br&gt;
  query AllPosts {&lt;br&gt;
    posts(orderBy: publishedAt_DESC) {&lt;br&gt;
      id&lt;br&gt;
      slug&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
&lt;/code&gt;;

&lt;p&gt;async function getPosts() {&lt;br&gt;
  const allPosts = await fetch(process.env.HYGRAPH_ENDPOINT, {&lt;br&gt;
    method: 'POST',&lt;br&gt;
    headers: {&lt;br&gt;
      'Content-Type': 'application/json'&lt;br&gt;
    },&lt;br&gt;
    body: JSON.stringify({&lt;br&gt;
      query: AllPosts&lt;br&gt;
    })&lt;br&gt;
  }).then((res) =&amp;gt; res.json())&lt;/p&gt;

&lt;p&gt;return allPosts.data.posts&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;export async function generateStaticParams() {&lt;br&gt;
  const posts = await getPosts()&lt;br&gt;
  return posts.map((post) =&amp;gt; ({&lt;br&gt;
    slug: post.slug&lt;br&gt;
  }))&lt;br&gt;
}&lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Serving the app&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;We have our static and optimized files, now we have to serve our app somewhere.&lt;/p&gt;

&lt;p&gt;We will store our files on the s3 bucket and place Cloudfront CDN in front of it.&lt;/p&gt;

&lt;p&gt;What do we get from that setup?&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuukwatz2xl1lw7s050qn.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuukwatz2xl1lw7s050qn.png" alt="File details from a single file in network tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking at one of the files in the network tab you will notice that the file is encoded with br which stands for brotli compression algorithm which has better compression around 15-20% than gzip which was previously the standard.&lt;/p&gt;

&lt;p&gt;On top of that  Cloudfront is caching our data which you can see by Hit from cloudfront message which means that your static content (which is your whole app at this point) is available physically in a location near you, which will bring latency to a minimum!&lt;/p&gt;

&lt;p&gt;Using a CDN with your fully static app makes so much sense, and when you get a good compression algorithm on top of that, plus the build-time optimizations, can't get any better than that!&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus - CMS
&lt;/h3&gt;

&lt;p&gt;Bonus points for getting that 100 SEO score go to Hygraph CMS, as it has good SEO support, graphQL API as you saw in the code snippet above so you can generate queries easily, as well as good templates and starters (which I used for my blog).&lt;/p&gt;

&lt;p&gt;Feel free to check out the performance mentioned at &lt;a href="https://mrocketsolutions.com/blog" rel="noopener noreferrer"&gt;https://mrocketsolutions.com/blog&lt;/a&gt; and comment below if you have any other options or questions!&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>performance</category>
      <category>seo</category>
    </item>
    <item>
      <title>How to deploy a React app without a server, easy, no compromises</title>
      <dc:creator>Mladen Stojanovic</dc:creator>
      <pubDate>Tue, 27 Oct 2020 01:02:32 +0000</pubDate>
      <link>https://dev.to/mladenstojanovic/how-to-deploy-a-react-app-without-a-server-easy-no-compromises-54co</link>
      <guid>https://dev.to/mladenstojanovic/how-to-deploy-a-react-app-without-a-server-easy-no-compromises-54co</guid>
      <description>&lt;h1&gt;
  
  
  The story
&lt;/h1&gt;

&lt;p&gt;You have an idea of an awesome app you want to create and you have a good knowledge of React, so what do you do?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app myApp
cd myApp
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and you are good to go! Everything is going really smoothly in your local environment and nothing stands in your way to creating that beautiful UI, leveraging the power of React all along the way.&lt;/p&gt;

&lt;p&gt;Time passes by, you finish your app, and surely, you want to show your app to the world.&lt;br&gt;
Maybe you are not ready for a full-fledged production-ready app with a domain, and all the bells and whistles, but only want to show it to someone else. You want to have it online without too much hassle.&lt;/p&gt;

&lt;p&gt;So, what are your options?&lt;/p&gt;

&lt;p&gt;When running &lt;code&gt;npm run build&lt;/code&gt; to create an optimized production build of your app that create-react-app provides, info in the terminal window tells you this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means you need to have a server in place to get your application up and running.&lt;br&gt;
The problem with servers is that computing power costs money, and there is a small chance you will find it unlimited for free anywhere, and also, you really aren't ready to pay money for your app at the moment. Other than that, setting up an HTTP server, getting a domain, etc. is a challenge on its own...&lt;br&gt;
But, you are a seasoned React veteran. You know that building a React app gives you a folder with all the files you need to have an app working.&lt;/p&gt;
&lt;h1&gt;
  
  
  Cloud services
&lt;/h1&gt;

&lt;p&gt;That is where the first major part of this puzzle gets solved... cloud computing!&lt;br&gt;
But it's really not that exotic because I'm mostly talking about storage solutions those provide, Azure Blob Storage, and Amazon s3 buckets.&lt;br&gt;
Both of them have an option to host a static website, and setting it up is fairly easy since both Azure and AWS provide free tier services for storage solutions that you cannot go out of if they are being used in a non-high load/traffic use-case. Definitely read the pricing tables for both of them if you plan to host something serious on them!&lt;/p&gt;
&lt;h1&gt;
  
  
  create-react-app on AWS s3
&lt;/h1&gt;

&lt;p&gt;I will now show you a really basic create-react-app deployed to an s3 bucket, and later on, I will show you how to do it by yourself on Azure! You can easily find similar tutorials for deploying static websites on the AWS s3 bucket. Comment below if you want an AWS s3 deployment tutorial as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://flex-app-dev.s3-website.eu-west-3.amazonaws.com"&gt;my really complex React app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will immediately recognize the default create-react-app screen with a twist. I added a router and an "About" page with links that can guide you back and forth. &lt;br&gt;
Our demo app works great until you try to refresh, or land directly on a page which is not our home page [e.g. &lt;a href="http://flex-app-dev.s3-website.eu-west-3.amazonaws.com/about"&gt;/about&lt;/a&gt;]. This is where any relatively serious app fails using this approach.&lt;br&gt;
The problem is that a React app is a single-page app with just one index.html which executes js files who then do their magic and fill up our app with all the beautiful content. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjuk9arkgm12yr7zet35r.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjuk9arkgm12yr7zet35r.PNG" alt="s3 bucket content" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you take a look at the bucket for this app, you will quickly realize that there is no "about" folder with an &lt;code&gt;index.html&lt;/code&gt; file inside of it, so we rightfully get a 404 error. We would need to have a server that redirects all of our traffic to this index.html and the javascript inside which will boot up our React app and figure out what we are trying to see.&lt;/p&gt;
&lt;h1&gt;
  
  
  Next.js
&lt;/h1&gt;

&lt;p&gt;This is where &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; comes in and saves the day!&lt;/p&gt;

&lt;p&gt;If you don't know what Next.js is, seriously go look it up and do a bit of research, it's awesome!&lt;/p&gt;

&lt;p&gt;I cannot give Next.js enough justice by doing this, but I will try to sum it up for anyone who hasn't heard about it before. &lt;br&gt;
Next.js is a framework for React which mainly provides server-side rendering out of the box, and it can be seen only as an "extension" to React because you still only write regular js and jsx (ts/tsx also supported!), but it is much, much more! Next.js gives us a router out of the box and it only "forces" us to use the file system as routes, so every file inside the &lt;code&gt;pages&lt;/code&gt; folder is a regular React component, but it is also a route.&lt;br&gt;
For example, creating a component inside the pages folder like &lt;code&gt;pages/about.js&lt;/code&gt; instantly registers the &lt;code&gt;/about&lt;/code&gt; route to go to this file. &lt;br&gt;
Next.js also provides us with some additional functions that help server-side data fetching which will come in handy pretty soon.&lt;br&gt;
You can start a new Next.js project as easy as create-react-app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app
# or
yarn create next-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The project
&lt;/h1&gt;

&lt;p&gt;I created a small Next.js app which I connected to a &lt;a href="https://www.thecocktaildb.com/api.php"&gt;free cocktails API&lt;/a&gt;, fetched a couple of cocktails, listed them, created a detail page of every one of them. Here is the link to the project so you can check it out&lt;/p&gt;

&lt;p&gt;&lt;a href="https://staticappdemo.z6.web.core.windows.net/"&gt;https://staticappdemo.z6.web.core.windows.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also provided the &lt;a href="https://github.com/mladenstojanovic/enjoying-next-demo"&gt;source code on github&lt;/a&gt; if you want to follow along.&lt;/p&gt;

&lt;p&gt;I will try to explain how this is done pointing out a couple of "gotchas" inside Next.js and then do the step by step deployment to Azure!&lt;/p&gt;

&lt;p&gt;You will notice that inside my &lt;code&gt;pages&lt;/code&gt; folder I have a structure like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+----_app.js
+----index.js
+----cocktails
|   +-- [id].js
|   +-- index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pages/cocktails/index.js&lt;/code&gt; is my &lt;code&gt;/cocktails&lt;/code&gt; route, and &lt;code&gt;pages/cocktails/[id].js&lt;/code&gt; is Next.js way to handle dynamic routes, so &lt;code&gt;/cocktails/123abc&lt;/code&gt; will go to that file and we will have &lt;code&gt;123abc&lt;/code&gt; available to us inside this file as &lt;code&gt;id&lt;/code&gt;.&lt;br&gt;
Since Next.js provides us with &lt;a href="https://nextjs.org/docs/advanced-features/static-html-export"&gt;static HTML export&lt;/a&gt;, we will use that feature to fetch our cocktails in build time and deploy everything as static pages to our cloud storage solution.&lt;/p&gt;

&lt;p&gt;The first thing we need to do is use the &lt;code&gt;getStaticPaths&lt;/code&gt; function that Next.js provides for us so that we can tell it what routes do we need to be generated at build time.&lt;br&gt;
Inside our &lt;code&gt;[id].js&lt;/code&gt; file you can see this piece of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This function gets called at build time
export async function getStaticPaths() {
  // Call an external API endpoint to get cocktails
  const res = await fetch(
    "https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Alcoholic"
  );
  const parsedRes = await res.json();
  const cocktails = parsedRes.drinks.slice(0, 9);

  // Get the paths we want to pre-render based on cocktails
  const paths = cocktails.map((cocktail) =&amp;gt; ({
    params: { id: cocktail.idDrink },
  }));

  // We'll pre-render only these paths at build time.
  // { fallback: false } means other routes should 404.
  return { paths, fallback: false };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see here, we only fetch the cocktails for their ids and map them as per documentation so that Next.js knows those are the ids we want to have for our cocktail routes.&lt;/p&gt;

&lt;p&gt;After that, you can see &lt;code&gt;getStaticProps&lt;/code&gt; being used like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This also gets called at build time
export async function getStaticProps({ params }) {
  // params contains the cocktail `id`.
  // If the route is like /cocktails/1, then params.id is 1
  const res = await fetch(
    `https://www.thecocktaildb.com/api/json/v1/1/lookup.php?i=${params.id}`
  );
  const cocktail = await res.json();

  // Pass cocktail data to the page via props
  return { props: { cocktail: cocktail.drinks[0] } };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the id to fetch details of an individual cocktail and then pass it down for us to use it inside &lt;code&gt;props&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next.js doesn't know that we want to use it as a static HTML export so it won't create the file structure as we want it for that use case. We can quickly fix that by adding this piece of code inside &lt;code&gt;next.config.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  trailingSlash: process.env.NEXT_PUBLIC_ENV === "prod",
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells us to use the &lt;code&gt;trailingSlash&lt;/code&gt; when doing a production build. You now need &lt;code&gt;.env.development&lt;/code&gt; and &lt;code&gt;.env.production&lt;/code&gt; files which Next.js will automatically recognize when building the app for production, or for you to use in your local environment.&lt;/p&gt;

&lt;p&gt;To build the app as static HTML, I added a new script to &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"build:static": "next build &amp;amp;&amp;amp; next export"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;npm run build:static&lt;/code&gt; creates an &lt;code&gt;out&lt;/code&gt; folder with all our pages built inside their own &lt;code&gt;id&lt;/code&gt; folders. If everything went well, your out folder should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F35wwwwvlfqi8zheje3do.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F35wwwwvlfqi8zheje3do.PNG" alt="Out folder structure" width="315" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Deploy to Azure
&lt;/h1&gt;

&lt;p&gt;Creating a free Azure account should be pretty easy, and in the Azure dashboard, use the search bar on top to find the &lt;code&gt;Storage accounts&lt;/code&gt; service. After entering &lt;code&gt;Storage accounts&lt;/code&gt; you should see something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpo7neezl94ee1g7i8eq5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpo7neezl94ee1g7i8eq5.PNG" alt="Storage accounts dashboard" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;code&gt;Create storage account&lt;/code&gt; button or &lt;code&gt;Add&lt;/code&gt; button on top left. &lt;/p&gt;

&lt;p&gt;You will need to create a new resource group (if you haven't did that previously) and you can do that inside the wizard easily. It looks like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqlf3sma7f9cbh3q7u57c.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqlf3sma7f9cbh3q7u57c.PNG" alt="create resource group" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill in the storage account name and choose a location geographically closest to you (or your audience).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgvfs0m2e9vfecp7r3bry.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgvfs0m2e9vfecp7r3bry.PNG" alt="Alt Text" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leave everything else as default and go straight for the &lt;code&gt;Review + create&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;The deployment will take about a minute or less and you should now see your new storage account inside the &lt;code&gt;Storage accounts&lt;/code&gt; dashboard&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuub4oc42ilsqhjui47zs.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuub4oc42ilsqhjui47zs.PNG" alt="Alt Text" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the newly created storage account. It will open up a menu. Scroll down and find the &lt;code&gt;Static website&lt;/code&gt; option. Enable it and fill the Index document name with &lt;code&gt;index.html&lt;/code&gt; and Error document path with &lt;code&gt;404/index.html&lt;/code&gt;. Next.js provides default 404 page for us. Click the save button and you will have your new website endpoint ready! It should look something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1obq2ena9jjrkrtd2n19.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1obq2ena9jjrkrtd2n19.PNG" alt="Alt Text" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll the menu back up to &lt;code&gt;Storage explorer (preview)&lt;/code&gt; click on it and open the &lt;code&gt;BLOB CONTAINERS&lt;/code&gt; folder and there you will see a &lt;code&gt;$web&lt;/code&gt; folder. That is where your built app files will be.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fghu4cyap3791l9s05s01.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fghu4cyap3791l9s05s01.PNG" alt="Alt Text" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we can upload our files here, we need to add ourselves as a blob owner, otherwise, the upload will fail. To do that, on the menu, find &lt;code&gt;Access Control (IAM)&lt;/code&gt; option. Click on the &lt;code&gt;Add role assignments&lt;/code&gt;. Select the role &lt;code&gt;Storage Blob Data Owner&lt;/code&gt;. Assign access to &lt;code&gt;User, group, or service principal&lt;/code&gt; and in &lt;code&gt;select&lt;/code&gt; field type in your e mail address associated with your Azure account. It should look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgryajxjrywgi4zy3giqx.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgryajxjrywgi4zy3giqx.PNG" alt="Alt Text" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next thing you want to do is &lt;a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"&gt;install the Azure CLI for your OS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that is done, enter your terminal and start with logging in to Azure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A new browser tab should open up for you to log in to your Azure account.&lt;/p&gt;

&lt;p&gt;After that, you need to find out the key for your storage account. To do that run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az storage account keys list --account-name 'mladenteststorage'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;just replace &lt;code&gt;mladenteststorage&lt;/code&gt; with your storage account name.&lt;/p&gt;

&lt;p&gt;You should get an output that looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az storage account keys list --account-name 'mladenteststorage'
[
  {
    "keyName": "key1",
    "permissions": "Full",
    "value": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
  {
    "keyName": "key2",
    "permissions": "Full",
    "value": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take the &lt;code&gt;"value"&lt;/code&gt; from the &lt;code&gt;"key1"&lt;/code&gt; and write it down.&lt;/p&gt;

&lt;p&gt;And finally to upload everything to our blob storage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az storage blob upload-batch -d '$web' -s 'C:\Users\mlst2502\...path-to-your-project\out' --account-name 'mladenteststorage' --account-key 'key-that-you-wrote-down-previously'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you have it! Your app should be visible on the URL you saw in the &lt;code&gt;Static website&lt;/code&gt; section of your storage account!&lt;/p&gt;

&lt;p&gt;If you read this all the way till the end, thank you for your attention! I hope this helped you in any way, and if you have any questions about the topic, feel free to ask me in the comment section, or find me directly on any of my social networks which are listed on &lt;a href="https://www.mladens.com"&gt;my website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What is React Server Side Rendering and should I use it?</title>
      <dc:creator>Mladen Stojanovic</dc:creator>
      <pubDate>Fri, 10 Aug 2018 12:58:58 +0000</pubDate>
      <link>https://dev.to/mladenstojanovic/what-is-react-server-side-rendering-and-should-i-use-it-5b7i</link>
      <guid>https://dev.to/mladenstojanovic/what-is-react-server-side-rendering-and-should-i-use-it-5b7i</guid>
      <description>&lt;p&gt;As stated in the title, I will try to present some pros and cons regarding this not-so-hot-anymore technology, and also help someone new to React SSR understand it a bit more.&lt;/p&gt;

&lt;p&gt;First of all, let's dive into some terminology stuff&lt;/p&gt;

&lt;h3&gt;
  
  
  SSR? Isomorphic? Universal? WTF?
&lt;/h3&gt;

&lt;p&gt;First of all, for some of you that don't know (as I haven't until recently) server side rendering is nothing special. Any ordinary static website is server side rendered, a server gets your request and spits out HTML to your browser. &lt;br&gt;
We also had templating languages doing some neat tricks for us that are considered as server side rendering.&lt;br&gt;
&lt;strong&gt;BUT&lt;/strong&gt; when we talk about JavaScript, Server Side Rendering usually points out to an ability of a front-end code to render HTML while running on a back-end system.&lt;/p&gt;
&lt;h4&gt;
  
  
  SPA + SSR = Isomorphic*
&lt;/h4&gt;

&lt;p&gt;* or universal&lt;/p&gt;

&lt;p&gt;Isomorphic or Universal apps are interchangeable phrases commonly referring to a way of writing your apps so that you use the same language on both server and client side. More specifically, for JavaScript, best case scenario would be that you also use the same syntax. &lt;br&gt;
For example if you are running your back-end in NodeJS you are probably using CommonJS module syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//...Our awesome app code...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./circle.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//...Rest of our awesome app code...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you write your React in ES6&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//...Our awesome app code...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//...Rest of our awesome app code...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Webpack we can start using our ES6 import syntax also on server side of our app, and that is the true goal of an isomporphic app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why would I want to use React with server side rendering in the first place?
&lt;/h3&gt;

&lt;p&gt;Well, our traditional React app would have this flow when loading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browser requests a page&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PAUSE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;We get pretty empty html and a script tag pointing to a JS file where all of our code lives&lt;/li&gt;
&lt;li&gt;Browser requests that script&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PAUSE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Content visible on the screen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We now see that we have 2 round-trips to server, which is kinda acceptable. But let's imagine that our app has a list of blog posts, or a series of images, or whatever that we need to request from some API, now the flow is a bit more realistic and looks something like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browser requests a page&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PAUSE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Browser requests our JS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PAUSE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;React app boots, requests data from backend&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PAUSE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Content visible on the screen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, the number of requests increased, so there is a lot more happening before our user sees anything on the screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now for the Server Side Rendered React App&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browser requests a page&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PAUSE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Content visible on the screen!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Whaaat? How? Let's look at it in a bit more detail&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browser requests a page&lt;/li&gt;
&lt;li&gt;    Server loads React in memory&lt;/li&gt;
&lt;li&gt;    Server fetches required data&lt;/li&gt;
&lt;li&gt;    Server renders React app&lt;/li&gt;
&lt;li&gt;    Server sends generated HTML down to the browser&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;USER SEES CONTENT&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Require JS file&lt;/li&gt;
&lt;li&gt;React App boots, requests data from backend&lt;/li&gt;
&lt;li&gt;App rerenders (hydrates) on the screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see we did only 1 trip to the server before getting some content for our user. Now, the content that we served before we rerendered everything is static, so if our user is super fast and starts clicking before hydrate happens, the app will not be responsive.&lt;/p&gt;

&lt;h3&gt;
  
  
  What problems are we solving using this approach?
&lt;/h3&gt;

&lt;p&gt;Two of the biggest ones are &lt;strong&gt;SEO&lt;/strong&gt; and &lt;strong&gt;perceived performance boost&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your app is a bit larger, search engine crawlers will see your page as a mostly empty html with a single &lt;code&gt;script&lt;/code&gt; tag that requests your massive React app, as it won't wait for the moment it fills up the DOM, your page won't get indexed.&lt;br&gt;
Meanwhile, Google improved their crawlers to search for javascript created content also, but Bing or Baidu are still lacking this feature, so if larger percentage of your audience is coming from other search engines, you will have to work that out.&lt;/p&gt;

&lt;p&gt;With React SSR your First Meaningful Paint time will be (in most cases) significantly lower. This is an important metric for some companies. You certainly heard stories of numerous companies increasing their profit by cutting down on load times for their web apps. (&lt;a href="https://wpostats.com/" rel="noopener noreferrer"&gt;https://wpostats.com/&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Above I wrote &lt;strong&gt;perceived&lt;/strong&gt; performance boost, and while it is true that you will get content to your user faster than using a traditional React app, the catch is that it probably isn't a &lt;em&gt;performance&lt;/em&gt; boost. In the SSR request example a little bit above you see that server is also doing everything that client does: It boots up React, renders the app for you and spits out HTML. This means that you are doing everything 2 times which isn't ideal. Also &lt;code&gt;renderToString()&lt;/code&gt; method that react uses to convert your beautiful jsx code to HTML is really slow and also synchronous. This puts server under more load, and your initial response from server will arrive later. &lt;/p&gt;

&lt;p&gt;If you decided to go with server side rendering, you will probably have 2 servers: One for the API and business logic, and another one for rendering purposes. Knowing how big of a task your rendering process is, you can scale up your rendering servers to match the increased load.&lt;/p&gt;

&lt;p&gt;Since I am not the first one who had issues with these problems, engineers over at Walmart labs created a tool that optimizes those quirks React SSR has, called Electrode. They also wrote couple of cool articles about it, really worth reading if you made it this far :) (&lt;a href="https://medium.com/walmartlabs/using-electrode-to-improve-react-server-side-render-performance-by-up-to-70-e43f9494eb8b" rel="noopener noreferrer"&gt;https://medium.com/walmartlabs/using-electrode-to-improve-react-server-side-render-performance-by-up-to-70-e43f9494eb8b&lt;/a&gt;)&lt;br&gt;
There are also "frameworks" for React SSR like Next.js for example which is gaining nice traction and support from community. &lt;/p&gt;

&lt;p&gt;Using React SSR also adds multiple levels of complexity. Remember freely using &lt;code&gt;window&lt;/code&gt; or &lt;code&gt;document&lt;/code&gt; to do stuff? Forget about it!&lt;/p&gt;

&lt;p&gt;I am just kidding of course, but you will have to be extra cautious, since the app will run first in a Node environment, &lt;code&gt;window&lt;/code&gt; and &lt;code&gt;document&lt;/code&gt; for example are not defined there, so you will have to restrain yourself from using them outside &lt;code&gt;componentDidMount&lt;/code&gt; or without &lt;code&gt;if (typeof window !== 'undefined')&lt;/code&gt;. I cannot remember how many times my app broke until I got used to it.&lt;/p&gt;

&lt;p&gt;Your Node server will catch your routes and pass it down to React to decide what to render, so how does it have access to your router on server? It doesn't. Solution? Double routes. Your Application renders depending on something from your Redux store? Double store.&lt;/p&gt;

&lt;p&gt;There are many complexities introduced with SSR, luckily for us, tools like Next.js solve many of them, but if you are stuck with solving all those problems by yourself, it will be really hard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use React Server Side Rendering?
&lt;/h3&gt;

&lt;p&gt;Maybe.&lt;/p&gt;

&lt;p&gt;If you / your company really values SEO, and significant number of your visits come from search engines other than google, yes.&lt;/p&gt;

&lt;p&gt;If you / your company really values user perceived performance, think about it, if your client side application performance can't get anything better, then yes.&lt;/p&gt;

&lt;p&gt;In any other case, my advice is to stay out of it, it will just increase complexity of your project without really much benefits.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>performance</category>
      <category>seo</category>
    </item>
    <item>
      <title>How we decreased load time by 40% by removing just 1 file</title>
      <dc:creator>Mladen Stojanovic</dc:creator>
      <pubDate>Thu, 28 Jun 2018 14:56:27 +0000</pubDate>
      <link>https://dev.to/mladenstojanovic/how-we-decreased-load-time-by-40-by-removing-just-1-file-1icj</link>
      <guid>https://dev.to/mladenstojanovic/how-we-decreased-load-time-by-40-by-removing-just-1-file-1icj</guid>
      <description>&lt;h3&gt;
  
  
  So the title of this article is really clickbait-ish, but in reality it is exactly what happened.
&lt;/h3&gt;

&lt;p&gt;I started working on a project around September last year. Since all of the NDA stuff happened with the client, I cannot write much about names, but it is a big company in their respective field. &lt;br&gt;
They are using a React SSR app to serve their websites which are not source of their income, it is for information, some blog posts, articles etc. Of course they have ads on it, and it is visited decently, but they didn't pay &lt;strong&gt;that&lt;/strong&gt; much attention to it.&lt;/p&gt;

&lt;p&gt;I know what you're going to say now: How come that they don't pay that much attention to it but they are using a really modern stack for their &lt;em&gt;"not so important"&lt;/em&gt; website?&lt;/p&gt;

&lt;p&gt;Well they wanted the previous team to build it with cutting edge tech since they were redesigning and recreating everything, and as you guessed, using some cutting edge technologies early in its adoption will leave you with (some) negative outcomes, but more on that in other posts (hopefully).&lt;/p&gt;

&lt;p&gt;Back to the present, my team and I got in as a part of a team that will maintain and add features to this (and several other) projects for this client. From the first day it really annoyed me how the app is slow, even though it is created as a server side rendered react app, it should be lightning fast! New Relic stats were coming in every week and showed something like 10 or 11 seconds of average loading time, it was really crazy!&lt;/p&gt;

&lt;p&gt;Couple of months in, I was at a tech conference where I attended a talk and workshop by Harry Roberts (&lt;a href="https://twitter.com/csswizardry" rel="noopener noreferrer"&gt;https://twitter.com/csswizardry&lt;/a&gt;) a performance consultant where I was really inspired by his biggest point in the whole presentation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your website's performance will increase as soon as you start paying attention to it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or something like that, it was a long time ago :)&lt;/p&gt;

&lt;p&gt;But from that point I actually started paying attention to this app's performance.&lt;br&gt;
In between standard issues and sprints, I started to analyze what are the biggest problems of our app and really fast I realized that our app's CSS file was &lt;strong&gt;2.9MB&lt;/strong&gt; unzipped and &lt;strong&gt;1.9MB&lt;/strong&gt; gzipped.&lt;br&gt;
I was shocked, how does a CSS file reaches this kind of size? It is a big app, but not THAT big. And gzip loves repetition, how this cannot be compressed even more?&lt;/p&gt;

&lt;p&gt;Time passed with new tasks and strict deadlines, we've all been there, but that CSS file just couldn't get out of my mind. One day my teammates and I sat down and started looking for a problem. We sorted every css file in the project and found out there was one that was 1.5MB large(!!!)&lt;/p&gt;

&lt;p&gt;Someone put 8 decently sized images (around 1500x600px), converted it to base64 and put it in a css file which was loaded every time in a bundle, even when it hasn't been used!&lt;br&gt;
Deleting that file reduced our bundled css file to 1.3MB unzipped, or 700KB gzipped! A huge win!&lt;/p&gt;

&lt;p&gt;Later on I tested the website with some performance tools and every single one showed decrease of 40 to 60% in load time! (first paint, full page load etc.)&lt;/p&gt;

&lt;p&gt;Moral of the story:&lt;/p&gt;

&lt;p&gt;Pay attention to your app's performance, sometimes really small changes can bring you really awarding results!&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
