'Expo build:web builds huge bundle and slow website with bad performance

The bundle size produced by expo build:web is huge at average 3mb.

I completed steps at https://docs.expo.io/guides/web-performance/. My app has no images so no real issue to optimise them. Other suggested improvements changed very little.

I used the bundle analyser and I have no installed modules of any significant size to cause the 3mb bundle size.

When I run build, I get:

entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (48.8 KiB). This can impact web performance.
Entrypoints:
  app (3.2 MiB)
      static/js/runtime~app.aaee9ccd.js
      static/js/2.a5f54fa3.chunk.js
      static/js/app.98ae2f23.chunk.js

The result of this is a webpage which peforms extremely poorly.

If I run google “lightspeed” (pagespeed insights) on the built result in browser, I get extremely poor ratings for initial page load.

I am thinking a potential way to solve, is branch off, then expo eject, then remove all unecessary npm modules to reduce bundle size.

I’ve also added lazy load on some components without much improvement.

Are there any other suggestions you might have?

Also attached are the google lightspeed test results.

Lightspeed Lightspeed 2



Solution 1:[1]

There are some ways to reduce expo web-build size. (Only for website)
(1) Use 3rd Party CDN instead of Node Package
(2) Use React Lazy Component
(3) Expo Sharp Cli to reduce size of Assets
(4) Use 3rd Party CSS instead of React Native StyleSheet
(5) Use default imports instead of * imports
(6) Write less codes as possible

3rd Party CDN

I have installed firebase to use firebase as backend. Instead of installing it with npm install --save firebase, I can use

<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-<service-name>.js"></script>

where service-name is 'firebase', 'analytics', etc.
Note. Currently Only version 8 is available for CDN.

Lazy Imports

Mostly I use all of my screens with Lazy. I have react-navigation for navigation. I have 'Home' Screen which exports with default. (Lazy import must always use default).

const LazyHome = React.lazy(()=> import("../screens/Home"));
const Home = ()=> (
<Suspense fallback={<div>Loading...</div>}>
<LazyHome/>
</Suspense>

You can read more in Official React Documents.

Expo Sharp CLI

It is easy to use. Just install it globally.

3rd Party CSS

Instead of

<Text style={style.header}>Header</Text>

You can use

<div className="h5 fw-bold">Header</div>

by adding bootstraps CDN in of index.html.

<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

Of course, you can use any css CDN you want.

Default Imports

Instead of

import * as Com from Components;

Use

import {Something} from Components;

But better is always default imports.

Write Less Codes

Well, this is not much important. But this affects only a bit of size. Instead of

const arr1 = [1,2,3,4,5]
const arr2 = [6,7,8,9]
const arr3 = arr1.concat(arr2)

Use

const arr3 = [...arr1,...arr2]

Instead of

let v;
if (something === true) {
  v = something;
} else {
  v = other;
}

Use

const v = something || other;

I can't tell all short hands syntaxes because I don't know all of them. When expo builds, they excludes 'Comments'. So, don't worry about Comments.

Where is expo's index.html File?

You can create one by expo customize:web. You will get 4 choices. Choose wisely.

Solution 2:[2]

Some things that may help:

  • Upgrade Expo to the latest version. Occasionally newer versions include bundle size improvements. I'm using Expo v44 + RN 0.64.3 and my bundle is only 1MB.

  • You can use Server-Side Rendering (SSR) to improve the initial page load experience. For example, try integrating with Next.js.

  • Enable code splitting and lazy loading and other Webpack optimizations specifically for web. See ?? How to code split with Expo web.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mircea Nistor
Solution 2