Home Blogs Optimizing React, Angular or Vue Single-Page Applications for Performance
Applications

Optimizing React, Angular or Vue Single-Page Applications for Performance

About The Author

Outline

In this post, we’ll look at how Vue, React, and Angular compare in terms of performance and what can be done to optimize eCommerce SPAs running on these frontend frameworks for the best user experience.

How does Angular, React and Vue compare in terms of performance

Running a fast site leads to bottom-line growth through better SEO ranking, more visitors, longer sessions, and, as a result, more revenue. Many eCommerce leaders who understand the role of speed have already shifted to headless commerce architecture, enabling the adoption of modern frontends, such as progressive web apps and SPAs. Lightweight SPA frontends are gaining popularity because they are a surefire way to solve various performance issues inherent to modern eCommerce platforms so that operators can deliver lightning-fast storefronts.

Well, that’s the theory. To verify these lofty claims, we performed a small in-house performance analysis. To this end, we tested nearly 2,000 popular eCommerce websites running on the leading frontend frameworks and assessed their performance based on Lighthouse 6 scores. The findings were surprising—the average Lighthouse score for the tested SPA frontends was only 24, with a median of 19 (out of 100)! Low as it sounds, this was still 26% higher than the average score for the leading 500 US internet retailers by revenue.

Vue.js sites were the fastest, averaging a score of 27 with a median of 20. Angular websites saw an average of 23; however, their performance scores were more dispersed, with a median of just 18. React websites were the slowest tested, with an average Lighthouse score of 22 and a median of 18. This was surprising, especially since the framework is used by some of the biggest players, including sites like PayPal, Grammarly, and Vimeo, to name a few.

The conclusion of the test was rather clear—while SPAs are thought to be faster than traditional websites, there is still room for improvement. Moreover, Google CrUX and other measurement tools don’t track the page transitions of Single-Page Applications (SPAs), misrepresenting them as being far slower than they are and penalizing their scores. We write more about this issue in another post on the blog.

 

The impact of start-up time and runtime performance on Lighthouse scores

The performance of apps is defined by two metrics: start-up time and runtime performance. The size of the code bundle primarily influences the former—i.e., the app code and the framework code combined. Runtime performance is contingent on the specific optimization features of the framework and the way it handles DOM manipulation and updating.

Bundle size

All three frameworks have similarly-sized, minimal code bundles. Although the framework’s bundle size impacts start-up time, the metric shouldn’t be the main focus when comparing the performance of Angular, React, and Vue.

More precisely speaking, Angular bundle size is only slightly larger than Vue and React bundle sizes, with Vue bundles being a bit smaller than React bundles. Also, it is worth noting is that the Angular dev team is steadily optimizing the size of their (source) code bundles.

See the chart below for the approximated numbers.

Angular, React, and Vue all offer great runtime performance, and each is equally fit to be the backbone for complex, revenue-generating websites with heavy traffic.

Lighthouse’s TTI and LCP metrics

Lighthouse is a great testing tool that returns valuable speed insights. It identifies possible performance issues and helps optimize a site’s various aspects. A lighthouse score is calculated based on a weighted average of multiple metrics (go here for a full rundown). Still, the Largest Contentful Paint (LCP), Time To Interactive (TTI), and Cumulative Layout Shift (CLS) are very likely the most important ones from the user’s perspective. TTI and LCP are directly connected with perceived load speed.

TTI is a good representation of the impact of a framework’s bundle size on the speed of the SPA, as the bundle needs to be evaluated entirely before a user can interact with the app. Sites with a long TTI will show various pieces of the site while loading but won’t allow users to interact with it, which may ultimately lead to frustration.

The LCP metric, on the other hand, measures how long it takes until the largest element of the page’s content is rendered on the screen.

Lighthouse vs. CruX real-life browsing data

It is worth noting that synthetic speed measurement tools (like Lighthouse) don’t tell the full story. Site speed is more about how the site “feels” when users browse through it. A Lighthouse performance score is a good reference point, but it’s somewhat arbitrary and hard to correlate to a real-world experience. For example, it’s hard to translate how much better a performance score of 60 would be, in terms of user experience, compared with a score of 50.

Synthetic tests also tend to simulate older devices and connections (e.g., Lighthouse simulates 3G connections), while in reality, most mobile users are on fast LTE or even 5G networks.

A site running on a specific framework may “feel” faster but lose to other sites regarding its raw performance score and vice versa. This is mainly due to specific tricks (e.g., lazy loading) that each framework employs to improve how fast the site “feels” to users.

