DOM path - Screenshots HTML/CSS/SVG via Playwright
Canvas path - Direct frame encoding via WebCodecs (faster)
For canvas-heavy compositions (Three.js, Pixi.js, raw Canvas API), the canvas path provides significantly better performance through hardware-accelerated encoding.
import * as THREE from 'three';import { Helios } from '@helios-project/core';const canvas = document.getElementById('canvas') as HTMLCanvasElement;const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: false // Disable if no transparency needed});const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75, 16/9, 0.1, 1000);camera.position.z = 5;// Add objectsconst geometry = new THREE.BoxGeometry();const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });const cube = new THREE.Mesh(geometry, material);scene.add(cube);// Lightingconst light = new THREE.DirectionalLight(0xffffff, 1);light.position.set(1, 1, 1);scene.add(light);const helios = new Helios({ duration: 10, fps: 30 });helios.subscribe((state) => { const time = state.currentTime; // Animate based on time (not delta) cube.rotation.x = time * 0.5; cube.rotation.y = time * 0.8; renderer.render(scene, camera);});
const geometry = new THREE.BoxGeometry();const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });for (let i = 0; i < 100; i++) { const mesh = new THREE.Mesh(geometry, material); scene.add(mesh);}
Use instancing for repeated objects
import { InstancedMesh } from 'three';const geometry = new THREE.BoxGeometry();const material = new THREE.MeshStandardMaterial();const count = 1000;const instancedMesh = new THREE.InstancedMesh(geometry, material, count);const matrix = new THREE.Matrix4();for (let i = 0; i < count; i++) { matrix.setPosition(Math.random() * 10, Math.random() * 10, Math.random() * 10); instancedMesh.setMatrixAt(i, matrix);}scene.add(instancedMesh);
Optimize shadow maps
renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Better qualityrenderer.shadowMap.autoUpdate = false; // Update manually if static// Only cast shadows from key lightsdirectionalLight.castShadow = true;directionalLight.shadow.mapSize.width = 2048;directionalLight.shadow.mapSize.height = 2048;