Angular + d3: анимация svg порождает ужасную CD
Итак, у меня есть компонент, который содержит некоторые d3. Это не очень сложно. Но SVG должен быть в постоянном переходе. Для того чтобы это произошло. Как только функция, выполняющая переход, запускается, она устанавливает время ожидания для повторного вызова через несколько секунд.
Когда этот код работает, вентилятор на моем компьютере немедленно включается, и процессор переходит на 40% +/-. Если я просто соберу svg, а затем не буду запускать анимацию в асинхронном цикле, то загрузка процессора составит всего несколько процентов. Как я и ожидал. Когда я приостанавливаю выполнение JS в DevTools, стек вызовов указывает на цикл CD.
Мой вопрос: как мне получить анимацию d3, чтобы не вызывать сумасшедшее обнаружение изменений Angular?
Вот код, который работает. Это внутри одного из моих классов:
const animate = () => {
// this points to a piece of the SVG in my template
gradient
.transition()
.duration(6001)
.ease(d3.easeSin)
.attr('r', 0.65)
.transition()
.duration(6001)
.ease(d3.easeSin)
.attr('r', 0.35);
this.zone.runOutsideAngular(() => {
this.timeout = setTimeout(() => {
this.zone.runOutsideAngular(animate);
}, 12003);
});
};
this.zone.runOutsideAngular(animate);
Вот что я пробовал до сих пор:
- Как видите, я попытался обернуть его
runOutsideAngular
звонки. Не помогло- Я изменил ChangeDetectionStrategy моего компонента на OnPush. Не помогло
- Я добавил импорт
d3
до ввозаzone.js
, надеясь, что всеd3
функции будут запущены до того, как зоны будут установлены и запущены. Не помогло
Я просто хочу, чтобы эта анимация работала за пределами Angular. Вот пример компонента. Если вы откроете его, обратите внимание, что загрузка процессора на этой вкладке в вашем браузере увеличится до 30%, 40%, 50%? https://plnkr.co/edit/VQAuQzA2JzKNoArmgbfn?p=preview
1 ответ
Вы можете попробовать это.
Удалить
перед загрузкой zone.js добавьте этот флаг. __Zone_disable_requestAnimationFrame = true;
вот обновленный образец.
__Zone_disable_requestAnimationFrame = true;