Это урок о производительности JavaScript, который вы уже знаете, но всегда забываете. По крайней мере, я

Вы можете полностью использовать JavaScript для создания производительной анимации со скоростью 60 кадров в секунду. Даже с тысячами элементов, движущихся в каждом кадре вашей анимации.

ПРИМЕЧАНИЕ. Это кросс-пост из моего информационного бюллетеня. Я публикую каждое электронное письмо через две недели после его отправки. Подпишитесь, чтобы получать больше подобного контента раньше прямо в свой почтовый ящик! 💌

Несколько лет назад (время летит незаметно) я использовал React, Redux и Canvas, чтобы протолкнуть генератор частиц через 20 000 элементов. Даже на мобильном телефоне.

Основная идея звучит так:

  • поместите все, что вы анимируете, в состояние
  • изменить состояние 60 раз в секунду
  • пусть React повторно отрендерит
  • анимация!

Дает вам полный контроль. Иногда даже слишком. Для более легкого подхода вы можете использовать переходы D3. Особенно полезно, если вы уже создаете датавиз или что-то в этом роде.

Около 10 строк кода и у вас есть Декларативные переходы D3 с реакцией 👇

Отлично работает 👌

Рекурсия DOM сложна для движка React

Но потом вы делаете что-то глупое. Как визуализировать древовидную структуру данных с помощью рекурсии.

Вот как выглядит использование переходов D3 для анимации всего 536 элементов, когда эти элементы глубоко вложены.

Да, это с производственной сборкой React. Не очень помогает.

Вы можете узнать больше о том, как работает этот флеймеграф, в этом уроке Tiny React & D3 flamegraph. Дело в том, что он декларативен, прост в использовании и имеет переходы D3 для анимации.

Но спектакль ужасный ☹️

Проблема в том, что распространение информации через глубоко вложенное дерево - это чуть ли не худший сценарий для движка React. Это означает, что огромная часть дерева помечена для обновлений и нет возможности для оптимизации.

Есть два способа решить эту проблему:

  1. Реорганизуйте код, чтобы он использовал плоскую структуру DOM / React.
  2. Вместо этого используйте переходы CSS

Первый вариант отличный. Модифицированная версия популярной в компьютерных классах задачи оптимизация хвостовой рекурсии.

Хвостовая рекурсия - это когда вы вызываете свою функцию как последнюю операцию вашей функции. Рекурсия происходит последней.

const Flamegraph = (...) => ( <g> <rect> <Flamegraph> </g> )

Вы, вероятно, всегда можете размотать их на петли. Петли имеют лучшую производительность.

Во многих других языках компилятор выполняет эту оптимизацию за вас. Вы пишете хвостовую рекурсию, а компьютер выполняет цикл.

Интересно, сможет ли React это сделать? Я должен спросить. Вероятно, это не то, о чем будет заботиться достаточное количество людей.

Делать это вручную громоздко.

CSS-анимация спешит на помощь

Калле Отт услужливо решил проблему с анимацией CSS. Потому что Калле Отт потрясающий.

Использование переходов CSS отлично работает 👇

Браузеры безумно хороши в анимации с помощью CSS. Часть движка рендеринга браузера, работающая, если это вообще возможно, на графическом процессоре, отлично работает.

Вы в любом случае уже выполняете переходы, не так, как будто вам нужен контроль над JavaScript. 🤷‍♀️

К тому же это довольно просто сделать.

Определите несколько переходов

const transitionTime = "250ms"; const transitionCurve = "cubic-bezier(0.85, 0.69, 0.71, 1.32)"; const widthTransition = `width ${transitionTime} ${transitionCurve}`; const transformTransition = `transform ${transitionTime} ${transitionCurve}`;

Примените их к нужным элементам с помощью JavaScript.

componentDidUpdate() { const { width, x, y } = this.props; d3select(this.gRef.current).attr("transform", `translate(${x}, ${y})`); this.hideLabel(); } // render <g transform={`translate(${x}, ${y})`} style= onClick={this.onClick} ref={this.gRef} >

Тот же API, что и раньше: измените x и width, когда вам нужно обновить. За исключением того, что теперь переход x обрабатывается transformTransition, а переход ширины запускается в componentDidUpdate с меньшим количеством строк, чем раньше.

Урок выучен. Спасибо, Калле 👌

В других новостях

Выбор стажера идет хорошо. На прошлой неделе у нас был веб-семинар, на котором я объяснил новый контекстный API React и ответил на кучу вопросов. Было весело. Вот резюме.

Придумывать это и принимать важные решения отнимали большую часть моей недели. Подробнее об этом в блоге на следующей неделе :)

Я обещаю, что "Learn While You Poop" скоро вернется в эфир. Я знаю, что уже говорил это несколько раз, но сейчас контент распланирован, и буфер накапливается. 🤞

Несколько крутых вещей

Вот несколько интересных моментов за неделю:

Ваше здоровье,

~ Swizec

PS: Вас заинтересует платный вебинар по React & D3? Подобно моим 7-часовым семинарам, но короче и намного дешевле. Я разрабатываю новый материал для обновления книги / курса и хочу его опробовать. Оставьте мне комментарий!

P.S. Если вам это нравится, обязательно подпишитесь, подпишитесь на меня в Twitter, купите мне обед и поделитесь этим со своими друзьями. 😄