快速定位WebGL渲染性能瓶颈,提供Chrome DevTools分析、纹理压缩、Draw Calls优化、shader与内存泄漏排查方法。
页面存档备份,存于互联网档案馆 WebGL QQCrome DevTools GPU QF12 + 性能 + 屏幕截图 + WebGL 5-10 + + + 5是一项面向实际任务的技能,主要用于GPU + 10ms + 20ms.;JS + 5ms + 10ms.;
从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。
执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。
F12 → Performance → 勾选 Screenshots + WebGL
录制 5-10 秒交互,查看 Frame 时间分布。
| 指标 | 健康值 | 警告值 |
|---|---|---|
| Frame 时间 | < 16ms | > 33ms |
| GPU 时间 | < 10ms | > 20ms |
| JS 时间 | < 5ms | > 10ms |
| Draw Calls | < 100/frame | > 300/frame |
| Triangles | < 100k/frame | > 500k/frame |
// ❌ PNG/JPG 纹理 — GPU 内存占用大,加载慢
const texture = loader.load('image.png')
// ✅ 压缩纹理 — 减小 50-75% GPU 内存
// 使用 Basis Universal 压缩
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader'
const ktx2Loader = new KTX2Loader()
ktx2Loader.setTranscoderPath('/basis/')
const texture = ktx2Loader.load('texture.ktx2')
// ❌ 每个物体一个 draw call
meshes.forEach(mesh => scene.add(mesh))
// ✅ InstancedMesh — 一个 draw call 渲染 N 个相同物体
import { InstancedMesh, Matrix4 } from 'three'
const instancedMesh = new InstancedMesh(geometry, material, count)
const matrix = new Matrix4()
for (let i = 0; i < count; i++) {
matrix.setPosition(positions[i])
instancedMesh.setMatrixAt(i, matrix)
}
instancedMesh.instanceMatrix.needsUpdate = true
// ❌ discard 导致 Early-Z 失效,性能暴跌 if (alpha < 0.5) discard; // ✅ 使用 alpha 混合 // material.transparent = true; material.depthWrite = false;
// ❌ 每帧创建新纹理
function render() {
const tex = new THREE.DataTexture(data, w, h, format)
scene.material.map = tex // GC 压力巨大
}
// ✅ 复用纹理,更新数据
const tex = new THREE.DataTexture(data, w, h, format)
function render() {
tex.image.data.set(newData)
tex.needsUpdate = true // 只标记更新,不重新创建
}
// ❌ 1000 个独立 Mesh = 1000 个 draw call
for (let i = 0; i < 1000; i++) {
scene.add(new THREE.Mesh(geo, mat))
}
// ✅ 合并几何体 — 1 个 draw call
import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils'
const merged = mergeGeometries(geometries)
const mesh = new THREE.Mesh(merged, material)
// ❌ 复杂分支
void main() {
if (condition1) { ... }
else if (condition2) { ... }
else { ... }
}
// ✅ 使用 mix/step 代替 if-else
void main() {
vec3 color = mix(colorA, colorB, step(0.5, value));
}
// ❌ 在 shader 中计算 sin/cos(虽然 GPU 快但能省则省) float s = sin(time * 0.001); // ✅ 用 uniform 预计算 uniform float sinTime;
// Three.js 常见泄漏点
function disposeMesh(mesh: THREE.Mesh) {
mesh.geometry.dispose()
if (mesh.material instanceof THREE.Material) {
mesh.material.dispose()
if (mesh.material.map) mesh.material.map.dispose()
} else {
mesh.material.forEach(m => {
m.dispose()
if (m.map) m.map.dispose()
})
}
}
// 监控 GPU 内存
renderer.info.render.triangles // 三角形数
renderer.info.render.calls // draw calls
renderer.info.memory.textures // 纹理数
renderer.info.memory.geometries // 几何体数
// 简易 FPS 计数器
let frames = 0, lastTime = performance.now()
function updateFPS() {
frames++
const now = performance.now()
if (now - lastTime >= 1000) {
console.log(`FPS: ${frames}`)
frames = 0
lastTime = now
}
}
// 在渲染循环中调用 updateFPS()
减少 draw calls、复用纹理、合并几何体、避免 shader 分支 — WebGL 性能优化的四大原则。
相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 134.3万人学习
共49课时 | 82.7万人学习
最新文章