Guides · · Maxwell Prehoda
13 Website Loading Screen Examples, and When a Preloader Hurts More Than It Helps
A full-page loading screen is worth it in two cases: the page genuinely cannot show anything useful until a big download finishes (a WebGL scene, a browser game, a Flutter or Unity build), or the intro is part of the brand experience and plays only once. Everywhere else, a preloader that covers the page makes the site feel slower and pushes back the moment Google measures as your Largest Contentful Paint.
So this list mixes both sides: studio preloaders worth stealing from, the engine hooks that give you a real progress number, and the examples that show when to drop the loading screen entirely. Every third-party entry was checked against its docs, repository or case study in November 2026. Most entries play a live, copyable CSS demo from our Loaders directory, our own take on the pattern. For small in-component spinners and dots, see loading animation examples.
1. Slack's loading messages, and why Slack retired them: Best for deciding whether you need a loading screen at all
Platform: Slack desktop and web app (retired July 2019)
Slack's startup screen used to show a short line of text while the app loaded, and Slack treated those lines as a feature. Its own changelog lists "Helpful loading messages from Slack" in November 2017 and a limited edition Brené Brown loading message collection in June 2017.
Then, in July 2019, the changelog entry reads: no more loading messages, because Slack now loads too quickly for them to be readable. That is the most useful lesson on this page. The best loading screen is the one your performance work makes unnecessary, and copy that flashes past in under a second is noise.
Our Rotating Status Text Loader below is a pure-CSS version of the rotating-message idea, compact enough to sit in a status pill instead of covering the whole screen.
Watch out for: Tips and jokes need time to be read. If your real load time is under two seconds for most users, a message will flash and vanish, which feels more broken than a plain spinner.
2. Awwwards Loading Animations collection: Best for agency and portfolio preloader inspiration
Platform: Awwwards Elements, free to browse (video recordings)
Awwwards curates a collection called Loading Animations, described as "a page or animated element which shows the progress of the loading process". It holds 542 recorded entries, from studios such as ByteTown, Studio Olimpo, Tubik, DashDigital and Emotion Agency, plus related Elements like Appart Agency's UX-writing loader and Heights Agency's interactive pre-loader.
Use it to study the agency preloader as a genre. The question to ask of each entry is how it ends: a loader that turns into the first screen feels like the page arriving, while one that simply fades out feels like a wall that was in the way. Our Split Flap Text Loader below is a pure-CSS take on the typographic style, with letters flipping in like a departure board.
Watch out for: These are screen recordings, so you get no code and no performance numbers. Many of the sites gate every visit behind the intro, which is fine for an award jury and tiring for a client checking your contact page for the third time.
Appart Agency: loading animation UX writing ↗Jon Way: loading animation ↗
3. Codrops Page Preloading Effect (after Fontface Ninja): Best for a logo preloader that hands off into the page header
Platform: HTML, CSS and JavaScript tutorial (Codrops license)
Codrops published this tutorial in August 2014 as "a simple page preloading animation based on the effect seen on Fontface Ninja", built with CSS animations, 3D transforms and SVG. A logo and a circular progress element hold the screen while assets load, then the whole header moves up while the page content is revealed underneath.
It is a clear reference for the handoff pattern: the loader does not disappear, it becomes the header. That one decision is what makes a preloader feel like design instead of a delay. Our Draw and Erase Circle Loader below is a pure-CSS version of the circular stroke, animating only `stroke-dashoffset` on one SVG circle.
Watch out for: The reveal waits for the page assets, which is exactly the pattern that delays LCP. The README also says you may use and adapt it in your projects but not republish or sell it as-is.
4. Igloo Inc by abeto: Best for WebGL sites where the intro is the experience
Platform: Custom WebGL site (case study on Awwwards)
Igloo Inc, the parent company of Pudgy Penguins, has a landing page built by the technical art studio abeto with Bureaux, documented in an Awwwards case study from October 2024. It is a useful example because the case study talks about loading as a design problem rather than hiding it behind a spinner.
The intro animation is rendered in real time instead of shipped as video, which the team says flows into the rest of the experience and keeps file size down. They wrote custom geometry exporters to minimise initial loading, used various strategies for loading textures and compiling shaders, and compressed their volume data to a smaller file than a typical website image. They also tested on low-end devices throughout. If your site needs a loading screen, this is the bar: make the wait as short as engineering allows, then make what is left part of the show.
Watch out for: This level of asset work takes a specialist team. A heavy 3D site without it will sit on a loading screen for many seconds on mobile data, and visitors leave before the show starts.
5. Three.js LoadingManager: Best for Three.js scenes that need a real loading percentage
Platform: Three.js (JavaScript), MIT license
Many Three.js sites drive their preloader with LoadingManager, which "handles and keeps track of loaded and pending data". You pass one manager to your loaders, then use `onStart`, `onProgress`, `onLoad` and `onError` to drive the screen: update a count as items finish, reveal the scene in `onLoad`, and show a retry message in `onError`.
The docs point out that you can run separate managers, for example to show separate loading bars for objects and textures. Our Liquid Fill Loader below is a pure-CSS take on a fill-up preloader you could drive from that count by mapping progress to a custom property.
Watch out for: `onProgress` fires when single items finish loading, not as bytes arrive. One large GLB model means the number sits at zero and then jumps, so split assets or animate between values.
6. Unity Web builds and createUnityInstance: Best for browser games built in Unity
Platform: Unity Web (WebGL) build templates
A Unity game in the browser starts with `createUnityInstance(canvas, config, onProgress)`. Unity's docs say the loader calls `onProgress` every time the download progress updates, during the initial load and, with Progressive Asset Loading on, during synchronous scene loads, with a value between 0.0 and 1.0.
That single number is all you need for a game-site loading screen: map it to a bar width, a filling logo or a level-select screen that fades in. Web templates control the HTML page around the player, so the loading screen is yours to design. Our Falling Blocks Loader below is a pure-CSS take on a game-flavoured loop for the moments the number is not moving.
Watch out for: The value tracks downloads. Anything your game does after the instance is created, like fetching a save or a level, needs its own loading state or players see a finished bar and a frozen screen.
7. Godot web export boot splash: Best for Godot games published to the web
Platform: Godot Engine web export (HTML shell)
Godot's web export ships a default HTML shell that can launch your project without changes, and you can replace it. The template exposes the boot splash through placeholders: `$GODOT_SPLASH` for the image, `$GODOT_SPLASH_COLOR` for the background colour and `$GODOT_SPLASH_CLASSES` for CSS classes that follow your splash settings.
For a custom loading screen, the docs point to the engine's `onProgress` callback, which is called regularly as the engine loads new bytes and reports current and total bytes. Our Pixel Hourglass Loader below is a pure-CSS take that suits a pixel-art game's splash.
Watch out for: The docs warn that `total` can be 0 when it cannot be calculated. Handle that case with an indeterminate animation, or your percentage divides by zero.
8. Flutter web initialization hooks: Best for Flutter web apps that sit on a blank page while booting
Platform: Flutter web (flutter_bootstrap.js)
Flutter web boots in three stages: load the entrypoint script, initialise the engine, run the app. The docs show a custom `flutter_bootstrap.js` that creates a plain div and rewrites its text at each stage, from "Loading Entrypoint..." to "Initializing engine..." to "Running app...".
That is a better loading screen than most animated ones, because it tells people something true about what is happening. Style the div as your splash, keep a small looping animation beside the text, and remove it when `runApp()` resolves. Our Loading Text with Animated Dots below is a pure-CSS version of the text-plus-dots pattern.
Watch out for: If you supply your own `onEntrypointLoaded`, the config you passed to `load()` is not forwarded. You have to pass it to `initializeEngine()` yourself.
9. PWA splash screens from the web app manifest: Best for installed web apps on Android and desktop
Platform: Web app manifest (Chromium browsers)
If your site is installable, you already have a splash screen, and you did not have to build it. web.dev explains that Chrome automatically creates the splash screen from the `name`, `background_color` and `icons` in your manifest. For Chromium you must provide at least a 192 by 192 and a 512 by 512 icon, and Chrome picks the one that best matches the device resolution.
The craft is in the handoff. Set `background_color` to the background of your first screen so the splash fades into the app instead of flashing white, and make that first screen render fast so the splash is gone before anyone studies it.
Watch out for: You do not control any animation here: the browser draws it. Do not stack your own animated preloader on top of the generated splash, or installed users get two loading screens in a row.
10. Next.js loading.js: Best for React apps that need loading states without a preloader
Platform: Next.js App Router (React Suspense)
This is the modern alternative to a full-page preloader. Drop a `loading.js` file into a route folder and Next.js wraps that segment in a Suspense boundary, showing an instant loading state from the server while the content streams in. The fallback is prefetched, navigation stays interruptible and shared layouts remain interactive while the new segment loads.
The result is a loading screen scoped to the part of the page that is actually loading, while the header, navigation and anything cached stay usable. Fill the fallback with a skeleton or a small loader. Our Dot Spinner below is a pure-CSS option that fits inside a segment without any JavaScript.
Watch out for: If the layout reads uncached data such as `cookies()` or `headers()`, `loading.js` will not show a fallback for it and navigation can block. Streaming also is not supported on a static export.
11. Pace by CodeByZach: Best for adding page-load feedback to an existing site in one script
Platform: JavaScript, MIT license, about 4 KB gzipped
Pace automatically adds a page-load progress indicator with no configuration: include the script and a theme stylesheet. It estimates progress from four collectors (Ajax requests, specific elements appearing, the document's readyState and event-loop lag) and restarts on `pushState` navigation, so it also covers single-page apps.
The script is about 4 KB minified and gzipped with no dependencies, and themes run 0.5 to 4 KB. It is the fastest way to give an old site some load feedback without touching its templates. Our Top Page Loading Bar below is a pure-CSS take on the thin bar style, and our progress bar guide covers that family in depth.
Watch out for: The progress is a heuristic, not a byte count, and only GET Ajax requests are tracked by default. Avoid the full-screen themes on content sites: covering the page brings back the LCP problem.
12. Our Full Page Loading Overlay: Best for blocking actions after first paint, like checkout
Platform: Motions directory, free, pure CSS Ours
A translucent, blurred overlay with a ring spinner and a real message ("Loading your dashboard") in a `role="status"` element with `aria-live="polite"`, so screen readers hear the text. The spinner is a pseudo-element, so the markup is a single div.
Use it for the moments when interaction genuinely has to stop: placing an order, switching workspace, applying a big filter. Change `position: absolute` to `fixed` to cover the whole viewport, and set `--ldr-color` to your brand. The copied snippet includes a `prefers-reduced-motion` block that slows the spin to three seconds rather than freezing it.
Watch out for: Never use it on the first load of a content page. It hides the content you want counted for LCP and blocks people who could already be reading.
13. Our Text Fill Loading Animation: Best for a short wordmark intro on a portfolio or studio site
Platform: Motions directory, free, pure CSS Ours
Outlined letters fill with solid colour from the left, hold, then the fill slides out to the right. It is one element: a text stroke plus a moving background clipped to the glyphs, so there is no image or font file to download before it can play.
Swap LOADING for your name or studio name and you have the agency-style wordmark intro from the Awwwards collection, at a fraction of the weight. Find more typographic loaders in Text Animations, or describe your own in the creator.
Watch out for: Play it once per session and keep it under about a second, then reveal real content. An intro that runs on every page view turns a signature into a toll.
How to choose a website loading screen
Start by checking whether you need one. Then pick the kind, then the look.
Check what it does to LCP
web.dev's guidance is an LCP of 2.5 seconds or less at the 75th percentile, and its rules explain why preloaders hurt: an element only counts once it has rendered and is visible, and Chromium ignores elements at `opacity: 0`. If your preloader hides the page with opacity or display tricks, your LCP becomes the moment the preloader leaves. On content, marketing and shop pages, skip the full-screen loader, render the real page fast and use skeletons or small loaders for the parts that are still arriving, the way Next.js `loading.js` does.
Use a real number when you have one
Games and 3D sites are the honest home of the full-page loading screen, and their engines hand you real progress: Three.js LoadingManager counts items, Unity reports 0.0 to 1.0, Godot reports bytes, Flutter reports stages. Show that number, or stage text like Flutter's, instead of a fake counter that always takes three seconds. Handle the edge cases each one documents: Godot's total of 0, Three.js jumping on large files, Unity's work after download.
Make the intro hand off, and play it once
For portfolios and studio sites where the intro is brand, study the Awwwards collection and the Codrops Fontface Ninja effect: the best loaders turn into the header or the hero instead of fading out. Keep it short, store a flag in `sessionStorage` so returning visitors skip it, and give `prefers-reduced-motion` users a static version. For the building blocks, browse our Loaders and Text Animations, and see logo loading animation ideas for brand-mark intros.
Fix the wait first, then design what is left
Run your page through a performance test before you design a loading screen. If the real content can render in under two seconds, delete the preloader and spend the effort on the first screen. If it cannot, because you ship a game, a 3D scene or a big app bundle, wire the loading screen to the real progress number and make it hand off into the page.
If you want a loader that matches your brand, describe it to our creator and get production-ready CSS keyframes, or paste your logo or header so the intro is built around it.
Make a full-page loading screen for a WebGL portfolio site. Show my wordmark in outline and fill it from left to right driven by a --progress custom property from 0 to 1. When progress reaches 1, hold for 200ms, then slide the wordmark up 40vh over 600ms with cubic-bezier(0.65, 0, 0.35, 1) so it becomes the page header. Animate only transform, opacity and background-position. Under prefers-reduced-motion, skip the slide and cross-fade to the page over 150ms.
Common questions
What is a website loading screen?
A website loading screen, or preloader, is a full-page layer shown while a site downloads what it needs before it can display. It usually has a logo, a spinner or a progress counter, and it disappears or animates away when loading finishes. Browser games, WebGL sites and app-style frameworks use them most.
Are preloaders bad for SEO and Core Web Vitals?
They often are. Google's LCP metric only counts content once it is rendered and visible, and Chromium ignores elements with `opacity: 0`. A preloader that hides the page therefore pushes LCP to the moment it disappears. web.dev's target is 2.5 seconds or less at the 75th percentile, which most full-screen intros struggle to meet.
How long should a website loading screen last?
As short as the real load. Never add an artificial minimum. Slack retired its loading messages in 2019 because the app loaded too quickly for them to be read, which is the right outcome. For brand intros, keep the animation to about a second and play it once per session.
How do I make a preloader with CSS?
Put a fixed, full-viewport element at the top of the body with your loader inside, then remove it or fade it out when the page's `load` event fires (or when your framework reports ready). Keep the loader itself pure CSS so it can play before any JavaScript downloads. Our Full Page Loading Overlay is a starting point.
Should a loading screen show a percentage?
Only if the number is real. Three.js, Unity and Godot all expose actual progress callbacks, so games and 3D sites can show one honestly. A counter that runs from 0 to 100 on a timer is a fake, and people notice when it stalls at 99.
Sources
- Slack: updates and changes (changelog)
- web.dev: Largest Contentful Paint
- Awwwards: Loading Animations collection
- Codrops PagePreloadingEffect repository
- Awwwards: Igloo Inc case study
- Three.js docs: LoadingManager
- Unity docs: Web template structure and instantiation
- Godot docs: Custom HTML page for Web export
- Flutter docs: Web app initialization
- web.dev: Add a web app manifest
- Next.js docs: loading.js
- Pace README (GitHub)