2013-07-10 121 views
4

我用正交投影法制作了一張地圖,我試圖改善性能,因爲旋轉不平滑(大約6-7FPS)。d3.js:正交旋轉優化

這是用topojson文件(world-100m)構建的世界地圖。我需要與國家互動,並將它們着色,所以有像國家那樣多的svg:路徑。

加載我有一個自動旋轉功能後使用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

嘗試通過調整--simplify-proportion,-s或--quantization topojson標誌來降低SVG路徑的複雜性。瀏覽器仍然有相當差的SVG渲染性能,並且使用地圖確實有助於減少點的數量和精度。

+0

在生成topojson文件的同時添加--simplify-proportion 0.6,將性能從11改進到20 FPS,而不會泄露太多細節。 –

1

D3.js使用Request Animation Frames執行定時器。

From D3 documentation

如果你的瀏覽器支持它,定時器隊列將使用requestAnimationFrame流體和高效的動畫。

因爲我知道這是在現代瀏覽器中執行動畫的最佳方法,我不認爲你可以直接優化這部分。否則,你可能會調用堆棧使用selection_each,這可能會被緩存到一個變量中。

+0

是的,我知道*請求動畫幀*,但我希望他會盡可能快。我對* Request Animation Frames *的理解是,它避免了更頻繁地循環瀏覽器可以重繪以避免無用的計算,但是這不應該使動畫變慢。對於'selection_each',你是絕對正確的,我會緩存這個結果。謝謝 ! –