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 ответ

Вы можете попробовать это.

  1. Удалить

  2. перед загрузкой zone.js добавьте этот флаг. __Zone_disable_requestAnimationFrame = true;

вот обновленный образец.

__Zone_disable_requestAnimationFrame = true;

https://plnkr.co/edit/ft1AdgMh9cGR5rfSxbkk?p=preview

Другие вопросы по тегам