предисловие
В этом выпуске я рекомендую вам книгу «Высокопроизводительный JavaScript». В этой книге мы можем понять узкие места производительности в процессе разработки JavaScript и способы повышения производительности во всех аспектах, включая загрузку кода, выполнение, взаимодействие с DOM, страницу жизненный цикл и др. Точно так же мы до сих пор используем метод интеллект-карт для интенсивного чтения. (Изображение интеллект-карты может быть немного маленьким, не забудьте нажать и посмотреть, вы что-то получите)
загрузить и выполнить
Управление кодом JavaScript в браузере — непростая задача, поскольку выполнение кода блокирует другую обработку браузера, например рендеринг пользовательского интерфейса. каждый раз<script>
тег, страница должна остановиться и дождаться загрузки кода (если он внешний) и выполнения, прежде чем продолжить работу с остальной частью страницы. Однако есть несколько способов уменьшить влияние JavaScript на производительность:
- положить все
<script>
Тег размещается внизу страницы, рядом с закрывающим тегом body.</body>
над. Этот метод гарантирует, что страница будет проанализирована до запуска скрипта. - Упакуйте скрипты в группы. страницы
<script>
Чем меньше тегов, тем быстрее загружается страница и тем более она отзывчива. Это верно независимо от внешних файлов сценариев или встроенного кода.
Существует несколько способов загрузки JavaScript без блокировки:
- для
<script>
Добавьте в тег атрибут defer (только для Internet Explorer и Firefox 3.5+) - динамически созданный
<script>
элемент, который загружает и выполняет код - Загрузите код с объектом XHR и внедрите его на страницу.
Используя описанные выше стратегии, вы можете значительно повысить фактическую производительность веб-приложений, использующих много кода JavaScript.
доступ к данным
В JavaScript место хранения данных может существенно повлиять на общую производительность вашего кода. Существует четыре типа доступа к данным: литерал, переменная, элемент массива и член объекта. У них разные соображения производительности.
Литеральный и локальный доступ к переменным выполняется очень быстро, элементы массива и члены объекта занимают больше времени. Локальная переменная работает быстрее, чем переменная вне области видимости, потому что она находится в первом объекте в цепочке областей видимости. Чем глубже переменная находится в цепочке областей видимости, тем больше времени требуется для доступа к ней. Глобальные переменные всегда самые медленные, потому что они всегда являются последним звеном в цепочке областей видимости. Избегайте использования выражения with, так как оно изменяет цепочку областей контекста среды выполнения. И с предложением catch в выражениях try-catch следует обращаться с осторожностью, так как оно имеет тот же эффект. Члены вложенных объектов могут существенно повлиять на производительность, и их следует использовать с осторожностью.
Чем глубже свойство или метод находится в цепочке прототипов, тем медленнее к нему осуществляется доступ. В общем, вы можете повысить производительность вашего кода JavaScript, сохраняя часто используемые члены объекта, элементы массива и переменные вне области видимости в локальных переменных. Тогда доступ к локальным переменным будет быстрее, чем к этим примитивным переменным. Используя эти стратегии, вы можете значительно повысить фактическую производительность веб-приложений, требующих большого количества кода JavaScript.
DOM-программирование
Доступ к DOM и манипулирование им — важная часть современных веб-приложений. Но каждый раз, когда вы пересекаете мост с острова ECMAScript на остров DOM, с вас будет взиматься плата за проезд по мосту. Чтобы уменьшить потери производительности при программировании DOM, помните о следующих моментах:
Минимизируйте доступ к DOM и делайте как можно больше на стороне JavaScript. Используйте локальные переменные для хранения ссылок DOM в местах, к которым часто обращаются.Будьте осторожны с коллекциями HTML, поскольку они демонстрируют «существование», всегда повторно запрашивая базовый документ. Кэшировать свойство длины коллекции в переменной и использовать эту переменную в итерации. Если вы часто работаете с этой коллекцией, вы можете скопировать коллекцию в массив.
Если возможно, используйте более быстрые API, такие как querySelectorAll() и firstElementChild. Обратите внимание на перерисовку и переразметку, пакетную модификацию стиля, автономные манипуляции с деревом DOM, кеширование и сокращение доступа к информации о раскладке. Абсолютные координаты используются в анимации с использованием прокси-серверов перетаскивания. Используйте методы размещения событий, чтобы свести к минимуму количество обработчиков событий.
Алгоритмы и управление процессами
Как и в случае с другими языками программирования, способ написания кода и выбор алгоритмов влияют на время выполнения JavaScript. В отличие от других языков программирования, ресурсы JavaScript ограничены, поэтому методы оптимизации важнее.
Характеристики производительности циклов for, while и do-while схожи, ни один из них не быстрее и не медленнее другого. Не используйте цикл for-in, если вы не перебираете объект с неизвестными свойствами. Лучший способ улучшить производительность цикла — уменьшить количество операций на итерацию и количество итераций цикла.
В общем, switch всегда быстрее, чем if-else, но это не всегда лучшее решение. Когда имеется много условий суждения, метод просмотра таблицы работает быстрее, чем if-else или switch.
Размер стека вызовов браузера ограничивает использование рекурсивных алгоритмов в JavaScript; ошибки переполнения стека препятствуют правильному выполнению другого кода. Если вы столкнулись с ошибкой переполнения стека, измените метод на итеративный алгоритм или используйте табуляцию, чтобы избежать дублирования работы.
Чем больше общий объем выполняемого кода, тем выше выигрыш в производительности от использования этих стратегий.
Строки и регулярные выражения
Интенсивные манипуляции со строками и поверхностно написанные регулярные выражения могут быть серьезными препятствиями для производительности, но советы, приведенные в этой главе, помогут вам избежать распространенных ошибок. Объединения массивов — единственный метод с приемлемой производительностью в IE7 и его более ранних версиях при объединении больших чисел или размеров строк. Если вас не интересует IE7 и его более ранние версии, объединение массивов — один из самых медленных способов объединения строк. Вместо этого используйте простые + и +=, чтобы избежать (создать) ненужных промежуточных строк.
Поиск с возвратом — это не только основная часть функции сопоставления регулярных выражений, но и частая причина, по которой регулярные выражения влияют на эффективность. Безудержный поиск с возвратом происходит, когда регулярное выражение должно быстро найти совпадение, но из-за какого-то специального действия с соответствующей строкой оно выполняется медленно и даже приводит к сбою браузера. Методы, позволяющие избежать этой проблемы, включают в себя создание взаимоисключающих смежных символов, отказ от вложенных квантификаторов, которые соответствуют одной и той же части строки несколько раз, и устранение ненужного поиска с возвратом путем повторного использования атомарного характера операций просмотра вперед.
Различные методы повышения эффективности регулярных выражений, помогают регулярным выражениям быстрее находить совпадения и тратить меньше времени на несовпадающие позиции (см. «Дополнительные способы повышения эффективности регулярных выражений»). Регулярные выражения не всегда являются лучшим инструментом для работы, особенно когда вы просто ищете строку текста.
Хотя существует много способов обрезать строку, использование двух простых регулярных выражений (одно для удаления начальных пробелов и другое для удаления пробелов в конце) обеспечивает краткий, кросс-браузерный метод, который работает для разного содержимого и длины строки. Цикл от конца строки до первого символа, не являющегося пробелом, или сочетание этого метода с регулярными выражениями в гибридном приложении — хорошая альтернатива, на которую меньше влияет общая длина строки.
Быстрый и отзывчивый пользовательский интерфейс
Обновления JavaScript и пользовательского интерфейса выполняются в одном процессе, и одновременно может выполняться только одно из них. Это означает, что пользовательский интерфейс не может реагировать на ввод во время выполнения кода JavaScript, и наоборот. Эффективное управление потоком пользовательского интерфейса заключается в том, чтобы убедиться, что JavaScript не работает слишком долго, чтобы это не повлияло на работу пользователя. Наконец, помните о следующих моментах:
- Время выполнения JavaScript не должно превышать 100 мс. Чрезмерное время выполнения приводит к заметным задержкам в обновлении пользовательского интерфейса, что отрицательно сказывается на общем взаимодействии с пользователем.
- Браузеры ведут себя по-разному в ответ на действия пользователя во время работы JavaScript. В любом случае, продолжительный JavaScript приведет к запутанному и бессвязному взаимодействию с пользователем.
- Таймеры можно использовать для планирования отложенного выполнения кода, что позволяет разбивать длительные сценарии на ряд более мелких задач.
Рабочие веб-потоки — это новая функция, предназначенная только для браузера, которая позволяет запускать код JavaScript вне потока пользовательского интерфейса без блокировки пользовательского интерфейса. Чем сложнее веб-приложение, тем важнее упреждающее управление потоком пользовательского интерфейса. Ни один код JavaScript не является настолько важным, чтобы он мог повлиять на взаимодействие с пользователем.
Ajax
Высокопроизводительный Ajax включает в себя: знание конкретных потребностей вашего проекта, выбор правильного формата данных и соответствующей технологии передачи.
Как форматы данных, обычный текст и HTML имеют очень строгие ограничения, но они экономят циклы процессора на стороне клиента. XML широко используется и обычно поддерживается, но он очень многословен и медленно обрабатывается. JSON легкий, быстро анализируется (как собственный код, а не строки) и такой же интерактивный, как XML. Пользовательские форматы с разделителями символов очень легковесны и являются самыми быстрыми при анализе больших наборов данных, но требуют дополнительного программирования для создания формата на стороне сервера и его анализа на стороне клиента.
XHR обеспечивает наиболее полный контроль и гибкость при запросе данных из доменов страниц, хотя и обрабатывает все входящие данные как одну строку, что потенциально может замедлить синтаксический анализ. С другой стороны, технология динамической вставки тегов сценариев позволяет выполнять запросы из разных источников и запускать JavaScript и JSON локально, хотя ее интерфейс недостаточно безопасен и не может читать заголовки или коды ответных сообщений. Multipart XHR может уменьшить количество запросов и может обрабатывать разные типы файлов в одном ответе, хотя он не может кэшировать полученные пакеты ответов. Маяки изображений — это самый простой и эффективный метод отправки данных. XHR также может отправлять большие объемы данных, используя метод POST.
В дополнение к этим форматам и методам передачи есть несколько рекомендаций, которые могут помочь еще больше ускорить Ajax:
- Сократите количество запросов, объедините их с файлами JavaScript и CSS или используйте MXHR.
- Сократите время загрузки страницы и используйте Ajax для извлечения небольшого количества важных файлов после загрузки остального содержимого страницы.
- Убедитесь, что ошибки кода не отображаются непосредственно пользователю, и обрабатывайте ошибки на стороне сервера.
- Узнайте, когда использовать надежную библиотеку Ajax, а когда написать собственный низкоуровневый код Ajax.
Ajax — это одна из самых больших областей улучшения потенциальной производительности вашего веб-сайта, поскольку многие веб-сайты активно используют асинхронные запросы и поскольку он обеспечивает решение многих не связанных между собой проблем, таких как загрузка слишком большого количества ресурсов. Креативное использование XHR такое разное, это не скучный и недружественный интерфейс, это синоним отзывчивости и эффективности, он не вызывает ненависти у пользователей, и всем, кто его увидит, он понравится.
практика программирования
JavaScript представляет некоторые уникальные проблемы с производительностью, связанные с тем, как вы организуете свой код. Веб-приложения становятся все более продвинутыми, содержат все больше и больше кода JavaScript, появляются шаблоны и антишаблоны. Пожалуйста, имейте в виду следующий опыт программирования:
- Избегайте двойной оценки, избегая конструкторов eval_r() и Function(). Кроме того, передайте аргументы функции вместо строковых аргументов в setTimeout() и setInterval().
- Литералы объектов и литералы массивов используются при создании новых объектов и массивов. Их быстрее создавать и инициализировать, чем непрямую форму.
- Избегайте повторения одной и той же работы. Используйте отложенную загрузку или условную предварительную загрузку, когда вам нужно определить браузеры.
- При выполнении математических вычислений рассмотрите возможность использования битовых операций, которые работают непосредственно с базовыми числами.
- Нативные методы всегда быстрее, чем что-либо, написанное на JavaScript. По возможности используйте нативные методы.
Создавайте и развертывайте высокопроизводительные приложения JavaScript
Процесс разработки и развертывания может оказать огромное влияние на приложения на основе JavaScript, и наиболее важные шаги следующие:
- Объединяйте файлы JavaScript, чтобы уменьшить количество HTTP-запросов
- Компактные файлы JavaScript с компрессором YUI
- Подавать файлы JavaScript в сжатом виде (в кодировке gzip)
- Делайте файлы JavaScript кэшируемыми, устанавливая заголовки ответа HTTP, и решайте проблемы с кэшированием, добавляя метки времени к именам файлов.
- Подавайте файлы JavaScript с помощью сети доставки контента (CDN), которая не только повышает производительность, но и управляет сжатием и кэшированием за вас.
Все эти шаги должны выполняться автоматически, либо с использованием общедоступных инструментов разработки, таких как Apache Ant, либо с использованием пользовательских инструментов разработки для реализации конкретных требований. Если вы заставите эти инструменты разработки работать на вас, вы сможете значительно повысить производительность веб-приложений или веб-сайтов, которые используют много кода JavaScript.
инструмент
Когда веб-страница или приложение замедляются, проанализируйте ресурсы, поступающие из Интернета, и проанализируйте производительность скрипта, чтобы вы могли сосредоточиться на тех областях, которые необходимо оптимизировать. Используйте сетевой анализатор для выявления узких мест в загрузке скриптов и других ресурсов страницы, что может помочь решить, какие скрипты нужно загружать отложенно, или для дальнейшего анализа. Здравый смысл подсказывает нам, что мы должны свести к минимуму количество HTTP-запросов и попытаться отложить загрузку скриптов, чтобы ускорить отрисовку страниц и предоставить пользователям лучший общий опыт. Используйте профилировщик производительности, чтобы найти медленные части вашего скрипта, проверьте, сколько времени занимает каждая функция и сколько раз функция вызывается, и используйте некоторые подсказки из самого стека вызовов, чтобы выяснить, где вы должны попытаться оптимизировать. Хотя затраченное время и количество вызовов обычно являются наиболее ценными моментами в данных, вам следует внимательно изучить процесс вызова функции и, возможно, обнаружить другие оптимизации. Эти инструменты больше не являются чем-то загадочным в средах программирования, в которых выполняется современный код. Используйте их перед началом работы по оптимизации, чтобы убедиться, что время разработки тратится на решение проблем.
😊Прошлые заметки и технические статьи
Чтобы систематически связывать передовые знания, я обычно использую интеллект-карты для записи заметок о прочитанном.githubБыл построен склад для хранения оригиналов этих ментальных карт и заметок о прочтении. Если вам также нравится использовать интеллект-карты для записи заметок о чтении, вы также можете поддерживать этот склад вместе со мной и можете оставить сообщение или WeChat (646321933), чтобы связаться со мной.
Интенсивное чтение «JavaScript, которого вы не знаете (Том 1)»
Интенсивное «Вы не знаете JavaScript» в объеме
Интенсив "на непрофессиональном языке Node.js"
Интенсивное чтение "Иллюстрированного HTTP"
алгоритм сборки мусора javascript
Что нужно знать о принципе реализации одностраничной маршрутизации
javascript реализует высокую имитацию