In the next sections, we will review the opportunities each of these frameworks offers for improving website performance.

Angular

Angular extends the HTML code with new tags and attributes and interprets the attributes to perform data binding.

Due to its rich features, the working application may be much bigger (approximately 500KB) compared to Vue or React, which may slightly impact performance.

Angular’s MVC abstraction (source)

Here is a quick summary of the main benefits of Angular.

  • Code generation. Angular generates highly optimized code for JavaScript virtual machines, giving the benefits of hand-written code. HTML templates combined with JavaScript open the door for impossible optimizations in other frameworks, for example, React.
  • Code splitting. Thanks to Component Router, Angular apps load quickly, delivering automatic code-splitting. This way, users load the code required to render the view they request.
  • Real DOM. Angular uses real DOM; therefore, it’s best suited for single-page applications where content is only updated from time to time, not those that frequently change, such as most eCommerce sites. Manipulating the virtual DOM is much faster because nothing is drawn on the screen.

React

Created and developed by Facebook, React is one of the most popular open-source mobile application frameworks. It doesn’t provide a wide range of libraries; thus, its size is significantly smaller than that of Angular.

With single-direction data, React allows better control over the project—when designing an app, React developers can nest child components within higher-order parent components.

React offers some interesting features, including:

  • Virtual DOM: Nodes are re-rendered only as needed. React compares the new data with the original DOM and updates the View automatically. This enhances the performance of all-sizes applications that need regular content updates.
  • One-way data binding: React uses one-way data binding with Flux controls application architecture. ReactJS helps update the View for the user, and Flux controls the application workflow. Virtual DOM adds advantages as it compares the new data with the original DOM and updates the View automatically.
  • Support for bundling and tree-shaking: minimizes the end user’s resource load.
  • Server-side rendering (SSR) support: offering speed gains in specific implementations.

To a bigger extent than Angular and Vue, React utilizes certain techniques that make the page “feel” faster to end users. For example, the framework prioritizes user input over rendering content on the page.

Vue

Vue is fast and very small at just about 30KB (gzipped), which results in faster first loads. This makes it the smallest of all the three frameworks and significantly speeds up the performance of websites running on Vue.

Vue offers:

  • Server-side rendering (SSR)
  • Tree shaking
  • Bundling
  • Virtual DOM: changes within a project don’t affect the DOM properly. Modifying the real DOM is a resource-intensive task, so updates are first applied to the virtual DOM.

Check out this detailed benchmark report to compare start-up times, memory allocation, and the duration of specific operations across the leading JavaScript frameworks and libraries. Compared to React, Vue is slightly better in terms of memory allocation and start-up times, although React is a bit faster runtime-wise.

Angular and Vue use HTML templates combined with JavaScript. This gives them extra room for optimization React does not offer. For example, Vue tracks dependencies preventing unnecessary renders of child components.

Vue vs. React vs. Angular SPA optimization

We know that benchmarks and performance scores don’t tell the whole story. Website speed may vary depending on application size and your optimization efforts. Here are a few ideas to help optimize Vue, React, and Angular SPAs for speed.

1. Server-Side Rendering (SSR)

Overall, there are four key benefits of using SSR with SPA sites:

  • SSR allows you to quickly load a SPA template and display content to the user (although the user may not be able to interact with it immediately). Without SSR, users would stare at an empty screen, waiting for the content to load and render in the browser.
  • SSR reduces the load on the end user’s machine.
  • Since Google can now properly crawl SPA content, server-side rendering may not be as important for SEO as it used to be. But the benefit of using SSR is that many other search engines still don’t understand JavaScript and can’t crawl JavaScript-heavy sites properly.
  • Social networks often can’t properly display content shared from client-rendered SPA sites. For example, Facebook scraper only relies on the meta tags set by the server—and doesn’t work with client-side rendered meta tags. To better control how your SPA site looks when shared through Open Graph, SSR is a must.
  • AMP speeds up first loads on mobile devices but doesn’t allow you to use JavaScript. It’s impossible to render AMP from React on the client, it must be done on the server. However, even with SSR in place, there are a lot of hoops to jump through to convert a React app into a valid AMP app. Fortunately, some frontend frameworks, like React Storefront, can handle everything for you.

SSR works best for static sites, but eCommerce SPA websites are still cacheable—with the right infrastructure. With Layer0, the content is rendered on the fly server-side and then cached at the edge with our CDN-as-JavaScript. This way, large-scale database-driven websites, such as eCommerce SPAs with thousands if not millions of pages, personalization, real-time inventory, and more, can delight users with sub-second page loads from landing through checkout.

