d3.js: оптимизация орфографического вращения
Я сделал карту, используя ортографическую проекцию, и я пытаюсь улучшить производительность, потому что вращение не плавное (около 6-7FPS).
Это карта мира, построенная из файла топойсона (world-100m). Мне нужно взаимодействовать со страной и раскрашивать их так, чтобы 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, и вот результат:
Кажется, что анимация запускается медленно, но я не знаю, что это такое. И когда я открываю его, происходит событие 2 GC (сборщик мусора?), Но ничего вокруг... У вас есть идея, что происходит в течение этих 90 мс?
Любые советы по улучшению производительности приветствуются:-)
Спасибо заранее!
Кстати, это выглядит так:
2 ответа
Попробуйте уменьшить сложность путей SVG, настроив флаги --simplify-пропорции, -s или --quanization topojson. Браузеры по-прежнему имеют довольно низкую производительность рендеринга SVG, а с картами это действительно помогает уменьшить количество и точность точек.
D3.js использует Request Animation Frames для выполнения таймеров.
Если ваш браузер поддерживает это, очередь таймера будет использовать requestAnimationFrame для плавной и эффективной анимации.
Как я знаю, это лучший подход для выполнения анимации в современных браузерах, и я не думаю, что вы можете напрямую оптимизировать эту часть. В противном случае кажется, что вы вызываете использование стека selection_each
это, вероятно, может быть кэшировано в переменную.