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 do 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 made the shift 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 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 actually 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 the two metrics: start-up time and runtime performance. The former is primarily influenced by the size of the code bundle—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.
All three frameworks have similarly-sized, minimalcode bundles. Although the framework’s bundle size has an impact on 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 which returns valuable speed insights. It identifies possible performance issues and helps to optimize various aspects of a site. A lighthouse score is a calculated based on a weighted average of multiple metics (go here for a full rundown), but 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 just yet, 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
Synthetic tests also tend to simulate older devices and connections (e.g. Lighthouse simulates 3G connections) while in reality most mobile users on fast LTE or even 5G networks.
A site running on a specific framework may “feel” faster, but may still lose to other sites in terms of 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 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 in size (approximately 500KB) compared to Vue or React, which may slightly impact performance.
Here is a quick summary of the main benefits of Angular.
- Code splitting. Thanks to Component Router, Angular apps load quickly, delivering automatic code-splitting. This way, users load 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.
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, and 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 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 an application architecture called Flux controls. 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 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.
React, to a bigger extent than Angular and Vue, utilizes certain techniques which make the page “feel” faster to end users. For example, the framework prioritizes user input over rendering content on the page.
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.
- Server-side rendering (SSR)
- Tree shaking
- 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.
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 immediately interact with it). Without SSR, users would stare at an empty screen, waiting for the content to load and finally render in the browser.
- SSR reduces the load on the end user’s machine.
- 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.
The XDN’s 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.
Overall, in terms of SSR capabilities and detailed documentation for it, Vue is superior to React, which needs third-party libraries (e.g.Next.js) to render pages server-side.
The downside is it’s totally different from the way you write a PWA/SPA and basically 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 they click on the link to the AMP page. 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 it down. To keep your app as fast as possible, you should implement code splitting.
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, so 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 other 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 to them. This saves bandwidth and decreases first input delay or FID (note FID is often approximated by time to interactive or TTI metric), which improves both your website speed and search engine ranking.
4. Lazy loading
Vue, React and Angular all provide support for 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 the way you generate the final HTML that’s sent back in the response. To capture the bundles that need to be loaded in order to hydrate the HTML that was rendered on the server, you’ll need to add <Loadable.Capture> to your SSR code, then use React Loadable’s getBundles function to figure out which <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.
Instead of rendering the images server-side you can let them populate client-side when the app mounts.
Only use lazy loading for images “below the fold,” i.e. those that 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, there are some heuristics which 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.
Detecting the user agent can help to serve an appropriate version of the SSR-rendered page. User agent detection is not normally 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 give your site a boost, 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 a number of web technologies working efficiently in unison.
Unlike other CDNs, Moovweb’s application-aware CDN works really 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.
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.
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 actually a full-stack problem. It spans the browser, edge, and server. This is why a full stack solution is needed to truly speed up any website, SPA as well as multi-page applications.
- All these technologies can improve speeds, but work best when applied in unison. Making all these technologies work together is a complex task which in-house teams may simply not be able to handle (for example it requires creating a Node.js layer).
Moovweb XDN: making the Web instant and simple
Moovweb XDN is a complete solution for making eCommerce websites really fast and easier to develop for. 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. The XDN essentially brings Jamstack to large eCommerce websites.
Simple: Moovweb XDN is your all-in-one platform to develop, deploy, preview, experiment on, monitor, and run your 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
- 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
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—you're 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 to your SEO rankings and conversions which, in turn, generate more revenue.
While much can be said about the performance each framework, there are three points to remember:
- Real-world differences in framework performance may, in fact, be miniscule. Performance of SPA sites depends on so many variables that it’s really impossible to compare these frameworks side-by-side in a meaningful way.
- 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 efficiently implement them on their own.Thankfully a few forward-thinking vendors, including Moovweb XDN, have done the heavy lifting for you.