Appearance
高级功能
RayChart 提供一组面向进阶场景的工具 API:性能监控、数据验证、对象池、WebGL 能力检测与数据缓存。常规图表开发用不到这些功能,遇到下述具体问题时再查阅对应章节。
什么时候需要本页内容
- 图表卡顿,想定位耗时瓶颈
- 用 JavaScript(非 TypeScript)开发,想在校验配置错误
- 编写高频创建临时对象的自定义 3D 动画
- 需要兼容老旧浏览器,检测 WebGL 能力
- 轮询数据时避免无意义的重复渲染
只画常规图表?直接看快速上手。
性能监控
方法级计时:DEV_MONITOR / globalMonitor
用于定位某段代码(如更新数据、重渲染)的耗时。
ts
import { DEV_MONITOR } from 'raychart'
function updateChart() {
const startTime = DEV_MONITOR.start('更新数据')
chartOption.value = { series: [{ data: newData }] }
DEV_MONITOR.end('更新数据', startTime) // 开发环境打印耗时(毫秒)
}也可用 measure 包裹函数自动计时:
ts
import { DEV_MONITOR } from 'raychart'
DEV_MONITOR.measure('更新数据', () => {
chartOption.value = { series: [{ data: newData }] }
})开发环境专用
DEV_MONITOR 在开发环境等价于 globalMonitor;生产构建中所有方法为空操作(start/end 返回 0),不产生任何开销。生产环境需要采样时,可自行创建 new PerformanceMonitor(true)。
读取某个标签的统计(getStats 需传入标签名,无数据时返回 null):
ts
import { globalMonitor } from 'raychart'
const stats = globalMonitor.getStats('更新数据')
if (stats) {
console.log(`平均: ${stats.avg.toFixed(2)}ms,最大: ${stats.max.toFixed(2)}ms,采样 ${stats.count} 次`)
}
// 打印全部标签的报告到控制台
globalMonitor.printReport()
// 清除统计(不传参数则全部清除)
globalMonitor.clear('更新数据')PerformanceMetric 字段:count(采样次数)、total / avg(总耗时 / 平均耗时)、min / max、last(最近一次),单位均为毫秒。
FPS 与内存监控
RayChart 内置独立的 FPS 与内存(Chrome 系浏览器)监控器:
ts
import { globalFPSMonitor, globalMemoryMonitor } from 'raychart'
// FPS:在渲染循环中调用 tick() 采样,保留最近 60 帧
function renderLoop() {
globalFPSMonitor.tick()
const fps = globalFPSMonitor.getAverageFPS()
requestAnimationFrame(renderLoop)
}
// 内存:仅支持提供 performance.memory 的浏览器(Chrome/Edge),其他环境返回 null
const usage = globalMemoryMonitor.getMemoryUsage()
if (usage) {
console.log('已用堆内存:', globalMemoryMonitor.formatBytes(usage.usedJSHeapSize))
}数据验证
用 JavaScript 开发且担心配置写错时,可手动校验配置。TypeScript 用户编辑器会直接提示,无需此功能。
ts
import { DataValidator, CommonRules } from 'raychart'
const option = {
series: [{ data: [1, 2, 3] }],
}
const schema = {
series: CommonRules.required('series 不能为空'),
'series.0.data': CommonRules.array(1, undefined, '至少一个数据点'),
'series.0.itemStyle.metalness': CommonRules.percentage('metalness 需在 0-100 之间'),
}
// 方式一:返回校验结果,不抛错
const result = DataValidator.validate(option, schema)
if (!result.valid) {
result.errors.forEach((e) => console.log(`${e.path}: ${e.message}`))
}
// 方式二:校验失败直接抛异常
try {
DataValidator.validateOrThrow(option, schema)
} catch (error) {
console.error('图表配置错误:', (error as Error).message)
}图表组件已内置校验
各图表在 setOption 时已自动校验关键字段(如系列必填、数据非空、类型枚举),校验失败会抛出带图表类型的错误。手动调用适用于需要自定义规则的场景。
CommonRules 预设规则:required / string / number(min?, max?) / array(minLength?, maxLength?) / enum(values) / positive / percentage / color,完整说明见 工具方法 API。
对象池
为什么需要对象池
高频动画循环中反复 new 临时对象(Vector3、Color 等)会产生大量垃圾,触发频繁 GC 导致卡顿:
ts
// 不推荐:每帧创建 1000 个临时向量,产生大量垃圾
function animate() {
for (let i = 0; i < 1000; i++) {
const v = new THREE.Vector3(x, y, z)
const length = v.length()
}
}推荐用法:withPooled 自动管理
从池中取对象、调用回调后自动归还,无需手动释放:
ts
import { withPooledVector3 } from 'raychart'
const length = withPooledVector3((v) => {
v.set(x, y, z)
return v.length()
}) // 回调结束后 v 自动归还池中同时使用多个向量时,回调参数为向量数组,按序解构使用:
ts
import { withPooledVectors } from 'raychart'
const newPos = withPooledVectors(3, ([pos, velocity, force]) => {
pos.copy(particle.position)
velocity.copy(particle.velocity)
force.set(0, -9.8, 0) // 重力
velocity.add(force)
pos.add(velocity)
return pos.clone() // 注意:clone 出的新对象不来自池中,用完自行释放或复用
})手动管理(不推荐)
ts
import { vector3Pool } from 'raychart'
const v = vector3Pool.acquire() // 从池中取一个 Vector3
v.set(1, 2, 3)
const length = v.length()
vector3Pool.release(v) // 必须归还,否则池会逐渐枯竭注意
手动管理容易遗漏 release()。请优先使用 withPooled* 自动管理。
内置对象池
| 名称 | 说明 |
|---|---|
withPooledVector3(fn) / withPooledVector2(fn) | 自动取还 3D / 2D 向量 |
withPooledColor(fn) | 自动取还颜色 |
withPooledVectors(count, fn) | 批量取用多个向量,回调收到数组 |
vector3Pool / vector2Pool / colorPool | 手动管理的向量 / 颜色池 |
quaternionPool / matrix4Pool / eulerPool | 四元数 / 矩阵 / 欧拉角池 |
box3Pool / spherePool | 包围盒 / 球池 |
自定义对象池
ts
import { ObjectPool } from 'raychart'
class Particle {
x = 0
y = 0
speed = 0
reset() {
this.x = 0
this.y = 0
this.speed = 0
}
}
// 构造签名:new ObjectPool(factory, maxSize?, reset?)
// 第二个参数是池容量(默认 100),第三个参数在对象归还时调用
const particlePool = new ObjectPool(() => new Particle(), 100, (p) => p.reset())
const p = particlePool.acquire() // 从池中取对象(池空时走 factory 创建)
p.x = Math.random() * 100
// ... 使用
particlePool.release(p) // 归还(超过容量上限时直接丢弃)WebGL 能力检测
检测是否支持
ts
import { checkWebGLSupport } from 'raychart'
const support = checkWebGLSupport()
if (!support.supported) {
// 不支持 WebGL:提示用户升级浏览器
console.error('浏览器不支持 WebGL')
} else {
console.log(`支持 WebGL ${support.version}.0`)
}获取详细能力
ts
import { getWebGLCapabilities } from 'raychart'
const caps = getWebGLCapabilities() // 不支持时返回 null
if (caps) {
console.log('最大纹理尺寸:', caps.maxTextureSize)
console.log('最大顶点属性数:', caps.maxVertexAttributes)
console.log('支持浮点纹理:', caps.extensions.floatTextures)
console.log('支持各向异性过滤:', caps.extensions.anisotropicFiltering)
}extensions 为对象,字段包括 floatTextures、halfFloatTextures、depthTexture、instancedArrays、anisotropicFiltering 等,完整定义见 工具方法 API。
检查指定扩展
ts
import { checkRequiredExtensions } from 'raychart'
const result = checkRequiredExtensions(['OES_texture_float', 'WEBGL_depth_texture'])
if (result.supported) {
console.log('所有扩展均支持')
} else {
console.log('缺少扩展:', result.missing)
}获取推荐的渲染器配置
按设备能力返回推荐配置(移动端自动降低质量):
ts
import { getRecommendedRendererConfig } from 'raychart'
const config = getRecommendedRendererConfig()
// { antialias: boolean, powerPreference: 'high-performance' | 'low-power' | 'default', precision: 'highp' | 'mediump' | 'lowp' }
console.log(config)打印完整能力信息(调试用)
ts
import { printWebGLCapabilities } from 'raychart'
printWebGLCapabilities() // 在控制台分组打印 WebGL 版本、限制与扩展支持自动适配
图表组件初始化时已自动检测并适配设备能力,无需手动调用。仅在需要自定义降级策略时使用以上 API。
数据缓存
轮询或高频 setOption 时,可用 globalDataCache 判断数据是否真正变化,跳过无意义的重复渲染:
ts
import { globalDataCache } from 'raychart'
setInterval(() => {
const newData = fetchData() // 轮询获取数据
// 数据内容有变化才更新图表
if (globalDataCache.hasChanged('myChart', newData)) {
chartOption.value = { series: [{ data: newData }] }
globalDataCache.set('myChart', newData)
}
}, 1000)其他方法:
ts
import { globalDataCache } from 'raychart'
// 读取缓存
const cached = globalDataCache.get('myChart')
// 删除单个缓存
globalDataCache.delete('myChart')
// 清空全部缓存(clear 不接受参数)
globalDataCache.clear()组件已内置
BaseChart.setOption 内部已用相同机制对 option 做内容哈希比对,内容未变化时自动跳过重渲染(开发环境控制台会打印 Data unchanged, skipping render)。手动使用缓存适用于组件之外的场景。
也可创建独立实例(可设置容量与过期时间,默认 50 条 / 5 分钟):
ts
import { DataCache } from 'raychart'
const cache = new DataCache(200) // 容量 200,超过自动淘汰最久未使用的条目完整 API 列表
性能监控
DEV_MONITOR- 开发环境计时工具(生产环境为空操作)globalMonitor- 全局方法级计时监控器globalFPSMonitor- 全局 FPS 监控器(tick/getAverageFPS/getCurrentFPS/getMinFPS)globalMemoryMonitor- 全局内存监控器(getMemoryUsage/formatBytes/printMemoryUsage,仅 Chrome 系浏览器)
数据验证
DataValidator- 配置验证工具(validate/validateOrThrow)CommonRules- 常用验证规则预设
Three.js 对象池(自动管理)
withPooledVector3()/withPooledVector2()/withPooledColor()/withPooledVectors()
Three.js 对象池(手动管理)
vector3Pool/vector2Pool/colorPool/quaternionPool/matrix4Pool/eulerPool/box3Pool/spherePoolObjectPool- 自定义对象池类
WebGL 能力检测
checkWebGLSupport()- 检查是否支持 WebGLgetWebGLCapabilities()- 获取详细能力checkRequiredExtensions()- 检查指定扩展printWebGLCapabilities()- 打印完整信息getRecommendedRendererConfig()- 推荐渲染器配置
数据缓存
globalDataCache- 全局缓存实例DataCache- 缓存类(可创建独立实例)
总结
| 功能 | 适用场景 | 难度 |
|---|---|---|
| 性能监控 | 图表卡顿,定位耗时瓶颈 | ⭐ 简单 |
| 数据验证 | JS 开发,担心配置写错 | ⭐ 简单 |
| WebGL 检测 | 兼容老旧浏览器 | ⭐ 简单 |
| 数据缓存 | 轮询数据,避免重复渲染 | ⭐⭐ 中等 |
| 对象池 | 高频创建临时对象的自定义动画 | ⭐⭐⭐ 较难 |
记住
常规图表开发无需使用这些功能,遇到对应问题时再回来看对应章节。
