A web app built with flutter has a very large bundle size and can take a long time to load. In my use-case this is not really a problem, users won't bounce. But I'd like to avoid them staring at a white screen for something like 5-10 seconds, without any feedback.
How can I display an HTML/CSS based loading spinner until my flutter web app is loaded?
The web app is embedded into web/index.html
. I've already included a small Javascript snippet that asks users for confirmation before reloading the page. This is executed properly.
Here I've found a nice self-container html and css spinner: /
If I add the spinner to an empty html template, it works fine.
But if I add it to the body of web/index.html
it's not visible on the screen.
When using "inspect element" to look at the DOM, I can see that the spinner is loaded, but covered by the flutter canvaskit renderer.
It seems to me that flutter sets up the div for this renderer almost instantly at page load, and then takes a long time to load the remaining ressources.
Is it possible to have a loading spinner that is displayed until flutter has finished all its preparations?
A web app built with flutter has a very large bundle size and can take a long time to load. In my use-case this is not really a problem, users won't bounce. But I'd like to avoid them staring at a white screen for something like 5-10 seconds, without any feedback.
How can I display an HTML/CSS based loading spinner until my flutter web app is loaded?
The web app is embedded into web/index.html
. I've already included a small Javascript snippet that asks users for confirmation before reloading the page. This is executed properly.
Here I've found a nice self-container html and css spinner: https://projects.lukehaas.me/css-loaders/
If I add the spinner to an empty html template, it works fine.
But if I add it to the body of web/index.html
it's not visible on the screen.
When using "inspect element" to look at the DOM, I can see that the spinner is loaded, but covered by the flutter canvaskit renderer.
It seems to me that flutter sets up the div for this renderer almost instantly at page load, and then takes a long time to load the remaining ressources.
Is it possible to have a loading spinner that is displayed until flutter has finished all its preparations?
Share Improve this question asked Mar 8, 2021 at 18:09 lhklhk 30.3k36 gold badges137 silver badges220 bronze badges2 Answers
Reset to default 10This tutorial worked well for me: https://medium./flutter-munity/adding-a-splash-screen-to-flutter-web-7930e5e44bd
Simply create your css file, here's my styles.css
inside the web/
folder:
.loader, .loader:after {
border-radius: 50%;
width: 10em;
height: 10em;
}
.loader {
margin: 60px auto;
font-size: 10px;
position: relative;
text-indent: -9999em;
border-top: 1.1em solid rgba(0, 217, 255, 0.2);
border-right: 1.1em solid rgba(0, 217, 255, 0.2);
border-bottom: 1.1em solid rgba(0, 217, 255, 0.2);
border-left: 1.1em solid #00d9ff;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation: load8 1.1s infinite linear;
animation: load8 1.1s infinite linear;
}
@-webkit-keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
Then import your css inside the <head>
of your web/index.html
:
<head>
<!--
iOS meta tags & icons, etc...
-->
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
And finish by adding your spinner in the <body>
(it should be the first line of the body):
<body>
<div class="loader">Loading...</div>
<!-- Register the service worker -->
</body>
Screenshot
As of Flutter 3.0, Flutter provides a new lifecycle API for more control and flexibility.
Minimal example show progress:
<html>
<head>
<!-- ... -->
<script src="flutter.js" defer></script>
</head>
<body>
<div id="loading"></div>
<script>
window.addEventListener('load', function(ev) {
var loading = document.querySelector('#loading');
loading.textContent = "Loading entrypoint...";
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
loading.textContent = "Initializing engine...";
let appRunner = await engineInitializer.initializeEngine();
loading.textContent = "Running app...";
await appRunner.runApp();
}
});
});
</script>
</body>
</html>
You can visit https://docs.flutter.dev/development/platform-integration/web/initialization for more info and example codes.