Flutter web has to download main.dart.js, the CanvasKit (or skwasm) runtime, fonts, and your assets before it can paint a single pixel. Depending on the size of those, that's easily 3 to 5 seconds of staring at a blank white page wondering if the site is broken.
You can fix it without touching any Dart code. Flutter mounts into <body>, so anything you put there shows immediately and disappears on its own once the engine takes over. Drop a logo in there, or better, show a real progress bar that reflects how far along the boot actually is.
Now make it actually move. Drop a custom web/flutter_bootstrap.js next to index.html. If the file exists, Flutter uses it instead of the auto-generated one. Hook into the loader stages:
{{flutter_js}}{{flutter_build_config}}const bar = document.querySelector('.progress-bar');const setProgress = (pct) => { bar.style.width = pct + '%'; };setProgress(20); // bootstrap running_flutter.loader.load({ onEntrypointLoaded: async function (engineInitializer) { setProgress(50); // main.dart.js downloaded const appRunner = await engineInitializer.initializeEngine(); setProgress(80); // engine ready await appRunner.runApp(); // Flutter has taken over the page, nothing else to do },});
These aren't fake percentages. Each one fires after a real milestone: the bootstrap script running, onEntrypointLoaded (main.dart.js parsed), initializeEngine resolving, and runApp mounting the app. A handful of discrete stages, not continuous progress, but enough to feel honest.
One thing to watch: everything here ships as plain HTML/CSS with the initial page request. Don't load a 2MB animated background, or you'll be solving one loading problem by creating another.