CDN-as-JavaScript service worker (called Layer0 Workers) intelligently fetches dynamic data from the edge before your visitor taps on a link and streams it into the browser, based on what they will most likely tap on.

Layer0 network and monitoring tools ensure that dynamic data is cached at least 95% of the time, shielding your database from the extra requests created by prefetching. This way, you can provide sub-second page loads, offering your visitors a seamless experience from landing through checkout.

Layer0 network and monitoring tools

Overall, regarding SSR capabilities and detailed documentation, Vue is superior to React, which needs third-party libraries (e.g.Next.js) to render pages server-side.

2. AMP

AMP creates better, faster experiences on the mobile web by simplifying the HTML and enforcing stringent limitations on CSS and JavaScript. These pages are then cached and pre-rendered on the Google server, which makes the transition to your app near-instantaneous.

The downside is it’s different from how you write a PWA/SPA and means a complete rewrite of the app unless you use a dedicated framework with built-in AMP support, such as React Storefront.

AMP pages have 500ms median page loads for traffic coming from Google’s SERP. These speeds are possible because Google servers prefetch and prerender AMP content to a user’s browser before clicking on the AMP page link. The average eCommerce site gets a large chunk of its traffic from Google search (both organic and paid), so these gains can have a massive impact.

Sites that use AMP also see reduced bounce rates, as users who may typically bounce while waiting for a page to load will now be met with a lightning-fast experience.

3. Code splitting

Your single-page application will grow over time as you continue to add features. But we know that every application has some features that are hardly ever used and unnecessarily slow down. You should implement code splitting to keep your app as fast as possible.

Code splitting involves creating separate bundles for each top-level component in your app. In the case of an eCommerce SPA, there will be separate bundles for the home page, product listings, and product description pages. This way, when a user arrives at your app via a link to a specific product, the browser doesn’t need to download and run the code for all of the previous pages, thus cutting the TTI and FID times.

With code splitting, the app can “lazy-load” other page components in the background and use them if the user decides to navigate them. This saves bandwidth and decreases first input delay or FID (note FID is often approximated by time to interactive or TTI metric), improving your website speed and search engine ranking.

4. Lazy loading

Vue, React and Angular all support lazy loading, which, in combination with SSR, can provide significant speed improvements.

Lazy loading presents a challenge when implementing SSR. The server should know which components were used to render the outgoing HTML and send the code for those components alongside the HTML. Otherwise, the app will need to mount in the browser and run two render cycles before it’s ready to be interactive, which will increase FID (and TTI), which may lead to content flash or jank.

Lazy loading and SSR are connected. The library you choose for lazy loading (e.g., React Loadable) will affect how you generate the final HTML sent back in the response. To capture the bundles that need to be loaded to hydrate the HTML that was rendered on the server, you’ll need to add <loadable.capture></loadable.capture> to your SSR code, then use React Loadable’s getBundles function to figure out which <script></script> tags need to be added to the document body.

Because lazy load client hints are not yet supported globally by all browsers, there are a couple of workarounds to implement lazy loading seamlessly.

Solution #1

Instead of rendering the images server-side, you can let them populate client-side when the app mounts.

Solution #2

Only use lazy loading for images “below the fold,” i.e., those you know will not be visible immediately after loading. This is challenging because the fold line may move up and down depending on the user’s device and display size. However, some heuristics help. For example, on an eCommerce category page, you might turn off lazy loading for the first set of product images (they are likely to be “above the fold)”. And for items you know will consistently be above the fold (e.g., headers, company logos, cart icons), you shouldn’t enable lazy load anyway and can always render them server-side.

Solution #3

Detecting the user agent can help to serve an appropriate version of the SSR-rendered page. User-agent detection is not generally recommended for implementing progressive enhancement, but it does the trick as a temporary workaround while browsers catch up and implement client hints.

This solution requires that you normalize your cache keys appropriately; otherwise, you could fragment your cache significantly.

5. Modern CDN

Optimizing your SPA for speed and using a good CDN on top of that will boost your site, but it is not enough to achieve sub-second speeds. This is because most traditional CDNs are only good at caching static files, but overall they don’t cope so well with JSON/HTML/SSR data—whereas that’s exactly what eCommerce SPA sites are made of. Making these sites faster requires several web technologies working efficiently in unison. Unlike other CDNs, Layer0 application-aware CDN works well with eCommerce SPAs. It optimizes cache hit ratios to unheard-of levels and brings intelligence to the edge. This helps business owners decipher trends and opportunities for optimization by categorizing similar pages as such (for example, PDP, PLP, and Cart) instead of just displaying an endless list of URLs. This lets you take action and see a difference in website load times.

