d3.js:正交旋转优化

时间:2013-07-10 07:55:26

标签: javascript performance d3.js map-projections heap-profiling

我使用正交投影制作了地图,我尝试提高性能,因为旋转不平滑(大约6-7FPS)。

这是使用topojson文件(世界100米)构建的世界地图。我需要与国家互动并将它们着色,以便存在与国家一样多的svg:path

加载后我使用d3.timer启动了自动旋转功能:

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

似乎动画帧被解雇是缓慢的部分,但我真的不知道它是什么。当我打开它时,有2个GC事件(垃圾收集器?)但没有任何问题......你知道在这90ms内发生了什么吗?

任何提高性能的提示都非常受欢迎: - )

先谢谢!

顺便说一下,它看起来像这样: Map overview

2 个答案:

答案 0 :(得分:2)

尝试通过调整--simplify-proportion,-s或--quantization topojson标志来降低SVG路径的复杂性。浏览器仍然具有相当差的SVG渲染性能,并且使用地图它确实有助于减少点的数量和精度。

答案 1 :(得分:1)

D3.js使用Request Animation Frames来执行计时器。

From D3 documentation

  

如果您的浏览器支持它,则计时器队列将使用requestAnimationFrame进行流畅且高效的动画。

据我所知,这是在现代浏览器中执行动画的最佳方法,我认为您无法直接优化此部分。否则,您似乎调用堆栈使用selection_each,它可能被缓存到变量中。