A common challenge in web 3D is the load time of large, detailed models. User experience is heavily influenced by how quickly content becomes interactive, and waiting for a multi-megabyte file to download can be a significant barrier.
At Needle, we’ve developed a solution to address this: a progressive loading technique, packaged in our @needle-tools/gltf-progressive
library. It’s designed to work seamlessly with popular tools like Needle Engine or Google’s <model-viewer>
or any three.js based engine to get your content on screen almost instantly.
This article provides a practical guide on how to implement this for your own projects.
model-viewer & gltf-progressive example
Original Size: 17.4 MB, Compressed: 6 MB, glTF progressive: 715 KB + streamed data
The Challenge with Standard glTF Loading
By default, when a browser loads a glTF or GLB file, it must download the entire file before it can render the model. For complex assets with high-resolution textures, detailed geometry, and multiple materials, this “all-or-nothing” approach can result in significant waiting times. Users are left staring at a blank space or a generic loading indicator until the entire transfer is complete.
This traditional loading approach creates several user experience problems:
- Poor perceived performance: Even if the actual loading time is reasonable, users perceive the experience as slow because they see nothing for an extended period
- High bounce rates: Users may leave the page before the content appears, especially on slower connections
- Inconsistent experience: Loading times vary dramatically based on network conditions and device capabilities
Modern web users expect immediate visual feedback, similar to how images on websites load progressively from low to high quality. Unfortunately, 3D models have traditionally lacked this capability, creating a significant barrier to adoption in web applications.
Our Solution: Progressive Loading
Our progressive loading approach is inspired by how modern images load on the web using techniques like progressive JPEG encoding. Instead of waiting for a single, monolithic file, the model is intelligently split into multiple quality levels that load incrementally.
Here’s how the process works in detail:
Initial Low-Quality Preview: An optimized, smaller version of the model loads first. This file is heavily compressed and simplified but maintains the overall shape and appearance of the final model. Users see something interactive within seconds, even on slower connections.
Background High-Quality Streaming: While the preview version is displayed and fully interactive, higher quality data streams in the background. This includes full-resolution textures, detailed geometry, and complete material properties.
Seamless Quality Transitions: Once the higher-quality data is ready, the system performs an imperceptible swap, replacing lower-quality assets with their high-fidelity counterparts. Users don’t experience any interruption or loading delays during these transitions.
This method dramatically improves the perceived load time, allowing users to start interacting with your 3D content immediately. The psychological impact is significant: instead of waiting 10+ seconds for a complete model to load, users see results in under 2 seconds and can begin exploring while additional details arrive.
Performance Benefits
Progressive loading typically reduces perceived loading time by 70–95% compared to traditional glTF loading, while maintaining the same final quality. This translates to higher user engagement and lower bounce rates.
Implementation with <model-viewer>
One of the most compelling features of our @needle-tools/gltf-progressive
package is its zero-configuration integration with existing model-viewer implementations. You don’t need to modify your existing <model-viewer>
elements, rewrite JavaScript code, or learn new APIs. Simply include our script, and progressive loading is automatically enabled for all compatible models.
This approach offers several advantages:
- Drop-in compatibility: Works with existing model-viewer projects without code changes
- Automatic detection: The library automatically detects when a glTF file supports progressive loading
- Graceful degradation: For models that don’t support progressive loading, the library falls back to standard loading behavior
- Framework agnostic: Works with any web framework or vanilla HTML
Here is a complete, production-ready example that demonstrates the integration:
<!DOCTYPE html>
<html>
<head>
<title>Progressive Loading with Needle and model-viewer</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 1. Importmap for Three.js, a dependency of model-viewer -->
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three/build/three.module.js",
"three/": "https://cdn.jsdelivr.net/npm/three/"
}
}
</script>
<!-- 2. The <model-viewer> web component -->
<script
type="module"
src="https://ajax.googleapis.com/ajax/libs/model-viewer/4.0.0/model-viewer.min.js"
></script>
<!-- 3. The Needle gltf-progressive script. This enables the progressive loading behavior. -->
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@needle-tools/gltf-progressive@latest/gltf-progressive.min.js"
></script>
</head>
<body>
<!--
The model-viewer tag is standard. The src model has been processed by Needle Cloud
to support progressive streaming.
-->
<model-viewer
src="https://cloud.needle.tools/-/assets/Z23hmXB2oYehK-2oYehK-world/file"
ar
shadow-intensity="1"
camera-controls
touch-action="pan-y"
auto-rotate
max-camera-orbit="auto 90deg auto"
></model-viewer>
<style>
html, body { margin: 0; padding: 0; width: 100%; height: 100%; }
model-viewer {
width: 100%;
height: 100%;
background-color: #f0f0f0;
}
</style>
</body>
</html>
Creating Progressive Assets with Needle Cloud
While progressive loading provides significant performance benefits, it requires assets to be specifically structured with multiple levels of detail (LODs). Creating these assets manually involves complex mesh decimation, texture resizing, and careful optimization—a time-consuming process that requires specialized knowledge.
Needle Cloud eliminates this complexity by providing an automated optimization pipeline that transforms your standard 3D assets into progressive-loading-ready files. This cloud-based service handles the technical intricacies, allowing you to focus on creating great content rather than managing optimization workflows.
The Needle Cloud Optimization Process
When you upload a 3D asset (glTF, GLB, FBX, USD, OBJ, or other supported formats) to Needle Cloud, our advanced pipeline automatically processes it through several optimization stages:
Mesh Optimization:
- Creates multiple levels of detail (LOD0, LOD1, LOD2, etc.) with progressively reduced polygon counts
- Applies intelligent mesh decimation that preserves visual quality while reducing complexity
- Generates optimized geometry suitable for real-time rendering across different devices
Texture Optimization:
- Produces multiple resolution variants (1024px, 512px, 256px, etc.) from your source textures
- Applies advanced compression algorithms including KTX2/Basis Universal for GPU-optimized formats
- Maintains alpha channels and multi-channel textures (normal maps, roughness, etc.) through the optimization process
Advanced Compression:
- Implements Draco geometry compression for mesh data
- Applies Meshopt compression for animation and vertex data
- Uses state-of-the-art algorithms to achieve 90%+ file size reduction while maintaining visual fidelity
The result is a single, optimized asset URL that contains all the necessary data for progressive streaming. This URL can be used directly in your <model-viewer>
implementation or any three.js-based application.
Getting Started with Needle Cloud
- Sign up: Create a free account at cloud.needle.tools
- Upload: Drag and drop your 3D assets into the web interface
- Process: Needle Cloud automatically optimizes your assets (processing time varies by complexity)
- Deploy: Copy the generated URL and use it in your model-viewer implementation
Cost-Effective Optimization
Needle Cloud’s optimization pipeline would cost thousands of dollars to implement and maintain internally. By using our service, you get enterprise-grade optimization without the infrastructure overhead.
Alternative Implementation Methods
While model-viewer provides the simplest integration path, our progressive loading technology works with any three.js-based application or framework. Here are additional implementation options:
Direct three.js Integration
For projects already using three.js, you can integrate progressive loading directly:
npm i @needle-tools/gltf-progressive
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { useProgressiveLoading } from '@needle-tools/gltf-progressive';
const url = "https://cloud.needle.tools/-/assets/Z23hmXBZN45qJ-ZN45qJ-world/file";
const gltfLoader = new GLTFLoader();
// register the gltf-progressive plugin
useNeedleProgressive(gltfLoader, renderer)
gltfLoader.load(url, gltf => {
scene.add(gltf.scene)
})
React Three Fiber Integration
For React applications using React Three Fiber:
import { useGLTF } from '@react-three/drei';
import { Canvas } from '@react-three/fiber';
function Model() {
const { gl } = useThree()
const url = 'https://cloud.needle.tools/-/assets/Z23hmXBZN45qJ-ZN45qJ-world/file'
const { scene } = useGLTF(url, false, false, (loader) => {
useNeedleProgressive(loader as any, gl as any)
})
return <primitive object={scene} />
}
function App() {
return (
<Canvas>
<Model />
</Canvas>
);
}
Needle Engine Integration
For full-featured interactive experiences, consider using Needle Engine, which includes progressive loading by default along with physics, networking, and XR capabilities.
Performance Monitoring and Analytics
To measure the impact of progressive loading on your application, consider implementing performance monitoring:
// Monitor loading performance
performance.mark('model-start');
loader.load(url, (gltf) => {
performance.mark('model-complete');
performance.measure('model-load-time', 'model-start', 'model-complete');
const measure = performance.getEntriesByName('model-load-time')[0];
console.log(`Model loaded in ${measure.duration}ms`);
});
This data helps you understand the real-world performance improvements achieved through progressive loading.
Conclusion
Progressive loading represents a fundamental shift in how we approach 3D content delivery on the web. By combining the simplicity and reliability of Google’s <model-viewer>
with the advanced optimization capabilities of Needle Cloud, developers can create 3D web experiences that load faster, engage users immediately, and provide consistently high performance across all devices and network conditions.
The benefits extend beyond just technical metrics:
- Improved user engagement: Users interact with content immediately rather than waiting for complete downloads
- Better conversion rates: Faster perceived loading times lead to higher user retention and lower bounce rates
- Enhanced accessibility: Progressive loading ensures your content works well even on slower connections or lower-end devices
- Future-proof optimization: As web standards evolve, progressive loading provides a foundation for even more advanced loading strategies
This approach represents our broader commitment to building a faster, more accessible spatial web. By removing technical barriers and simplifying implementation, we’re making high-quality 3D experiences available to more developers and, ultimately, more users.
Next Steps
Ready to implement progressive loading in your project? Here’s how to get started:
- Sign up for Needle Cloud: Create a free account at cloud.needle.tools to access our optimization pipeline
- Upload your assets: Drag and drop your existing 3D models to automatically generate progressive-loading versions
- Integrate the library: Add the
@needle-tools/gltf-progressive
script to your existing model-viewer implementation - Monitor performance: Use browser developer tools to measure the performance improvements in your specific use case
For more advanced use cases, explore the full Needle Engine documentation to learn about physics, networking, XR capabilities, and custom component development.
Additional Resources
- GLTF progressive on NPM
- Model-viewer documentation - Complete guide to Google’s model-viewer web component
- glTF specification - Technical details about the glTF 3D format standard
- Three.js documentation - Comprehensive three.js library documentation
More Examples
Explore additional implementations and see progressive loading in action: