2022-07-14
2256
#create react app#nextjs#react
Sean Connolly
3373
Jul 14, 2022 â‹… 8 min read

Comparing Create React App vs. Next.js performance differences

Sean Connolly Senior Web Architect intensely focused on fast teams and fast apps @thegoldenshun.

Recent posts:

Rust logo over black marble background.

Handling memory leaks in Rust

Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.

Ukeje Goodness
Nov 20, 2024 â‹… 4 min read
Robot pretending to be a person.

Using curl-impersonate in Node.js to avoid blocks

Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.

Antonello Zanini
Nov 20, 2024 â‹… 13 min read
Solving Eventual Consistency In Frontend

Solving eventual consistency in frontend

Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.

Kayode Adeniyi
Nov 19, 2024 â‹… 6 min read
How To Use Lazy Initialization Pattern With Rust 1.80

How to use the lazy initialization pattern with Rust 1.80

Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.

Yashodhan Joshi
Nov 18, 2024 â‹… 5 min read
View all posts

24 Replies to "Comparing Create React App vs. Next.js performance differences"

  1. One thing that I believe needs to be clarified is that Next.js takes advantage of isomorphic/universal rendering. When an app is loaded for the first time, it’s loaded via SSR. Afterwards, CSR kicks in, giving you the best of both worlds.

    1. Jason, your info is very important because if you use a Server Side Rendering only approach instead of the isomorphic rendering like Next.js, you will still end up with a faster loading time in the SSR page but with slower website rendering after the initial load.

  2. The linked Walmart Labs article is excellent but it’s important to remember it’s from 2017, and they call out synchronous SSR as a bottleneck with renderToString. This is no longer the case with React 16 and the enhancements that Fiber brought.

  3. Interesting that Gatsby is not included in this. With it’s client side re-hydration it’s pretty solid for building web apps as well as static sites.

    Recently built http://www.growable.io with Gatsby and the performance wins out of the box are crazy 🤯

    Any reason why it wasn’t included?

  4. Will, I did not include Gatsby because I believed it to be a static site generator. Static sites will be more performant, but this post was intended to cover applications that require dynamic data.

  5. Interesting, thank you for sharing! I have experience with CRA but am considering Next.js for a new project. I did leverage SSR with CRA though, so I’d be interested to know how CRA with SSR compares to Next.js. My instinct says since the architecture is similar then the performance should be, but then the SSR for CRA is more home-rolled so likely not as optimized. I realize that would be a more extensive benchmark to build out though.

  6. Matt, I suspect the performance difference would be negligible between CRA w/SSR and Next.js w/SSR. I personally prefer not to home-roll when there is a viable meta framework available like Next.js, but that choice is based more on developer ergonomics rather than performance.

  7. I have a question here.
    I’m already aware with the benefits of Nextjs on CRA. I migrated my website(https://m.truebil.com) from CRA to Nextjs. I got 80% improvement on FMP, FCP which also improve the lead conversion by 15%. This is awesome.
    But this is all for new user. It has negative impact on returning user because CRA works better for returning users. For the returning user drop in lead is 10%.

    CRA works better for returning user because all contents(js) are cached on client side so it get rendered faster whereas in SSR first call goes to server which is time consuming.

    How can I improve the performance of returning user?

  8. Let me ask you how the deployment looks like ? with CRA you just need a bucket , but if I understand next.js correctly you will need a nodejs server running, so much more expensive and resource intensive . Another thing is the next js page redoing the query on each request ? I think getinitial props don’t do it, but getserverprops does it, can you confirm the behaviour

  9. At the time this was written, these were deployed to Vercel (formerly Zeit). With server rendering, you do need a Node.js server though I recommend using Vercel or Netlify serverless options. It will keep your costs low and with Next.js you can now deploy hybrid apps where you only server render when you need to. Static pages can be deployed as static HTML, which can then be served by a CDN.

    getInitialProps will refetch on every request as long as you aren’t using the static export option. Use Next.js standard build/deploy and you’ll be able to choose between static/server rendering per page.

  10. It would have been nice to see a comparison between both a worst and best case scenario. Would a SPA not generally see better performance when navigating between different pages than a SSR website? I think SSR: good, CSR: bad is a gross oversimplification as there are pros and cons to both solutions.

  11. As another reader commented, Next.js uses CSR after the initial page load. The exercise in this article was purely focused on initial load but it is important to note that Next.js’s hybrid approach minimizes the trade-off since you don’t lose the benefits of CSR for subsequent page navigations.

  12. Sean Connolly is wrong when he says “don’t lose the benefits of CSR for subsequent page navigations”. You do lose some benefits of CSR because when you navigate to the new page. Next JS’s bundle splitting still requires you to make another trip to the Next JS server to load new Javascript code (code that has other dependencies, determined by the build process, than code on initial load page) when you navigate new page.

  13. Hey. Trying, thanks for clarifying that detail for others.

    It’s important to understand that route based code splitting is also encouraged in CRA apps so they would have the same hit in route changes. With Nextjs it is trivial to prefetch that bundle to eliminate the delay.

  14. Hi Sean,
    Even when you also have Route splitting in CRA. Both sides are not equal.
    As Vaibhav Kumar already mentioned, Next JS is bad for returning clients.

    The reason why? JS bundle CACHING.
    When configured correctly, the JS bundle will be cached. This means for returning clients, the next page of CRA will be loaded instantly at least with the skeleton. However, with Next, you always have to return to the server because … well.. the server… renders.

    This is especially true and unavoidable when the data is dynamic. Yes you can still hack into the code and make the data fetching happens on client and renders skeleton while the server… renders. But it makes the code utter hell and complicated.

    It is so disappointed to me that most people on the internet think Next is good. In my opinion, with prerender.io (they have free opensource for on premise setup), you don’t even need Next for SEO. The performance of Next may be a tiny bit better with initial page load but lose quickly for subsequent pages as well as returning clients (where JS bundle CACHING kicks in). So performance wise, Next is likely even a loser, no where near clear winner. On top of that, you have to setup your node server, wasting computing resource and cloud money, topped that with all the complications when using redux and CSS in JS. Next is bad conceptually in my opinion in everyway.

    PS: No flame war intended. I just want to clear things out for a lot of junior, middle+ developers (I met a lot) when they say Next is new technology and good without having a deeper understanding of how everything cliques. If I understand anything wrong, please correct me. I will be grateful of your correction. Regards.

  15. One suggestion:
    – Can you make the CRA renders the Skeleton (https://material-ui.com/components/skeleton/)?
    This will make the first useful content paint of CRA appears much quicker. This will show the true performance difference between CRA and Next JS in this first useful content paint category. Your current setup gives tremendous bias to Next JS.

    One admission:
    – After thinking about it, making Next show Skeleton instantly might not be very tricky as I thought. Please let us know how you would do that?

  16. By the way, there is a huge bias in your test setup.
    Your CRA bundle, css and html build was not served as STATIC assets from something such as Amazon Cloudfront.
    If you serve it from Cloudfront, the empty/skeleton html result will comes from somewhere very close to the user in Boulder CO. And you will have first contenful paint with the skeleton (instead of empty) almost instantaneously with Cloudfront edge servers. The Lighthouse score would have been totally different.

    Please publish our discussion. I don’t want to start a Next JS is bad article (flame war baiting accusation, you know) therefore I want to limit my opinion to comments. But at the same time, I want to point my junior devs to somewhere (such as this thread) to argument and discussion with you that explains why Next JS being faster than CRA is a myth. That way I don’t have to spend time explaining to them repeatedly. Thank you.

  17. Hi Trung,

    I understand the implications of bundle caching for returning users. But we need to emphasize the difference between displaying a skeleton vs displaying meaningful content. If you need to optimize the display of meaningful, dynamic data then a server render will still win.

    If you want to prioritize the display of a skeleton you can go with either CRA or Next, because with Next you can generate static pages in addition to serve rendered pages. I prefer the flexibility Next provides.

    If you want to provide your juniors with a helpful resource, I suggest you do some more research and write your own post.

  18. Hi Sean Connolly, I am a junior developer about React. I have read your meaningful article and I have also read your comment when reply other opinions about this. I see you prefer to use Next rather than CRA even though you will create a complex web app? is that right?

    I hope you can reply my question. I am sorry for my bad english language.
    Thank you before.

    1. Hi there! It’s been a while since this article was originally published. Next.js has come a long way since then and today I believe it’s a much simpler starting point than CRA is. Over time, many apps will grow in complexity and Next.js has enough flexibility to scale to those needs that might be difficult to foresee when the app is new. I can’t say the same for CRA as I think there are too many limits to its capabilities (personally I don’t think it was ever really intended to be a solution for long lived production apps).

      The complexity comments for Next.js are usually tied to its specific server rendering capabilities as you need to account for the reality that your code can run in different contexts, i.e. in the browser and on the server and there are constraints associated with that.

Leave a Reply