Optimizing Flutter Web App Performance, Speed, and SEO

Cross-platform frameworks like Flutter offer solutions but come with challenges in SEO and load times. We explore optimization techniques to enhance performance and SEO for web apps.

4 minutes

In today’s fast-paced digital landscape, modern websites now have to contend with performant and feature-rich mobile applications. Many businesses are turning to web applications to meet the demand for enhanced functionality and user-friendly interfaces. Cross-platform frameworks such as Flutter attempt to solve this problem while saving significant development time and cost as a single codebase can serve as a website, mobile application (iOS and Android), and even a desktop application.

However, web apps come with their own set of challenges. Unlike simple HTML landing pages, web apps are fully functional applications that must load completely before use. This poses particular challenges for SEO and initial load performance, as they are not inherently designed with these aspects in mind. This can significantly affect load times, which are critical for search engines like Google and Bing.

The speed and performance of your web application can make or break user engagement and business success. A single second delay in page response can result in a 7% reduction in conversions, which underscores the critical importance of optimizing your web app’s performance not just for user satisfaction but also for search engine ranking.

Despite these challenges, there are many tactics that we can employ to optimize web apps for Search Engine Optimization (SEO) purposes.

Creating a Benchmark

To identify bottlenecks in any web app, it’s essential to set an initial benchmark. For our testing, we used Google’s PageSpeed Insights, which employs Lighthouse and emulated hardware to provide consistent performance test results for both mobile and desktop platforms.

Key Scoring Metrics

  • First Contentful Paint (FCP): The time it takes for the first text or image to appear (lower is better).
  • Largest Contentful Paint (LCP): The time it takes for the largest text or image to appear (lower is better).
  • Total Blocking Time (TBT): The time between FCP and Time to Interactive (lower is better).
  • Cumulative Layout Shift (CLS): The amount that elements move within the viewport (lower is better).
  • Speed Index (SI): How quickly content is visually populated (lower is better).

These metrics are compiled by Google to determine the Performance score of a given site. Take a look at this Performance score breakdown for YouTube.com:

YouTube Desktop Performance score breakdown
YouTube Desktop Performance score breakdown.

With a clear understanding of how to benchmark a web app, the our next challenge is to introduce optimizations for quicker load times and improved user experience.

Package Size Optimization

Web app code can quickly balloon in size due to messy code or unused dependencies left in the production version. Unlike mobile apps, traditionally, all compiled JavaScript code must be transferred, parsed, compiled, and executed before anything can be displayed on the screen.

Deferral and Code Cleanup

Flutter’s deferring mechanism allows us to defer non-essential bits of the application, which are then compiled into separate JavaScript files. These files are loaded only when needed, significantly improving the initial load performance. By deferring parts of the app that aren’t immediately required, we ensure that the most critical elements are loaded first, enhancing the user experience and improving SEO metrics.

To defer a specific third-party dependency or our own first-party code, we can modify our imports as follows:

// defer the import of the package
import 'package:example/package.dart' deferred as package;

// and, only when required, load the library 
await package.loadLibrary();

This approach segments the main JavaScript file into multiple bundles, each loaded only when required by the application.

However, even after deferring all unnecessary initial code, the output may still result in large file sizes of a few Megabytes, impacting load times, especially on mobile devices. To further optimize performance, server-side compression techniques can be introduced.

Fortunately, several efficient compression algorithms are available for this purpose, including gzip and Brotli, which can be employed on most server types. To implement gzip compression globally for all JavaScript files on an NGINX server, we can add the following snippet to our nginx.conf or default.conf file:

http {
    gzip on;
    gzip_types application/javascript;
    ...
}

As an example, we managed to reduce the JavaScript file size for a client by one-third using deferral techniques and code cleanup practices. Coupled with server-side gzip compression, this approach reduced the transferred JavaScript file size by 76.37%, substantially improving the initial page render speed, particularly for users on mobile.

We chose gzip over Brotli in this scenario because gzip is supported out of the box on NGINX, allowing for straightforward upgrade paths and long-term support, while providing similar file size reduction as compared to Brotli for our specific use case.

Meta Tag Prerendering

While file size reductions help, web apps still face challenges with SEO. Initial loading times for web apps can affect SEO performance and link previews, as app-generated meta tags may not load in time. This leaves crawlers and link renderers with no useful information.

Server-Side Rendering of Meta Tags

We can address this by implementing server-side rendering of meta tags. The server inspects the requested URL, passes it through an API endpoint, and appends relevant meta tags directly to the HTML page before returning it to the client. This ensures all necessary information is present immediately, improving SEO scores and allowing link previews to work effectively.

For a particular client, we designed a modular URL and content structure which enabled us to generate relevant meta tags for any given URL on initial load. This allowed for better link previews and significant SEO score improvements on Google’s PageSpeed Insights.

Preloading and Preconnecting

To maximize loading efficiency, we can use the time spent loading and evaluating the web application’s compiled JavaScript code to preload large image assets and preconnect to frequently used resources. Including preload and preconnect tags in the HTML head element, we can then introduce a loading splash screen which utilizes the largest preloaded image, reduce FCP, LCP, SI, and CLS penalties.

Raw performance numbers are not all, however, and by using a predetermined header image URL or an API endpoint, we can precache and display the header image upon initial load, enhancing the user experience as well.

Methodology for improving image load times and performance scores with precaching
Methodology for improving image load times and performance scores with precaching

Moving Forward

Combining all of these techniques, we were able to increase a client’s PageSpeed Insight scores for their Flutter web application from

Client PageSpeed Insights performance score before improvements

to

Client PageSpeed Insights performance score after improvements

With scores increased across the board, beating those of YouTube, Discord, and even some traditional HTML websites, this is a tremendous win!

Further optimizations are possible. For example, Flutter’s recent support for WebAssembly (WASM) output offers potential for quicker loading times as WASM binaries do not require parsing and compiling at runtime like JavaScript. However, many third-party Flutter dependencies still lack WASM support, and the upgrade path can be complex. Continued research and optimization are needed to fully leverage these improvements.

Although many believe that SEO and traditional web performance are not synonymous with web apps, employing these optimization techniques can help bridge that gap. By focusing on aspects like performance, server-side rendering, and strategic preloading, we can move web app development closer to achieving both high functionality and strong SEO performance.

Remember, anything is possible with the right approach and continuous improvement!

Subscribe to Stay Up-to-Date!

Stay in the loop with everything you need to know about Software Development.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *