In the previous article, we mentioned that many Three.js model performance issues can first be addressed with Draco compression and LOD management, which are mainly used to solve problems like slow model loading and lag during the first screen.
But in real projects, there is another even more common situation: the model has already loaded, the scene displays correctly, but as soon as you move the camera, the frame rate starts to drop. And the more objects you have in the scene, the more obvious the stuttering becomes. At that point, the problem is usually no longer about loading, but about runtime rendering pressure.
When I troubleshoot this kind of issue, I usually focus on two things: instanced rendering and geometry merging.
Instanced Rendering: Very Effective for Large Numbers of Repeated Models
When your scene contains a large number of repeated objects—such as trees, streetlights, chairs, equipment, or parts—instanced rendering is a great way to optimize them.
Although there may be many of these objects, in practice they are often just the same model placed repeatedly in different positions. If you still render them one by one in the usual way, the draw call count can shoot up quickly, and once the scene becomes more complex, frame drops are almost inevitable.
The core idea of instancing is simple: let all repeated objects share the same geometry and material, and render them in batches. This can significantly reduce the number of rendering submissions and has a very direct impact on runtime performance.
Generally speaking, using InstancedMesh can reduce draw calls from O(n) to O(1), with performance improvements that can exceed 10x.
import { InstancedMesh, Matrix4 } from 'three';
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial();
const count = 1000; // 1000 cubes
const instancedMesh = new InstancedMesh(geometry, material, count);
const matrix = new Matrix4();
for (let i = 0; i < count; i++) {
// Set position, rotation, and scale for each instance
matrix.setPosition(Math.random() * 100, Math.random() * 100, Math.random() * 100);
instancedMesh.setMatrixAt(i, matrix);
}
scene.add(instancedMesh);
Geometry Merging: More Useful When the Scene Has Too Many Fragmented Models
There is another common case where the scene does not contain many repeated models, but instead has a huge number of small and fragmented objects. Think of architectural components, industrial parts, decorative surfaces, and similar assets. Each one may be lightweight on its own, but once the count gets high enough, Three.js can still struggle.
This is where geometry merging becomes useful. The idea is also straightforward: merge scattered small geometries into a single geometry as much as possible, greatly reducing the number of scene nodes and draw calls, and therefore lowering rendering pressure.
import { BufferGeometryUtils } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
const geometries = [];
for (let i = 0; i < 100; i++) {
const geometry = new THREE.BoxGeometry();
geometry.translate(
Math.random() * 10,
Math.random() * 10,
Math.random() * 10
);
geometries.push(geometry);
}
const mergedGeometry = BufferGeometryUtils.mergeBufferGeometries(geometries);
const mesh = new THREE.Mesh(mergedGeometry, material);
scene.add(mesh);
// Draw calls reduced from 100 to 1
Why I Started Using Translight 3D
If you only have a few models, manually handling instancing or merging is still manageable. But once the project gets larger, manual processing becomes the last thing you want to do.
For example, figuring out which models are suitable for instancing, which ones should be merged, and whether everything needs to be reprocessed after a model update can take a huge amount of time. And many optimization issues cannot really be solved just by patching things at the front-end code level—the root cause often lies in the model assets themselves.
What impressed me most about Translight 3D is that it can handle geometry instancing and geometry merging in one click. In other words, before the assets even enter Three.js, the runtime bottlenecks that usually cause scene lag have already been addressed.

By instancing repeated models, it reduces redundant rendering pressure; by merging fragmented small objects, it lowers the rendering burden of the scene. As a result, assets processed by Translight 3D are much better suited for real-time rendering, and the whole scene runs much more smoothly.
Summary
If Draco compression and LOD solve the problem of “models being too heavy to bring in,” then instancing and geometry merging solve the problem of “scenes being too heavy to run.” For projects with lots of models and complex scenes, using Translight 3D directly saves a lot of effort and delivers more stable optimization results.


