跳转到主要内容

"If we really want to make our website faster, we should just rewrite it in Next.js."

I think you'd be hard pressed to find a tech startup anywhere without at least one developer who is constantly saying this.

But is it actually true?

I certainly had no reason to doubt it.

As someone who had just done the big upgrade from AngularJS to Angular, I was happy that all those months of work had resulted in a massively improved PageSpeed Insights performance score for both our landing page and our content pages. Before the upgrade the scores for these pages were typically in the mid 20s, whereas now the scores for the content pages are often into the low 90s, and the logged out landing page is even faster.[1]

At the same time, I was wondering if maybe I shouldn't be having some buyers remorse; after all, how much faster could our site have been had I rewritten it using Next.js instead?

Had you asked me, my guess at the time, based on purely circumstantial evidence, would have been 30 - 40%.

Why?

I know of multiple teams who have switched from Angular to Next.js, specifically citing the performance benefits. And clearly it wouldn't be worth doing so if the advantage were only 5 or 10%. Further, the First Contentful Paint of our own site on mobile is currently around 2.0 seconds, and be in the green you're supposed to be under 1.2 seconds. So surely SSR must be the best way to actually get there, right?

Right?

Not to mention that if you Google for angular performance, most of the top results are articles about how React is faster.

Either way it was kind of a moot point because I'd already done the work, and we weren't going to be rewriting the site anytime soon. But I was still curious. So I did the logical thing: I went to the Next.js website, looked at some of the logos of the companies using the framework, and started typing their domains into PageSpeed Insights.

TikTok got a 23. IGNHulu, and Netflix were in the upper teens. And the fastest site I tried that day was Twitch, which got in the mid 50s.

These results were... surprising.

Were these sites slow because they were big commercial sites with lots of marketing and analytics scripts, or was there something else going on? And, similarly, how did this compare with Angular?

After a few weeks of mulling over these questions, I suddenly remembered that PageSpeed Insights had an API. And in addition to the Next.js showcase, there was also the Made With Angular site. So I scraped a list of every site on each of these pages, and wrote a script.

Here were the results:

Framework Average Performance Score Average First Contentful Paint (s) Average Time To Interactive (s)
Angular w/o SSR 37.4 4.7 13.5
Angular w/ SSR 37.5 3.1 17.1
Next.js 34.8 3.7 19.3

See also: full data and code.

If I were purely a frontend developer then maybe this data wouldn't have been as surprising, but as a fullstack developer, it was somewhat shocking.

Some observations:

  • The average and median performance scores for both frameworks were very similar. Angular had a slight edge in both cases, but not enough to be meaningful.
  • There is a huge range of performance scores within each framework. For Next.js, the range was 1 - 87. For Angular, the range was 3 - 95.

It's very clear from this data that choice of framework is not the primary driver of site performance; just manually looking at the source code for some of these sites, it's clear that it's things like unnecessary dependencies, outdated dependencies, sites running development mode in production, etc. (Several of these sites were still running Angular v4 or v5 in production!)

This observation is also reflected in my own migration path. For context, migrating from AngularJS to Angular has four main phases:

  1. Replacing Bower with NPM, and replacing Grunt with Webpack.
  2. Converting AngularJS controllers and directives into AngularJS components. And replacing template code injected via ng-include with components.
  3. Porting AngularJS components to Angular components, and going from running AngularJS to running Angular.
  4. Making additional optimizations that are now possible thanks to Angular, like deferring JS and CSS that isn't needed in the initial bundle.

Of these four steps, the only one that did not result in a substantial improvement in performance was step 3, actually replacing AngularJS with Angular.

That said, when it comes to performance, even though the average and median performance scores are very similar, the edge here goes to Angular.

Why?

If we buy into the idea that the framework itself isn't the primary factor behind the average performance score for each framework, which the data supports, then really it makes the most sense to consider only the fastest sites. The reason is that in either framework it's likely possible to get up to a 95 or so on a real-world, medium- or large-sized site. So the question then is how difficult is it to actually get there? And the best way to answer this, at least that I can think of, is just by looking at what percentage of sites do actually get there, or at least close.

The results here are super interesting:

This graph was generated by taking the raw scores for each framework, and then calculating their respective performance scores at each percentile. So e.g. for Angular, the fastest site gets a 95, the 95th percentile site gets a 77.75, the 90th percentile site gets a 71, etc. What you can see is that the scores at each percentile are basically identical for sites at the 70th perentile and slower. But above the 70th percentile, Angular sites have a clear advantage.[2][3]

