d3.js:正交旋转优化

5
我使用正交投影制作了一张地图,现在我需要提高性能,因为旋转不够流畅(大约6-7FPS)。这是一个使用topojson文件(world-100m)构建的世界地图。我需要与国家进行交互并彩色显示,因此SVG:path与国家数量相同。加载后,我使用启动自动旋转功能:
autoRotate = () =>
  @start_time = Date.now()     # Store the current time (used by automatic rotation)

  d3.timer () =>
    dt = Date.now() - @start_time

    if @stopRotation or dt > @config.autoRotationDuration
      true
    else
      @currentRotation[0] = @currentRotation[0] - @config.autoRotationSpeed
      @projection.rotate @currentRotation
      redrawPathsOnRotationOrScale(@currentRotation, @projection.scale())
      false

redrawPathsOnRotationOrScale = (rotation, scale, duration = 1) =>
  @currentRotation = rotation

  @projection
    .rotate(@currentRotation)
    .scale(scale)

  @groupPaths.selectAll("path")
    .attr("d", path)

为了理解为什么速度如此慢,我在Chrome中做了一个性能分析记录,以下是结果: Chrome profiling 1/2 Chrome profiling 2/2 似乎“Animation Frame Fired”是个慢的过程,但我不太清楚它是什么。当我打开它时,出现了2次GC事件(垃圾回收器?),但周围没有其他信息...您知道这90毫秒内发生了什么吗?
欢迎提供任何改善性能的技巧 :-)
提前感谢!
顺便说一下,它看起来像这样: Map overview
2个回答

3
尝试通过调整 --simplify-proportion、-s 或 --quantization topojson 标志来降低 SVG 路径的复杂性。浏览器仍然具有相当差的 SVG 渲染性能,对于地图来说,减少点数和精度真的很有帮助。

在生成topojson文件时添加--simplify-proportion 0.6可以提高性能,从11帧/秒提升到20帧/秒,而且不会失去太多细节。 - John Smith

2
D3.js使用请求动画帧来执行计时器。 D3文档中写道:
如果您的浏览器支持,计时器队列将使用requestAnimationFrame进行流畅和高效的动画。
我知道这是在现代浏览器中执行动画的最佳方法,并且我认为您无法直接优化此部分。否则,似乎您调用堆栈使用selection_each,可能可以缓存到变量中。

是的,我知道关于“请求动画帧”,但我期望它能尽可能地快。我的理解是,“请求动画帧”避免了循环比浏览器重新绘制更频繁,以避免无用的计算,但这不应该使动画变慢。对于“selection_each”,你说得对,我会缓存这个结果。谢谢! - John Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接