But most importantly, CDN-as-JavaScript uses advanced predictive prefetching techniques to stream cached data from the edge into users’ browsers before they tap on anything. This keeps websites 5 seconds ahead of shoppers’ taps, allowing them to delight users with an instant browsing experience.

6. Mobile tooling

Angular is great for building mobile apps. You can use the framework to build a web application that runs on any device or develop iOS and Android native apps by combining Angular with NativeScrip. This allows you to reuse Angular concepts such as data binding, dependency injection, services, and routing.

React Native is considered the king of cross-platform development. It allows developers to reuse up to 99% of JavaScript code between Android and iOS with React-like components. This means developers can create 100% native widgets that control their own style. The framework handles the View layer as a pure state output, which makes it easy to create companion apps for iOS/Android with a native look and performance.

Although Vue lags behind React, it still offers several valuable solutions for mobile development. For example, NativeScript allows you to write Vue applications and compile them to native iOS/Android apps.

Then comes Vue Native. The framework combines the advantages of Vue and RN ecosystems, declarative rendering, two-way binding, and a set of basic components for creating a cross-platform native app.

SPAs are faster but still have speed issues

The original allure of a single-page application is that subsequent pages don’t reload during navigation, leading to a faster, frictionless browsing experience. But modern SPA frontends are only part of the site speed solution, and a couple of problems still need to be addressed:

  • Synthetic speed benchmarks and tests don’t necessarily tell the whole story. The speed of these frameworks may vary depending on application size and your optimization efforts.
  • While various cutting-edge frontend technologies, including progressive web apps, SPAs, and AMP, can dramatically enhance the customer experience, website speed is a full-stack problem. It spans the browser, edge, and server. This is why a full-stack solution is needed to speed up any website, SPA, and multi-page application.
  • All these technologies can improve speeds but work best when applied in unison. Making all these technologies work together is a complex task that in-house teams may be unable to handle (for example, it requires creating a Node.js layer).

Layer0: making the Web instant and simple

Layer0 is a complete solution for making eCommerce websites fast and easier to develop. It combines advanced optimization techniques to speed up large-scale, database-driven websites, such as eCommerce SPAs, along with powerful tools that give devs back a day a week by putting the code in the center of their workflows. Layer0 essentially brings Jamstack to large eCommerce websites.

Instant: By combining modern frontends with a CDN-as-JavaScript with a 95% cache hit ratio for dynamic content at the edge and a Node.js backend-for-frontend, Layer0 helps complex websites optimize for speed across the stack. It is the only platform guaranteeing median sub-second Largest Content Paint (LCP) times for large-scale eCommerce websites.

Simple: Layer0 (now Edgio) is your all-in-one platform to develop, deploy, preview, experiment on, monitor, and run the frontend that lets you:

  • Utilize Jamstack for eCommerce via both pre and just-in-time rendering
  • Enable zero latency networking via prefetching of data from your product catalog APIs
  • Configure edge natively in your app (CDN-as-JavaScript)
  • Run edge rules locally and in pre-prod
  • Create preview URLs from GitHub, GitLab, or Bitbucket with every new branch and push
  • Run splits at the edge for performant A/B tests, canary deploys, and personalization
  • Serverless JavaScript that is much easier and more reliable than AWS Lambda

Conclusion

Running a faster site is not just a fancy gimmick. At the end of the day, you are not only trying to wow your users but also attempting to please the largest search engine in the world. Since Google’s ranking will soon be determined, in part, by page speed, it cannot be taken lightly. A fast site means boosts your SEO rankings and conversions, which, in turn, generate more revenue.

While much can be said about the performance of each framework, there are three points to remember:

  1. Real-world differences in framework performance may be minuscule. The performance of SPA sites depends on so many variables that it’s impossible to compare these frameworks side-by-side in a meaningful way.
  2. Whether you’re on Angular, Vue, or React, there is still much space for improvement.

Making SPAs faster requires a combination of advanced web technologies working in unison, and your in-house teams may not be able to implement them efficiently. Thankfully a few forward-thinking vendors, including Layer0, have done the heavy lifting for you.

Layer0 combines server-side rendering with advanced predictive prefetching and pre-caching at the edge. Because dynamic data is cached at least 95% of the time, your database is protected from the extra requests created by prefetching. Layer0 CDN-as-JavaScript service worker intelligently fetches your dynamic pages before your visitor taps on a link. This way, you can provide sub-second page loads on single-page applications, offering your visitors a seamless experience from landing through checkout.