Пример к статье «JS: убираем onclick из html»
-
Избегайте использования eval
При каждом вызове eval или Function, производится разбор строки с исходным кодом. Движок JS должен при этом интерпретировать исходный код и перевести его в исполняемый. Это достаточно трудоёмкая операция — часто в сотни раз более медленная, чем простой вызов функции.
Функция eval особенно плоха, поскольку содержание интерпретируемой строки не известно заранее. Так как код из неё выполняется в рамках кода из которого вызван, это означает, что компилятор не может оптимизировать окружающий контекст. Браузеру приходится откладывать интерпретацию большей части окружающего кода до момента выполнения. Это добавляет значительное количество времени к работе.
Конструктор Function не настолько плох, как eval, так как не влияет на окружающий код, но всё равно он весьма медлителен.
-
Избегайте использования with
Хотя with часто может быть удобен, он может плохо влиять на скорость. With заставляет движок каждый раз создавать дополнительный контекст, содержащий поля используемой переменной. Само это приводит к незначительным замедлениям. Одако, так как структура переменной не известна во время компиляции, компилятор не может нормально оптимизировать код.
Не менее удобный, но более эффективный подход состоит в том, чтобы ссылаться на нужный объект, используя обычную переменную, и из неё получать доступ к полям объекта.
-
Изолируйте eval и with
Так как эти конструкции могут очень сильно повлиять на работу, их использование должно быть сведено к минимуму. Но всё же есть места, где они могут действительно понадобиться. Если какую-либо функцию вызывают часто, или какой-либо цикл выполняется много раз, то нужно стараться избегать этих конструкций внутри них. Они лучше подходят для кода, который выполняется один или несколько раз, а не для критических участков.
Везде, где это возможно, изолируйте их от другого кода так, чтобы они не затронули его работу. Например, располагайте их в функциях верхнего уровня или вызывайте их однажды и сохраняйте результат, с тем, чтобы в следующий раз использовать уже его, не запуская повторно интерпретацию.
Хотя это не столь важно, но конструкция try-catch-finally может иметь своё нехорошее воздействие в некоторых браузерах, включая Оперу, поэтому лучше изолировать и её.
-
Избегайте глобальных переменных
Многие создают глобальные переменные, просто потому что это легко. Однако, по некоторым причинам, глобальные переменные могут снизить скорость работы сценариев.
Во-первых, при использовании глобальной переменной внутри функции, движок должен пройти в поиске переменной по всей цепочке вызванных функций, пока не достигнет глобальной области. Локальные переменные будут найдены значительно быстрее.
Глобальные переменные существуют на протяжении всего времени жизни сценария. Локальные же переменные уничтожаются при завершении функции. Память, занимаемая ими, может быть освобождена сборщиком мусора.
Во-вторых, глобальные переменные являются свойствами объекта window, что означает, что они находятся не в одном, а в двух контекстах. В глобальном контексте переменные хранятся связанные с названиями, в то время как в локальных контекстах используется предопределённый оптимизированный индекс. В результате глобальные переменные отнимают больше времени на их поиск.
-
Остерегайтесь неявных преобразований объектов
Литералы, такие как строки, числа и логические переменные в рамках ECMAScript могут быть представлены двумя способами. Каждый из них может быть, как простым значением, так и объектом. Например, строковое значение может быть создано просто обычным присвоением литерала: oString='какая-то строка', в то же время эквивалентный объект может быть создан с помощью oString = new String('какая-то строка').
Любые свойства и методы определены только для объекта String а не для простого значения (примитива). Когда вы ссылаетесь на свойство или метод примитивной строки, механизм ECMAScript должен неявно создать новый объект String с тем же самым значением, после чего вызвать нужный метод. Этот объект используется только один раз и при следующем запросе будет создан снова.