Производительность
JavaScript — очень быстрый язык. В некоторых случаях он оказывается лишь немногим медленнее C++. При этом объем данных, с которым работает большинство приложений достаточно незначительный (обычно это не более нескольких тысяч объектов), операции над которыми будут занимать небольшое количество времени.
Узким местом является не работа с данными, а работа c DOM. Несколько вставок в DOM могут быть медленнее обработки массива на несколько тысяч элементов.
Именно поэтому стоит использовать Array.prototype.map
, а не for
,
так как читаемость map
выше.
Оптимизировать операции (заменять «медленный» map
на «быстрый» for
)
стоит только в том случае, если профилирование показало,
что в данном конкретном месте map
занимает значительное время
с учетом остальных операций. Аналогично и для всех остальных операций.
Операции с DOM
Операции с DOM - главное узкое место при разработке приложений. Медленными являются не только операции на изменение, но также и операции на чтение из DOM, так как многие такие операции вызывают reflow элементов.
Современные фреймворки берут изменения DOM на себя. Они минимизируют количество операций с DOM. У каждого фреймворка свой механизм, с которым стоит разобраться и понимать что происходит внутри, чтобы писать код, который позволяет фреймворку работать корректно.
Скорость работы
Несмотря на то, что JS — быстрый язык, всё же необходимо понимать что такое асимптотическая сложность и какое количество операций потребуется тому или иному алгоритму при различном количестве элементов. Например, функции со сложностью O(n^3) при 1000 элементов потребуется миллиард (1000^3) операций для выполнений — даже для небольшого числа элементов время выполнения получится огромным.
60FPS
60 кадров в секунду — это тот показатель, к которому необходимо стремиться. Именно при таком количестве кадров, анимации выглядят наиболее плавными. Сложностью является то, что на один кадр отводится всего 16.6мс времени. При этом в это время входит как вычисления (JS), так и reflow \ repaint самой страницы.
Если есть какие-то долгие операции, то имеет смысл их разбивать
на несколько отдельных, каждую из которых вызывать через
requestAnimationFrame
или requestIdleCallback
(в зависимости от их приоритета).
Еще одним вариантом является Web Workers — они позволяют запустить выполнение кода в отдельном потоке, который не будет вызывать подвисание интерфейса во время его выполнения.