Another way to think about the same trend is that, in this data set, 12% of Angular sites had performance scores over 70, as compared with only 5% of Next.js sites. It's not clear why this is, and it may well be that a different data set would yield a different distribution curve.

If I were seriously considering spending eighteen months to rewrite our frontend then maybe I'd pay for a list of the 100k sites with the most traffic to see if the trend is still the same, but as it stands I'm more than happy to let anyone else who is interested see how tweaking the methodology changes (or doesn't change!) the outcome.

But based on the current data, I see no reason to think that migrating from Angular to Next.js will deliver any performance benefits, let alone benefits substantial enough to justify such a massive project. In fact, it may be worth taking seriously the idea that even if it's possible for apps built with either Angular or Next.js to achieve top performance scores, it may actually be more time consuming (read: expensive) to do this with Next.js. At the very least it's an idea worthy of future exploration.

Of course there's more to performance than just the overall performance score:

  • Angular had almost the identical performance scores with and without SSR.
  • Angular with SSR and Next.js both had significantly faster FCP scores than Angular without SSR, but significantly slower TTI scores.

What the data really shows here is that pre-rendering is a lateral move — you're gaining FCP at the expense of TTI.

That said, most major social platforms, like Twitter and Facebook, currently require sites to be pre-rendered in order to generate dynamic preview cards, so if Next.js makes this easier then that would be an advantage for Next.js.

The absurd thing here is that FWD:Everyone is apparently faster than every site in both the Angular and Next.js showcases. And it really is absurd, given that:

  • FWD:Everyone isn't a small site: it's a social network with 26 routes and a dozen or so modals, each of which is fully styled for desktop, tablet, and mobile.
  • While I like to think of myself as generally competent at writing frontend code, it's far from an area of expertise, so there are likely more optimizations that could be done if I had a more specialized skill set.
  • There are several more possible performance improvements that I know of and that are within my skill set to execute, but that I just haven't gotten around to doing yet.

Obviously the fact that I haven't junked up our pages with tons of marketing trackers like many of the larger and more commercial sites is a huge advantage, but still, you'd think there would be at least some other sites with better overall scores. After all these aren't just any Angular or Next.js sites, they're the ones that the proponents of those frameworks have specifically chosen because they ostensibly reflect well on those technologies.

Even though the average performance of websites using each of these frameworks is similar, overall this is a win for Angular; over the last couple years countless people have been promoting the idea that the way to fix slow Angular sites is to rewrite them in Next.js, and the data very clearly does not support this. In our own case, improving our speed by switching to Next.js would require us to be significantly faster than every site in the Next.js showcase. Maybe this is possible, but absent further information this doesn't seem like a great bet.

And if I did have to bet, my best guess is that I'd get more mileage out of spending three months getting rid of bootstrap than I would by spending eighteen months rewriting our site in React.

What's more, the upcoming performance improvements on the Angular roadmap actually look pretty good. Angular without Zone.js and with RxJS 8 should mean substantially smaller production bundle sizes. And upcoming improvements to Angular Universal should make implementing SSR even easier.

For me personally, I see a solid roadmap for getting our site to go from often being in the low 90s to consistently being in the mid 90s, should that become worth doing. But then again, phones are getting faster every year, so today's 93 might already be tomorrow's 100 anyway.

Regardless, on the basis of performance both frameworks are likely good enough. Startups should instead be choosing their frontend framework based on total cost of ownership, development speed, and ease of hiring. And once you've made your decision, don't second-guess yourself; the framework is not your limiting factor.

[1] During this process I also made other performance improvements like replacing Moment.js with Day.js, upgrading from Bootstrap 4 to Bootstrap 5, dropping jQuery, making the JS and CSS more DRY, and deleting tons of unused JS and CSS. Some of these required first upgrading from AngularJS to Angular, others did not.
[2] Even if you discount the fastest Angular site in this dataset, which is little more than a Hello World app.
[3] The Angular series on this graph includes both sites using and not using SSR, since SSR seems to have no affect on performance scores. And in fact if you make the same graph, but excluding Angular sites using SSR, the graph looks nearly identical — if anything, the gap between Angular and Next.js at and above the 70th percentile is even more pronounced.