authgear / authgear-server

Open source alternative to Auth0 / Firebase Auth
https://www.authgear.com
Apache License 2.0
81 stars 37 forks source link

Code splitting #2058

Closed louischan-oursky closed 2 years ago

louischan-oursky commented 2 years ago

Goals

Idea

louischan-oursky commented 2 years ago

Example of including classic script and CSS

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="npm:intl-tel-input/build/css/intlTelInput.css">
    <link rel="stylesheet" href="npm:@tabler/icons/iconfont/tabler-icons.min.css">
    <script src="npm:intl-tel-input/build/js/intlTelInput.js"></script>
    <script src="npm:intl-tel-input/build/js/utils.js"></script>
    <script type="module" src="./pageA.ts"></script>
</head>
</html>
louischan-oursky commented 2 years ago

Problems we have encountered

Parcel by default use entrypoint filename to name bundles

Since we now have code splitting, we have multiple bundles. Having every bundle sharing the same name index makes debugging harder. We solve this by writing our own Namer plugin.

Parcel requires either import() or multiple page to enable code splitting

Our solution is to create a dummy page that refers a dummy script. The dummy script contains import() calls to force code splitting on third party modules

<!DOCTYPE html>
<html>
  <head>
    <script type="module" src="./dummy.ts"></script>
  </head>
</html>
import("library-a");
import("library-b");
$ parcel build ./src/*.html

FOUC after code splitting

Our color scheme is class-based so it requires JavaScript to work. The color scheme JavaScript was initially bundled together with other non-rendering essential code. It runs only after every script has been loaded. However, there is a gap between all blocking CSS have been loaded and all deferred scripts have been fetched. Once blocking CSS have been loaded, the page renders immediately. At that time, the color scheme JavaScript did not kick in yet, thus the page is rendered in light. After all deferred scripts have been executed, the page is rendered in dark. This light to dark change is the FOUC. We solve this by extracting the color scheme JavaScript from the main bundle, making it a blocking classic script. So it is executed BEFORE the page is rendered.