A Production React Three Fiber Meshy Pipeline for Web 3D Models
Learn how JRV Systems builds a practical React Three Fiber Meshy pipeline. From AI text-to-3D generation to gltfpack compression and lazy-loading for fast websites.
Adding 3D models to a website can make it feel premium and interactive. But it often comes at a high cost: performance. A single, unoptimised 3D model can easily be several megabytes, slowing your page load to a crawl, especially for users in Malaysia on mobile data. The key is to have a repeatable process that balances visual quality with file size.
At JRV Systems, we've developed a workflow for this. This article details our production React Three Fiber Meshy pipeline, a series of steps we take to go from a simple text prompt to a highly optimised 3D asset running smoothly in a web browser.
The Core Challenge: Balancing Quality and Performance
The main goal is to keep our 3D assets, specifically in GLB format, under 100KB. For context, that's smaller than many high-resolution JPEG images. Achieving this without making the model look terrible requires a deliberate, multi-step approach. Simply exporting a model from a 3D tool and dropping it into a website is not a viable strategy for production applications.
Every kilobyte matters. A fast-loading site improves user experience, SEO ranking, and conversion rates. For the e-commerce and dashboard projects we build, performance is not a feature; it's a requirement. This pipeline is how we meet that requirement while still delivering modern, visually engaging interfaces.
Step 1: Generating Assets with Meshy AI
Our process begins with AI. Instead of spending hours in complex 3D software like Blender for simple decorative assets, we use services like Meshy.ai. Meshy specialises in text-to-3D and image-to-3D generation. We provide a descriptive prompt, for example, "a minimalist ceramic vase with a single tropical leaf," and the AI generates a 3D model.
The initial output from Meshy is a great starting point. It provides the geometry and basic texturing (PBR materials) in a standard GLB file. However, this initial file is rarely optimised for the web. A typical model from Meshy might be between 500KB and 2MB. This is far too large for our performance budget, which leads us to the next critical step.
Step 2: Refining and Compressing with gltfpack
This is the most important part of the pipeline for performance. We take the raw GLB file from Meshy and process it using gltfpack, a powerful command-line tool developed by Arseny Kapoulkine (zeux). It is not a magic bullet, but it's close. gltfpack performs several optimisations:
- Mesh Simplification: It intelligently reduces the number of vertices and faces in the model's geometry while trying to preserve its overall shape.
- Quantization: It reduces the precision of vertex data (positions, normals), saving space with minimal visual impact.
- Texture Compression: It converts standard PNG or JPEG textures into a highly optimised format like Basis Universal inside a KTX2 container. This is a huge source of file size savings.
Our typical command looks something like this: gltfpack -i model.glb -o model-opt.glb -cc -tc. The -cc flag applies aggressive compression, and -tc handles the texture compression. The results are significant. It's common for us to see a 1.5MB model shrink down to 70-90KB after this process. The visual difference is often imperceptible to the average user.
Step 3: Integrating with React Three Fiber
Once we have our optimised model-opt.glb file, it's time to bring it into the application. We use React Three Fiber (R3F), a React renderer for Three.js. It lets us declare 3D scenes declaratively, just like we build the rest of our UI.
To ensure the 3D model doesn't block the initial page load, we load it asynchronously and lazily. Here’s the strategy:
- We create a wrapper component, let's call it
LazyModel. - This component uses the
react-intersection-observerhook to detect when it has been scrolled into the viewport. - Only when the component is visible does it begin to fetch and render the actual 3D model using the
@react-three/dreilibrary'suseGLTFhook.
This means the browser only downloads the ~80KB model when the user is about to see it. The initial page load remains lightning-fast. The combination of a small file size from gltfpack and lazy loading with an IntersectionObserver is the core of our performant React Three Fiber Meshy pipeline.
When to Use Spline Instead
It's worth mentioning Spline, a popular browser-based 3D design tool. Spline is excellent for creating entire interactive 3D scenes, complex animations, and physics-based experiences. It's an all-in-one solution.
However, for our use case of adding a single, optimised, decorative model, Spline can be overkill. A Spline export often includes its own JavaScript runtime, which can add a larger initial payload to your site than our lean, single-model approach. We view Spline as an escape hatch—the right tool when a project requires a complex, self-contained 3D scene. For individual assets, the Meshy -> gltfpack -> R3F pipeline gives us maximum control over performance and a much smaller footprint.
A Practical Workflow for Modern Web Apps
This pipeline—from AI generation to aggressive optimisation and lazy loading—provides a reliable path to including 3D on the web without compromising speed. It allows us to enhance the user interfaces of billing systems, clinic management software, and e-commerce platforms with modern visuals, all while respecting the user's bandwidth and time. It's a practical, production-ready approach that turns a potential performance bottleneck into a lightweight enhancement.