A 3D Homepage Without a Loading Screen: How We Stopped Moving the Stall Around

Most 3D websites open on a loading screen. Here is how we removed one from an online store, why three fixes only moved the freezes, and what fixed them.

Key Takeaways

  • Ambitious 3D websites usually open on a loading screen, because the browser needs time to download the scene and prepare it for the graphics card. On an online store, that screen sits between the shopper and the products.
  • Removing it is easy. The hard part is the one-off setup it was hiding: on this project, about 1.2 s of work in blocks of 150 to 500 ms that the browser cannot split.
  • Starting that setup on the first scroll, splitting it into steps, and waiting for pauses in scrolling all moved the freezes to a different part of the page. None removed them.
  • The fix was to stop doing the work in the visitor's browser: the 3D film is now rendered offline as a video. The homepage no longer loads a 3D library at all.
  • Scroll-linked motion driven by JavaScript can feel stepped on a trackpad even when frame metrics look perfect. CSS scroll-driven animations fixed it.

This is the story of one homepage, measured at every step. It's for founders, marketing leads and developers planning a site with heavy 3D or motion, and wondering whether they have to accept a loading screen to get it.

The client and the brief

shoporganyc.com is the online store of New Tripolis Pharma, the exclusive distributor of Organyc in Lebanon. Organyc makes pads, liners and tampons in organic cotton. The brand was launched in 2008 out of Corman, a cotton company founded in 1947 that supplied bandages to hospitals and pharmacies across Italy and Europe (Organyc, Our Story). We built the store: catalogue, checkout with cash on delivery, map-based delivery addresses, an editorial section and the content management behind it.

