Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Test Run

Traditional (ms)

Guest/Module (ms)

1

9133

6558

2

5582

3308

3

5510

3300

4

5610

3354

5

5634

3342

6

5671

3284

7

5693

3322

8

5640

3297

9

5623

3347

10

5580

3376

Average

5967.6

3648.8

This improvement is because we’re bundling less stuff in the guest/module architecture. If the MFE retains its index page which loads core-js, regenerator-runtime, and the header/footer, the build time is actually slightly higher on average.

Production Builds

Test Run

Traditional (ms)

Guest/Module (ms)

1

14896

10935

2

14982

10415

3

14844

10362

4

14840

10741

5

14776

10320

6

15003

10449

7

15161

10308

8

15170

10182

9

14982

10456

10

15309

10343

Average

14996.3

10451.1

Similar to the development build times, we’re bundling less actual code, so can expect there’s less work to do.

Production Bundle Sizes

Traditional Build

File

Size

Notes

440b1fd39e91e51e7522b7475338e338.png

526

An image I can’t find the source of - maybe a header or footer?

588.ccafd157cd20348f5d12.js

1794751179475

Dependencies (with Treeshaking)

95ec738c0b7faac5b5c9126794446bbd.svg

342

User menu icon

app.2733c7b2743ced7571ec.css

510993

Our massive stylesheet

app.2733c7b2743ced7571ec.js

1279

Our application code

index.html

31299

Big because it includes New Relic script.

runtime.e844be7d2206edc6dff5.js

2070

Webpack overhead

Total: 1,725,984 bytes

Guest/Module Build

File

Size

Notes

272.9f559385b83edb423687.js

66629

Module federation runtime

440b1fd39e91e51e7522b7475338e338.png

526

Same blank image… unsure why this is here.

446.88baa1ec0097e5a731bb.css

1

Presumably a stub for paragon’s stylesheet somehow, since we’re not importing it.

446.88baa1ec0097e5a731bb.js

929360

Paragon

483.f8bdb2bc9f890dc5a6d3.js

123479

react-dom - singleton, so impossible to use

810.39346add3075df3c2e86.js

7123

react - singleton, so impossible to use

826.48c8a2cae4305c5e8390.js

914

prop-types

95ec738c0b7faac5b5c9126794446bbd.svg

342

A “user” icon. Unclear why this has been bundled.

__federation_expose_GuestPage.74bf4d7962b592080a4d.css

115

Our module CSS!

__federation_expose_GuestPage.74bf4d7962b592080a4d.js

2240

Our module JS!

app.c2789d2465bb34d2a8e5.js

168

Unused

guest_partial.1a68511e4abda6f1aea1.js

666

Overhead

index.html

31525

Unused as a module

remoteEntry.js

75855

Manifest

runtime.3e9d4ef61501a655f753.js

7147

Overhead

(thumbs down) Worst case bundle size: 1,167,317 bytes

The worst case scenario is how many bytes we’d have to load if our host application didn’t have a compatible shared dependency version for any of our dependencies (like Paragon).

The above bundle size number won’t make sense with the sizes in the above table. While running this test, I realized that because my MFE didn’t use our other shared dependencies, they weren’t included in the bundle. Rather than start over, I went back to the Shared Dependencies page, counted up the total size of all the dependencies that we would have to load if our host didn’t have a compatible copy of them, and added that to the base size of our best case scenario. That number was 1,081,960, and includes @openedx/paragon, classnames, prop-types, react-redux, react-router, react-router-dom, and redux. React, react-dom, and @edx/frontend-platform don't count because they are singletons and can’t be loaded more than once.

✨ Best case bundle size: 78,210 bytes

In the best case scenario, we load our GuestPage JS and CSS and the remoteEntry.js file. Remote entry is the size it is because of how many shared dependencies we have - it needs to act as a manifest for all the other files we might need to load.

Tip

In our worst case scenario, our MFE is now 67.6% of the size of a traditional MFE.

In our best case scenario, our MFE is now 4.5% of the size of a traditional MFE.

As the application code of an MFE increases these numbers will shift, but they show the effect of using Shared Dependencies.