The homepage centrepiece is an "anatomy" of an Organyc pad in 3D: the pad comes apart layer by layer, and the text explains what each layer does. It's the brand's main argument (what's inside the product), so it had to look exceptional.

Why 3D websites open on a loading screen

Before writing a line of code, we looked at how the best 3D sites handle loading. The answer is almost always the same: a loading screen.

There's a good reason for it. A 3D scene needs its models, textures and lighting downloaded, and then the browser has to compile the shaders, the small programs the graphics card runs to draw each material. Until that's done, the first frames stutter. A loading screen hides all of it, and on a portfolio or a brand experience, visitors accept the wait.

Apple takes a different route on some product pages. Its well-known AirPods Pro scroll animation is a sequence of pre-rendered images drawn on a canvas, not a live 3D scene, as CSS-Tricks showed by recreating it (Jurn van Wissen, 2020). Keep that in mind; it comes back at the end.

Version 1: the loading screen

The first version, built on 23 October 2026, followed the market. A full-screen loader held the page until the hero video had buffered and the 3D scene had prepared itself. Once the page appeared, everything ran smoothly.

Our contact at New Tripolis Pharma wasn't fully sure about it. A loading screen on a shop is unusual, and a shopper who came for a pack of pads doesn't expect to wait for a show. When we explained why ambitious 3D sites work this way, he was convinced and approved it.

We weren't satisfied, though. The numbers backed his first instinct. On a mobile Lighthouse run, the homepage scored 41, with 8.6 s of Total Blocking Time and 3.3 MB of page weight. (Before that, we had already compressed the hero video from 19.5 MB to 2.2 MB without visible loss.) For a store that wants to rank in Google and convert visitors on a phone, that's a lot to ask. So we set ourselves a goal the client hadn't asked for: keep the 3D, lose the loading screen, and never let the page freeze.

Version 2: no loader, a lighter page

On the morning of 10 November we removed the loader and lightened the page:

  • Hero: a poster image that shows instantly, and a lighter video for phones (690 KB).
  • Product slider: it now sends only the fields the cards display, so the homepage HTML went from 456 KB to 277 KB.
  • 3D scene: it now loads on the visitor's first scroll, tap or key press, instead of before the page appears.

In our local Lighthouse runs, the mobile score went from 41 to 70, Total Blocking Time from 8.6 s to 0.3 s, and page weight from 3.3 MB to 1.5 MB. Run against the live site, the score landed between 60 and 63. Lighthouse is a lab test, and scores move with the network and the machine that runs them.

The cost the loader was hiding

Then the jitter appeared. The 3D setup (compiling shaders, preparing the lighting and the reflections) takes about 1.2 s in total, in blocks of 150 to 500 ms. During each block the browser's main thread can do nothing else: no scrolling, no animation, no response to a tap. Google treats anything over 50 ms as a long task that makes a page feel unresponsive (web.dev, Optimize long tasks).

The 3D library we used, three.js, already offers an asynchronous compile that uses a browser extension to compile shaders in parallel (three.js source, compileAsync). We used it. Some of the setup still runs in single, indivisible blocks, notably the preparation of the reflections, which we precompiled as well.

The loader had absorbed that cost. Without it, the cost landed wherever the visitor happened to be. Here's what each fix did:

AttemptWhere the freezes landedResult
Start the 3D setup on the first scrollWhile scrolling into the 3D sectionJitter at the pinned section
Precompile shaders, split the setup into stepsWhile scrolling the heroJitter in the hero
Wait for pauses in scrolling before each stepInside the 3D section and the next one, after the visitor had scrolled pastScrolling broke badly, and the section still said "Loading the layers" on arrival
Start the setup 1.5 s after load, in one goBefore the 3D section, during the heroThe section was ready on arrival, but the hero video stuttered

The third attempt is the instructive one. Waiting for a pause in scrolling sounds clever, but each block can't be interrupted once it starts. A block that started in a pause froze the scroll that resumed a moment later. And while the visitor kept scrolling, the setup kept slipping later, past the point where it was needed.

The lesson: you can move a cost like this, but you can't hide it. It has to happen before the visitor needs it, at a moment they won't notice, or not happen in their browser at all.

A side quest: scrolling in "steps" on a trackpad

While testing, we felt the scroll move in small steps on a laptop trackpad. Chrome's performance traces showed the page itself scrolling smoothly: almost every frame was presented on time.

The culprit was the next section, where cards slide in as you scroll. React was moving those cards on every scroll frame. Browsers scroll on a separate thread and deliver scroll events to JavaScript asynchronously (Chrome for Developers, scroll-driven animations), so the cards were always one frame behind the page. Frame metrics don't show that. A hand on a trackpad does.

We moved the cards to CSS scroll-driven animations (MDN, animation-timeline), where the browser itself moves them in step with the scroll. The card positions match the old version within 1 px, and JavaScript work while scrolling that section dropped from 319 ms to 103 ms. Browsers without support keep the scripted version. The feature works in Chrome since version 115, Safari since 26 and Firefox since 159 (MDN browser compatibility data). On the same trackpad, the steps were gone.

Was the hero video over-compressed?

With the 3D setup now running during the hero, the hero video stuttered, and the first suspicion was the compression. We checked rather than guessed: compared frame by frame with the 4K original, the video scored an SSIM of 0.992 (1.0 means identical), and all 174 frames were there at the original 24 fps. The file was fine. The stutter came from the 3D setup running over it: four freezes, 3.5 to 6 s after load, each skipping 3 to 6 frames.

That settled it. As long as the 3D scene was prepared in the visitor's browser, it would freeze something.

Version 3: render the film offline

We asked the question that should probably come first on any project like this: does the visitor interact with the 3D, or only watch it? Here, they watched. A button, "Discover the layers", plays the film in place, and the visitor can replay it. They never rotate the pad or pick a layer.

A film you only watch can be a video. So we render the same 3D scene offline, frame by frame at 60 frames per second, into two cuts: 4.1 MB for desktop and 1.6 MB for phones. The video only downloads when the visitor approaches the section. The video's own clock drives the existing text and colour animations, so they stay in step with the picture.

Measured on the live site afterwards:

Live 3D scenePre-rendered video
Hero videoFour freezes of 180 to 500 ms1 dropped frame in 8 s
Long tasks after loadSeveral, 150 to 500 msNone
3D library downloadedYesNo

The cause is gone, not moved. The opening, every step of the film, the finale and the Replay button all work as before.

The trade-offs

Nothing is free. Here's what we gave up:

  • The pad no longer passes in front of the heading. The video sits under the text.
  • The pad is a still frame while it waits for the button, instead of breathing gently.
  • Screens that aren't 16:9 crop the edges of the video.
  • Any change to the 3D scene means re-rendering the videos. It takes under a minute, and the steps are scripted.

Our automated tests can't reproduce touch scrolling faithfully, so we checked the final version by hand on a phone: scrolling and the film both run smoothly. We haven't run timed measurements on a phone.

Checklist for your own 3D homepage

  1. Decide whether visitors interact with the 3D or only watch it. If they only watch, a pre-rendered video or image sequence is almost always lighter and smoother.
  2. Measure the setup, not just the download. Record a performance trace and look for long tasks after load. A small file can still hide a second of shader compilation.
  3. If you keep live 3D, schedule the setup deliberately, before the visitor reaches the section and away from anything that animates. Don't hope to slip it into pauses.
  4. Drive scroll-linked motion with CSS, not with JavaScript on every scroll event.
  5. Test on a trackpad and a phone, not only with metrics. People feel lag before tools report it.
  6. If you keep a loading screen, make it a choice, for a brand experience where visitors expect it, not a default.

Frequently asked questions

Is a loading screen always bad? No. On an immersive brand site or a portfolio, visitors accept a short wait, and the best 3D sites use one. On an online store or a lead-generation page, every second before content appears costs visits, so it's worth working harder to avoid one.

Doesn't a video weigh more than a 3D model? Sometimes. Here the phone cut is 1.6 MB and only downloads near the section. The real saving is the setup work the browser no longer does, which no file size shows.

Can't you just split the 3D setup into smaller steps? Partly. Some steps, like compiling a complex shader, can't be split by your code. Once a 300 ms block starts, the page freezes for 300 ms, wherever the visitor is.

Does this hurt SEO? The opposite. The page is lighter, blocks the browser far less, and shows its content immediately, all things Google measures.


FNB Solutions designs and builds ambitious websites and online stores that stay fast. See our custom websites service, or tell us about your project.

Sources