Разное

Оптимизировать js: Как оптимизировать JavaScript и ускорить загрузку сайта

03.07.2021

Содержание

Увеличиваем скорость работы сайта при помощи оптимизации JavaScript

Сайт может работать быстрее, если выполнены следующие рекомендации по оптимизации JS-кода. Если же этого не сделать, то сайт будет недостаточно быстро отображаться на стороне клиента.

Если какие-то скриптовые библиотеки не нужны на странице — их надо отключить. В процессе разработки часто подключаются те скрипты, которые потом не используются. Например, скрипты для отладки. Или те скрипты, которые собирались использовать, но потом передумали. Не надо заставлять пользователя загружать ненужный хлам.

Если без каких-то скриптов сайт функционален, то загрузку этих JS-скриптов осуществлять после отрисовки страницы (для этого надо поместить код в конец секции body). Некоторые скрипты нужны для создания эффектов, которые инициируются не сразу после загрузки страницы или их отложенная загрузка не влияет на первое впечатление от сайта. Автоматическое пролистывание слайдера или скрипт для сбора статистики посещений, например, легко могут быть инициированы уже после отрисовки страницы в браузере. Пусть лучше пользователь побыстрее увидит страницу, а не ждёт тратит при загрузке лишнее время ради того, чтобы через 5 секунд красиво перелистнулся рекламный баннер или чтобы его посчитали.

Загружайте скрипты с поддоменов, с других доменов или используйте CDN — даже у самых продвинутых браузеров файлы с одного домена загружаются в ограниченное число потоков. Если изображений, стилей и скриптов на странице достаточно много, то образуется очередь на загрузку данных. Количество используемых потоков лимитируется только для домена, поэтому если JS-файлы будут загружаться с другого домена (или поддомена), то их загрузка произойдёт быстрее за счёт параллельности.

Блокирующие скрипты не должны подгружаться с «непонятных» внешних доменов. Если внешний домен перестанет отвечать или станет отвечать с длительной задержкой, то будет «тормозить» весь ваш сайт, а пользователи будут «любоваться» белым экраном. Если используете внешние домены для скриптов, то убедитесь, что эти домены достаточно стабильны.

JS надо сжать, минимизировать и оптимизировать. Удаление пробелов, переносов строк, сокращение названий переменных и другие оптимизации значительно уменьшают размер файлов скриптов и ускоряют загрузку. При использовании сторонних библиотек — подключайте минимизированную версию в production-окружении. Для собственных скриптов используйте специальные библиотеки, сжимающие и оптимизирующие JavaScript, — UglifierJS, JSMin, Closure Compiler, YUI Compressor. При использовании агрессивных оптимизаций обязательно прочтите рекомендации для используемого компрессора и протестируйте работоспособность полученных файлов.

Совместно используемые скрипты должны быть объединены в один файл. Загрузка одного файла в 50 Kb осуществляется быстрее загрузки 10 файлов по 5 Kb, отдача таких файлов меньше грузит сервер, да и сжатие эффективнее работает на больших файлах.

Используйте GZIP для сжатия данных. Современные браузеры поддерживают обработку сжатых данных. Оптимальный способ — предварительное сжатие используемых скриптов на максимальном уровне компрессии и отдача веб-сервером предварительно сжатых файлов. Сжатие «на лету» нагружает сервер, поэтому его на нагруженных проектах лучше не использовать.

Кэшируйте скрипты на стороне клиента — не заставляйте пользователей многократно скачивать один и тот же скрипт: используйте соответствующие заголовки в ответе веб-сервера (Expires или Cache-Control max-age, Last-Modified или ETag).

Не используйте большие библиотеки без надобности — например, ради какого-то элементарного эффекта на главной странице сайта не стоит на всех страницах подключать jQuery. Если для реализации всей интерактивности сайта может хватить 30 строчек простого js-кода, то использование объёмной библиотеки просто нерационально.

Про оптимизацию javascript кода (часть 1)

Нижеследующее — размышления после профилирования нескольких скриптов, и поисков быстрого кода.

Все больше статей по клиентской оптимизации появляется. Но проблема в том, что практики из статей начинают применять молодые разработчики без понимания причин. Зачастую авторы статей рассказывают как они решили свою проблему.

Видел людей, которые всерьез спорят про быстрые и медленные циклы, и использование бинарных операторов для ускорения. На практике потребность в подобных манипуляциях встречается очень редко. Эти споры процветают, пишутся тесты. Правда ребята забывают, что самым узким местом клиентского JS является DOM.

При переписывании цикла на более быструю версию, кеширование переменных (для более быстрого поиска по областям видимости) скрипт можно ускорить на 5%, ну на 10%. При этом произойдет
потеря в читаемости исходного кода, его понимании.

Но ситуация с оптимизацией — палка о трех концах. Второй конец: браузерная оптимизация. Например пример двух циклов:

 // 1
for (var i = 0; i 

Вторая версия чуть более многословна, но быстрее первой. Третья менее многословна, но не совсем понятна слету (проход по массиву в обратном порядке не естественен для понимания).

На практике интерпретаторы сами оптимизируют код циклов, и большой разницы в скорости отработки в современном браузере профилирование не покажет, не говоря уже о пользовательских ощущениях. Какая разница, скрипт выполнится за 10мс или 9мс.

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

А вот третий конец — это DOM. Обновление одного узла в DOM-e ведет за собой каскад телодвижений со стороны браузера: обновление свойств children, parentNode, nextSibling у нод, которые «цепляются» этим изменением, обновление liveCollections, триггер repaint и reflow, очистка памяти, если использован innerHTML, то еще дополнительный парсинг текста в DOM модель.

На фоне такого количества действий низкоуровневые оптимизации меркнут. Слишком просто одним лишним обращением к DOM-у свести все оптимизации на нет.

Узких мест в DOM-е множество. Самые тяжелые — обновление: добавление и удаление узлов. При том время отработки одного и того же кода зависит от общей сложности DOM дерева, максимальной вложенности, количества таблиц стилей и количества правил. Это означает, что один и тот же способ оптимизации даст различный прирост, в зависимости от сложности страницы.

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

Снова повторяется история с циклами: не стоит усложнять исходны код, подстраивая его под браузер. Пусть этим занимаются браузеростроители.

Я к чему веду: смысла в особой оптимизации кода нет. Самый разумный подход — написать код как есть, структурировать и сделать его читаемым и понятным. И только если профилирование покажет необходимость оптимизаций, начать именно с оптимизации работы с DOM.

Оптимизация node.js приложения

Дано: старое http node.js приложение и возросшая нагрузка на него.
Стандартные решения проблемы: докинуть серверов, все переписать с 0, оптимизировать уже написанное.
Давайте попробуем пойти путем оптимизации и разобраться, как можно найти и улучшить слабые места приложения. А быть может ускориться не трогая ни строчки кода 🙂

Всех заинтересованных добро пожаловать под кат!

Для начала определимся с методикой тестирования производительности.
Нас будет интересовать количество обслуженных запросов за 1 секунду: rps.
Запускать будем приложение в режиме 1 воркера (1 процесса), замеряя производительность старого кода и кода с оптимизациями — абсолютная производительность не важна, важна сравнительная производительность.


В типичном приложении с множествами разных роутов логично сначала найти самые загруженные запросы, на обработку которых тратится большая часть времени. Утилы вида request-log-analizer или множество подобных позволят извлечь эту информацию из логов.
С другой стороны, можно взять реальный список запросов и пулять их все (например с помощью yandex-tank-а) — получим достоверный профиль нагрузки.
Но делая множество итераций оптимизации кода, куда удобнее использовать более простой и быстрый инструмент и один конкретный тип запросов (а после оптимизации одного запроса изучать следующий, и т.д.). Мой выбор — wrk. Тем более что в моем случае количество роутов не велико — проверить все по одному не сложно.

Сразу надо оговорится, что в плане блокирующих запросов, ожидания БД и т.п. приложение уже оптимизировано, все упирается в cpu: при тестах воркер потребляет 100% cpu.

На продашен серверах используется node.js версии 6 — с неё и начнем:
Requests/sec: 1210

Пробуем на 8й ноде:
Requests/sec: 2308
10я нода:
Requests/sec: 2590

Разница очевидна. Ключевую роль тут играет обновление версии v8 — множество плохо оптимизирующегося v8 кода осталось в прошлом. И чтобы не бороться с ветряными мельницами исчезнувшими в node.js v8 — лучше сразу обновиться, а потом уже заниматься оптимизацией кода.

Переходим собственно к поиску узких мест: на мой взгляд, лучший инструмент для этого — flamegraph. И с появлением проекта 0x получить flamegraph стало очень просто — запускам 0x вместо node: 0x -o ваш_скрип.js, делаем тест, останавливаем скрипт, смотрим результат в браузере.

Примерно так выглядит flamegraph тестируемого кода до оптимизаций:

Внизу фильтры, оставляем app, deps — только код приложения и сторонних модулей.

Чем шире полоска — тем больше времени потрачено на выполнения этой функции (включая вложенные вызовы).

Разбираться будем с центральной, самой большой частью.
В первую очередь подсвечиваем неоптимизированные функции. У меня в приложении таких нашлось немного.
Далее, верхние функции — типичные кандидаты на оптимизацию. Остальные же функции выстроились горкой с относительно равномерными ступеньками — каждая функция вкладывает небольшую долю задержек, явного лидера нет.

Дальше возможен простой алгогритм действий: оптимизировать самые широкие функции, переходя от одной к другой. Но я выбрал другой подход: оптимизировать начиная от точки входа в приложения (обработчик запроса в http.createServer). В конце исследуемой функции вместо вызова следующих функций я завершаю обработку запроса, отвечая ответом-пустышкой, и изучаю производительность именно этой функции. После её оптимизации ответ-пустышка перемещается дальше по стеку вызовов к следующей функции и т.д.

Удобное следствие такого подхода: можно видеть rps в идеальных условиях (при работающей только одной стартовой функцией rps близок к максимальному rps-у hellow world node.js приложения), и при дальнейшем перемещении заглушки-ответа вглубь приложения наблюдать вклад исследуемой функции в падение производительности в rps-ах.

Итак, оставляем только стартовую функцию, получаем:
Requests/sec:

16176

Подключая фильтры core, v8 можно увидеть, что практически вся исследуемая функция состоит из отправки ответа, логгирования и других слабо оптимизируемых вещей — едем дальше.

Переходим к следующей функции:
Requests/sec: 16111
Ничего не изменилось — погружаемся дальше:
Requests/sec: 13330

Наш клиент! Видно что задействованная функция getByUrl занимает значимую часть стартовой функции — что хорошо коррелирует с проседанием rps.
Смотрим внимательно что в ней происходит (включаем core, v8):

много чего происходит… курим код, оптимизируем:

for (var i in this.data) {
  if (this[i]._options.regexp_obj.test(url)) return this[i];
}
return null;

превращаем в
let result = null;
for (let i=0; i<this.length && !result; i++) {
  if (this[i]._options.regexp_obj.test(url)) result = this[i];
}

И получаем
Requests/sec: 16015

Визуально функция «сдулась» и занимает значительно меньшую долю от стартовой функции.
В детальной информации по функции так же все значительно упростилось:

Идем дальше, к следующей функции
Requests/sec: 13316

В этой функции много array функций и, несмотря на существенное ускорение в последних версиях node.

js, они все еще медленней простых циклов: меняем [].map и filter. на обычный for и получаем
Requests/sec: 15067

И так раз за разом, для каждой следующей функции.
Еще несколько пригодившихся оптимизаций: для хешей с динамически изменяемым набором ключей new Map() может быть на 40% быстрее обычного {};
Math.round(el*100)/100 в 2 раза быстрее чем toFixed(2).
В flamegraph-е для core и v8 функций можно увидеть как и малопонятные записи, так и вполне говорящие StringPrototypeSplit или v8::internal::Runtime_StringToNumber, и, если это значимая часть выполнения кода, попытаться оптимизировать, например просто переписать код, не выполняющий эти операции.
Например, замена split на несколько вызовов indexOf и substring может давать двойной выигрыш в производительности.

Отдельная большая и сложная тема — jit оптимизация, а вернее деоптимизированные функции.
При наличии большой доли таких функций надо будет разбираться и с ними.
Тут может помочь вдумчивое изучение вывода node —trace_file_names —trace_opt_verbose —trace-deopt —trace_opt

Например, строчки вида
deoptimizing (DEOPT soft): begin 0x2bcf38b2d079 <JSFunction getTime… Insufficient type feedback for binary operation привели к строчке
return val >= 10? val: ‘0’+val;
Замена на
return (val >= 10? »: ‘0’)+val;
исправила ситуацию.

Для старого v8 движка есть достаточно много информации по причинам и способах борьбы с деоптимизацией функций:
github.com/P0lip/v8-deoptimize-reasons — список,
www.netguru.co/blog/tracing-patterns-hinder-performance — разбор типовых причин,
www.html5rocks.com/en/tutorials/speed/v8 — про оптимизации для v8, думаю справедливо и для текущего движка v8.
Но многие из проблем уже не актуальны для нового v8.

Так или иначе, после всех оптимизаций удалось получить Requests/sec: 9971, т.е. ускорится примерно в 2 раза за счет перехода на свежую версию node. js, и еще в 4 раза за счет оптимизации кода.
Надеюсь, этот опыт будет полезен кому-нибудь еще.

Оптимизация скриптов и стилей сайта

Частая проблема неоптимизированных сайтов — это множество дополнительно подключаемых файлов. Интересно, что периодически я встречал ситуацию, что эти файлы даже не использовались. Они просто впустую нагружали сайт. В этой статье поговорим о скриптах (.js) и стилях (.css).

Оптимизация js скриптов

Сразу скажу, что оптимизация не должна вредить полноценной работе сайта. Не нужно лишать себя полезных сервисов, типа веб-аналитики или онлайн-чата.

В первую очередь, нужно сделать анализ того, используются ли каждый подключаемый скрипт на сайте. Во вторую очередь, нужно проверить, используются ли скрипты на всех страницах или только на одной/нескольких. Если пара скриптов используется только на главной странице, то не нужно их загружать на всех других страницах сайта. В любой CMS можно создать несколько шаблонов раздела head, которые будут отличаться списком подключаемых файлов.

Итак, вы убедились, что скрипты только нужные, а загружаются они только на нужных страницах. Далее смотрим внутри этих файлов. Сжат ли там код? Если нет, то простое сокращение ненужных символов может сэкономить десятки килобайт. Можно это сделать вручную (например, https://jscompress.com/), а можно с помощью дополнительных сервисов, которые сжимают код всех подключенных js файлов автоматически (например, в Modx это MinifyX).

Следующий этап оптимизации — проверить место подключения js файлов. Чем выше в шаблоне сайта подключение скриптов, тем сильнее их загрузка откладывает отображение основного контента сайта. Не всем скриптам обязательно подключение в разделе head, некоторые можно перенести в самый конец документа перед закрывающим тегом body.

Ещё один приём — это использование асинхронной загрузки скриптов, которая не блокирует загрузку прочих файлов сайта. Опять же, не все скрипты могут работать в таком режиме. Каждый нужно проверять отдельно.

<script async src="/путь-к-файлу.js"></script>

Каждый отдельный скрипт загружается с помощью отдельного запроса. Мы знаем, что чем меньше запросов, тем быстрее пройдёт загрузка всех файлов. Соответственно, можно объединить все скрипты в один или несколько. Сначала разбиваем скрипты по типам: нужно ли им быть в разделе head или можно их разместить в конце документа, могут ли скрипты загружаться асинхронно или нет. После объединения у вас может остаться пара скриптов вместо пары десятков.

Важно соблюдать последовательность объединения. Если у вас jquery плагин, то его код должен идти после самого jquery. Объединить файлы можно вручную, но лучше делать это автоматически (например, в Modx это может сделать плагин MinifyX).

Оптимизация css стилей

Также сначала проверяем необходимость подключения конкретных стилей. Если вы используете библиотеки типа Bootstrap, то выбирайте только необходимые стили, не нужно загружать то, чем вы не пользуетесь.

Принципы оптимизации загрузки css файлов аналогичны js:

  • Загружаем нужны стили на нужных страницах
  • Сжимаем код
  • Объединяем в один файл

Можно выделить самые важные стили (описание 10-100 самых базовых элементов) и встроить их (inline) в код страницы. Google рекомендует это делать для ускорения прорисовки шаблона/структуры страницы.

Все оптимизации css стилей также лучше автоматизировать с помощью плагинов.

Вышеперечисленные базовые действия могут существенно ускорить загрузку страниц. То есть вы один раз проведёте эту работу, а количество запросов, которые требуются для загрузки сайта может сократиться на несколько десятков. Общий размер всех js и css файлов можно сократить в несколько раз после сжатия.

К сожалению, многие CMS (WordPress, Битрикс) идут с шаблонами, которые изначально сделаны так, как будто они специально хотят замедлить ваш сайт. Оптимизируйте подключаемые js и css файлы — это обязательный этап работы по ускорению скорости загрузки сайта.

Автор: Александр Дергунов
Дата публикации: 29.12.2019 г.

Как оптимизировать CSS- и JS-файлы в WordPress?

👍 Научим создавать сайты на WordPress бесплатно за 11 уроков. Подробнее →

Каждый современный веб-сайт для своей работы использует CSS- и JS-файлы. Первые используются для построения разметки внешнего вида, а JS – это JavaScript-скрипты, отвечающие за расширение функционала.

Для чего оптимизировать CSS- и JS-файлы?

В рамках оптимизации (увеличения скорости) работы сайта веб-мастера стараются уменьшить размер файлов обеих типов. Это имеет смысл делать, если на сайте одновременно подключаются несколько таких файлов. В процессе эволюции сайтостроения была придумана технология минификации, которая позволяет уменьшить размеры файлов скриптов за счет удаления в них комментариев, лишних пробелов, переносов строк.

В арсенале WordPress имеется множество бесплатных плагинов, поддерживающих и успешно применяющих эту технологию. Одним их таких есть AssetsMinify.

Плагин AssetsMinify

После установки и активации плагина в админ-панели WordPress появляется страница настроек плагина, на которую можно попасть, выполнив переход Настройки -> AssetsMinify.

Тут можно сделать основные настройки. Во-первых, для включения работы плагина следует отметить галочкой пункт Use Compass. Дальше для оптимизации стилей нужно отметить пункт Compress styles, а для скриптов – Compress scripts. Следующим шагом идет включение пункта Async attribute on footer’s script tag, отвечающего за асинхронную загрузку файлов, которая позволяет Вашему веб-браузеру грузить основной код страницы, не дожидаясь загрузки css- и js-скриптов.

После выставления всех настроек необходимо нажать кнопку Save. В итоге, каждый раз при обращении к страницам Вашего сайта, скрипты и стили будут загружатся в уже сжатом виде, что в итоге довольно сильно может ускорить работу сайта в целом.

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

Мне нравитсяНе нравится

Если Вам понравилась статья — поделитесь с друзьями

Оптимизация производительности – React

React использует несколько умных подходов для минимизации количества дорогостоящих DOM-операций, необходимых для обновления пользовательского интерфейса. Для многих приложений, использование React приведёт к быстрому пользовательскому интерфейсу без особых усилий по оптимизации производительности. Тем не менее, существует несколько способов ускорить React-приложение.

Использование продакшен-сборки

Если вы испытываете проблемы с производительностью в React-приложении, убедитесь в том, что вы проводите тесты с настройками минифицированной продакшен-сборки.

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

Если вы не уверены в том, что процесс сборки настроен правильно, вы можете проверить это, установив React Developer Tools for Chrome. Если вы посетите сайт, работающий на React в продакшен-режиме, иконка будет с чёрным фоном:

Если вы посетите сайт с React в режиме разработки, у иконки будет красный фон:

Как правило, режим разработки используется во время работы над приложением, а продакшен-режим при деплое приложения для пользователей.

Ниже вы можете найти инструкцию по сборке своего приложения для продакшена.

Create React App

Если ваш проект сделан с помощью Create React App, выполните:

Эта команда создаст продакшен-сборку вашего приложения в папке build/ вашего проекта.

Помните, что это необходимо только перед деплоем на продакшен. Для обычной разработки используйте npm start.

Однофайловые сборки

Мы предлагаем готовые для продакшена версии React и React DOM в виде отдельных файлов:

<script src="https://unpkg. com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>

Помните, что для продакшена подходят только те файлы, которые заканчиваются на .production.min.js.

Brunch

Для наиболее эффективной продакшен-сборки с Brunch, установите плагин terser-brunch.

# В случае использования npm
npm install --save-dev terser-brunch

# В случае использования Yarn
yarn add --dev terser-brunch

Затем, для создания продакшен сборки, добавьте флаг -p к команде build:

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

Browserify

Для наиболее эффективной продакшен-сборки с Browserify, установите несколько плагинов:

# В случае использования npm
npm install --save-dev envify terser uglifyify

# В случае использования Yarn
yarn add --dev envify terser uglifyify

При создании продакшен-сборки, убедитесь, что вы добавили эти пакеты для преобразования (порядок имеет значение):

  • Плагин envify обеспечивает правильную среду для сборки. Сделайте его глобальным (-g).
  • Плагин uglifyify удаляет импорты, добавленные при разработке. Сделайте его глобальным (-g).
  • Наконец, полученная сборка отправляется к terser для минификации (прочитайте, зачем это нужно).

К примеру:

browserify ./index.js \
  -g [ envify --NODE_ENV production ] \
  -g uglifyify \
  | terser --compress --mangle > ./bundle.js

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

Rollup

Для наиболее эффективной продакшен-сборки с Rollup, установите несколько плагинов:


npm install --save-dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-terser


yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-terser

При создании продакшен-сборки, убедитесь, что вы добавили эти плагины (порядок имеет значение):

  • Плагин replace обеспечивает правильную среду для сборки.
  • Плагин commonjs обеспечивает поддержку CommonJS в Rollup.
  • Плагин terser сжимает и оптимизирует финальную сборку.
plugins: [
  
  require('rollup-plugin-replace')({
    'process.env.NODE_ENV': JSON.stringify('production')
  }),
  require('rollup-plugin-commonjs')(),
  require('rollup-plugin-terser')(),
  
]

Полный пример настройки можно посмотреть здесь.

Помните, что это нужно делать только для продакшен-сборки. Вам не следует использовать плагин terser или плагин replace со значением 'production' в процессе разработки, потому что это скроет вспомогательные предупреждения React и замедлит процесс сборки.

webpack

Примечание:

Если вы используете Create React App, пожалуйста, следуйте инструкциям выше.
Этот раздел подойдёт для тех, кто самостоятельно настраивает webpack.

Webpack 4.0 и выше по умолчанию минифицирует код в продакшен-режиме.

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  mode: 'production',
  optimization: {
    minimizer: [new TerserPlugin({  })],
  },
};

Вы можете узнать об этом больше в документации webpack.

Помните, что это нужно делать только для продакшен-сборки. Вам не стоит использовать TerserPlugin в процессе разработки, потому что тогда скроются вспомогательные предупреждения React и замедлится процесс сборки.

Анализ производительности компонентов с помощью вкладки Chrome «Performance»

В режиме разработки вы можете видеть как компоненты монтируются, обновляются и размонтируются с помощью инструментов производительности в браузерах, которые их поддерживают. Например:

Для того, чтобы сделать это в Chrome:

  1. Временно отключите все расширения Chrome, особенно React DevTools. Они могут существенно исказить результаты!
  2. Убедитесь, что вы запускаете приложение в режиме разработки.
  3. Откройте в инструментах разработчика Chrome вкладку Performance и нажмите Record.
  4. Выполните действия, которые вы хотите проанализировать на производительность. Не записывайте более 20 секунд, иначе Chrome может зависнуть.
  5. Остановите запись.
  6. События React будут сгруппированы под меткой User Timing.

Для более детального ознакомления, посмотрите эту статью от Бена Шварца (Ben Schwarz).

Обратите внимание, что результаты являются относительными и в продакшене рендеринг компонентов будет быстрее. Всё же это должно помочь вам понять, когда какой-то пользовательский компонент обновляется по ошибке, а также как глубоко и часто обновляется пользовательский интерфейс.

В настоящее время Chrome, Edge и IE единственные браузеры, которые поддерживают данную возможность, но мы используем стандарт User Timing API, поэтому ожидайте, что больше браузеров добавят его поддержку.

Пакеты react-dom версии 16.5+ и react-native версии 0.57+ предоставляют расширенные возможности анализа производительности в режиме разработки с помощью инструментов разработчика React Profiler. Обзор профайлера можно найти в посте блога «Введение в React Profiler». Пошаговое видео-руководство также доступно на YouTube.

Если вы ещё не установили инструменты разработчика React, вы можете найти их здесь:

Примечание

Профилирование продакшен-пакета для react-dom также доступно как react-dom/profiling. Подробнее о том, как использовать этот пакет, читайте на fb.me/react-profiling

Виртуализация длинных списков

Если ваше приложение рендерит длинные списки данных (сотни или тысячи строк), мы рекомендуем использовать метод известный как «оконный доступ». Этот метод рендерит только небольшое подмножество строк в данный момент времени и может значительно сократить время, необходимое для повторного рендера компонентов, а также количество создаваемых DOM-узлов.

react-window и react-virtualized — это популярные библиотеки для оконного доступа. Они предоставляют несколько повторно используемых компонентов для отображения списков, сеток и табличных данных. Если вы хотите использовать что-то более специфическое для вашего конкретного случая, то вы можете создать собственный компонент с оконным доступом, как это сделано в Twitter.

Избежание согласования

React создаёт и поддерживает внутреннее представление отображаемого пользовательского интерфейса. Оно также включает React-элементы возвращаемые из ваших компонентов. Это представление позволяет React избегать создания DOM-узлов и не обращаться к текущим без необходимости, поскольку эти операции могут быть медленнее, чем операции с JavaScript-объектами. Иногда его называют «виртуальный DOM», но в React Native это работает точно так же.

Когда изменяются пропсы или состояние компонента, React решает нужно ли обновление DOM, сравнивая возвращённый элемент с ранее отрендеренным. Если они не равны, React обновит DOM.

Несмотря на то, что React обновляет только изменённые DOM-узлы, повторный рендеринг всё же занимает некоторое время. В большинстве случаев это не проблема, но если замедление заметно, то вы можете всё ускорить, переопределив метод жизненного цикла shouldComponentUpdate, который вызывается перед началом процесса ререндеринга. Реализация этой функции по умолчанию возвращает true, указывая React выполнить обновление:

shouldComponentUpdate(nextProps, nextState) {
  return true;
}

Если вы знаете ситуации, в которых ваш компонент не нуждается в обновлении, вы можете вернуть false из shouldComponentUpdate, чтобы пропустить весь процесс рендеринга, включая вызов render() и так далее ниже по иерархии.

В большинстве случаев вместо того, чтобы писать shouldComponentUpdate() вручную, вы можете наследоваться от React.PureComponent. Это эквивалентно реализации shouldComponentUpdate() с поверхностным сравнением текущих и предыдущих пропсов и состояния.

shouldComponentUpdate в действии

Вот поддерево компонентов. Для каждого из них SCU указывает что возвратил shouldComponentUpdate, а vDOMEq указывает эквивалентны ли отрендеренные React элементы. Наконец, цвет круга указывает требуется ли согласовать компонент или нет.

Поскольку shouldComponentUpdate возвратил false для поддерева с корнем C2, React не пытался отрендерить C2, следовательно не нужно вызывать shouldComponentUpdate на C4 и C5.

Для C1 и C3 shouldComponentUpdate возвратил true, поэтому React пришлось спуститься к листьям и проверить их. Для C6 shouldComponentUpdate вернул true, и поскольку отображаемые элементы не были эквивалентны, React должен был обновить DOM.

Последний интересный случай — C8. React должен был отрисовать этот компонент, но поскольку возвращаемые им React-элементы были равны ранее предоставленным, ему не нужно обновлять DOM.

Обратите внимание, что React должен был делать изменения только для C6. Для C8 этого удалось избежать сравнением отрендеренных React-элементов, а для поддеревьев C2 и C7 даже не пришлось сравнивать элементы, так как нас выручил shouldComponentUpdate и render не был вызван.

Примеры

Если единственный случай изменения вашего компонента это когда переменная props.color или state.count изменяются, вы могли бы выполнить проверку в shouldComponentUpdate следующим образом:

class CounterButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this. state.count !== nextState.count) {
      return true;
    }
    return false;
  }

  render() {
    return (
      <button
        color={this.props.color}
        onClick={() => this.setState(state => ({count: state.count + 1}))}>
        Счётчик: {this.state.count}
      </button>
    );
  }
}

В этом коде shouldComponentUpdate — это простая проверка на наличие каких-либо изменений в props.color или state.count. Если эти значения не изменяются, то компонент не обновляется. Если ваш компонент стал более сложным, вы можете использовать аналогичный паттерн «поверхностного сравнения» между всеми полями props и state, чтобы определить должен ли обновиться компонент. Этот механизм достаточно распространён, поэтому React предоставляет вспомогательную функцию для работы с ним — просто наследуйтесь от React.PureComponent. Поэтому, следующий код — это более простой способ добиться того же самого эффекта:

class CounterButton extends React. PureComponent {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  render() {
    return (
      <button
        color={this.props.color}
        onClick={() => this.setState(state => ({count: state.count + 1}))}>
        Счётчик: {this.state.count}
      </button>
    );
  }
}

В большинстве случаев вы можете использовать React.PureComponent вместо написания собственного shouldComponentUpdate. Но он делает только поверхностное сравнение, поэтому его нельзя использовать, если пропсы и состояние могут измениться таким образом, который не сможет быть обнаружен при поверхностном сравнении.

Это может стать проблемой для более сложных структур данных. Например, вы хотите, чтобы компонент ListOfWords отображал список слов, разделённых через запятую, с родительским компонентом WordAdder, который позволяет кликнуть на кнопку, чтобы добавить слово в список. Этот код работает неправильно:

class ListOfWords extends React. PureComponent {
  render() {
    return <div>{this.props.words.join(',')}</div>;
  }
}

class WordAdder extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      words: ['словцо']
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    
    const words = this.state.words;
    words.push('словцо');
    this.setState({words: words});
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick} />
        <ListOfWords words={this.state.words} />
      </div>
    );
  }
}

Проблема в том, что PureComponent сделает сравнение по ссылке между старыми и новыми значениями this.props.words. Поскольку этот код мутирует массив words в методе handleClick компонента WordAdder, старые и новые значения this.props.words при сравнении по ссылке будут равны, даже если слова в массиве изменились. ListOfWords не будет обновляться, даже если он содержит новые слова, которые должны быть отрендерены.

Сила иммутабельных данных

Лучший способ решения этой проблемы — избегать мутирования значений, которые вы используете как свойства или состояние. К примеру, описанный выше метод handleClick можно переписать с помощью concat следующим образом:

handleClick() {
  this.setState(state => ({
    words: state.words.concat(['словцо'])
  }));
}

ES6 поддерживает синтаксис расширения для массивов, который поможет сделать это проще. Если вы используете Create React App, то этот синтаксис доступен там по умолчанию.

handleClick() {
  this.setState(state => ({
    words: [...state.words, 'словцо'],
  }));
};

Таким же образом вы можете переписать код, который мутирует объекты. К примеру, мы имеем объект с именем colormap и хотим написать функцию, которая изменяет colormap. right на 'blue'. Мы могли бы написать:

function updateColorMap(colormap) {
  colormap.right = 'blue';
}

Чтобы написать это без мутирования исходного объекта, мы можем использовать метод Object.assign:

function updateColorMap(colormap) {
  return Object.assign({}, colormap, {right: 'blue'});
}

Функция updateColorMap теперь возвращает новый объект, вместо того, чтобы мутировать исходный. Метод Object.assign входит в ES6 и требует полифила.

Синтаксис расширения свойств объекта упрощает обновление объектов без мутаций:

function updateColorMap(colormap) {
  return {...colormap, right: 'blue'};
}

Этот синтаксис был добавлен в JavaScript в ES2018.

Если вы используете Create React App, то Object.assign и синтаксис расширения объектов доступны вам по умолчанию.

При работе с глубоко вложенными объектами, постоянное их обновление может запутать. Если вы столкнулись с такой проблемой, обратите внимание на Immer или immutability-helper. Эти библиотеки позволяют писать хорошо читаемый код, не теряя преимуществ иммутабельности.

Оптимизация canvas — Интерфейсы веб API

Элемент <canvas> является одним из наиболее широко используемых инструментов для рендеринга 2D-графики в Интернете. Однако когда веб-сайты и приложения используют Canvas API на пределе его возможностей, производительность начинает снижаться. В этой статье приводятся предложения по оптимизации использования элемента canvas для обеспечения хорошей работы графики.

Ниже приведён сборник советов по улучшению производительности canvas.

Предварительно отрисуйте похожие примитивы или повторяющиеся объекты на offscreen canvas

Если вы повторяете одни и те же операции рисования в каждом кадре анимации, рассмотрите возможность их выгрузки на offscreen canvas. Затем вы можете визуализировать закадровое изображение на свой основной canvas так часто, как это необходимо, без необходимости повторять шаги, необходимые для его генерации.

myCanvas.offscreenCanvas = document.createElement('canvas');
myCanvas.offscreenCanvas.width = myCanvas.width;
myCanvas.offscreenCanvas.height = myCanvas.height;

myCanvas.getContext('2d').drawImage(myCanvas.offScreenCanvas, 0, 0);

Избегайте координат с плавающей точкой и используйте вместо них целые числа

Субпиксельный рендеринг происходит при рендеринге объектов на canvas без целых значений.

ctx.drawImage(myImage, 0.3, 0.5);

Это заставляет браузер выполнять дополнительные вычисления для создания эффекта сглаживания. Чтобы избежать этого, обязательно округлите все координаты, используемые в вызовах drawImage(), например, с помощью Math.floor().

Не масштабируйте изображения в

drawImage

При загрузке кешируйте изображения разных размеров на offscreen canvas, а не постоянно масштабируйте их в drawImage().

Используйте несколько слоёв canvas для сложных сцен

Вы можете обнаружить, что некоторые объекты в вашем приложении нужно часто перемещать или менять, в то время как другие остаются относительно статичными. Возможной оптимизацией в этой ситуации является наложение ваших элементов с использованием нескольких элементов <canvas>.

Например, допустим, у вас есть игра с пользовательским интерфейсом наверху, геймплеем в середине и статическим фоном внизу. В этом случае вы можете разбить свою игру на три слоя <canvas>. Пользовательский интерфейс будет меняться только при изменении пользователем, слой с игровым процессом будет меняться с каждым новым кадром, а фон останется в основном неизменным.

<div>
  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>
</div>

<style>
  #stage {
    width: 480px;
    height: 320px;
    position: relative;
    border: 2px solid black;
  }

  canvas { position: absolute; }
  #ui-layer { z-index: 3; }
  #game-layer { z-index: 2; }
  #background-layer { z-index: 1; }
</style>

Используйте простой CSS для больших фоновых изображений

Если у вас есть статическое фоновое изображение, вы можете нарисовать его на простом элементе <div>, используя свойство CSS background, и расположить его под canvas. Это сведёт на нет необходимость рендеринга фона на canvas на каждом тике.

Масштабирование холста с использованием CSS-преобразований

CSS-преобразования быстрее, поскольку они используют графический процессор. В идеале, не стоит не масштабировать canvas, или можно использовать меньший canvas и увеличивать его при необходимости, но не уменьшать.

var scaleX = window.innerWidth / canvas.width;
var scaleY = window.innerHeight / canvas.height;

var scaleToFit = Math.min(scaleX, scaleY);
var scaleToCover = Math.max(scaleX, scaleY);

stage.style.transformOrigin = '0 0'; 
stage.style.transform = 'scale(' + scaleToFit + ')';

Отключите прозрачность

Если ваше приложение использует canvas и не нуждается в прозрачном фоне, установите для параметра alphaзначение false при создании контекста рисования с помощью HTMLCanvasElement.getContext(). Эта информация может использоваться браузером для оптимизации рендеринга.

var ctx = canvas.getContext('2d', { alpha: false });

Другие советы

  • Объединяйте запросы к canvas. Например, рисуйте одну ломанную линию вместо нескольких отдельных линий.
  • Избегайте ненужных изменений состояния canvas.
  • Отображайте только изменения экрана, а не заново перерисовывайте.
  • По возможности избегайте свойства shadowBlur (en-US).
  • Избегайте рендеринга текста, когда это возможно.
  • Попробуйте разные способы очистки canvas ((clearRect(), или fillRect(), или изменение размера canvas).
  • С анимациями используйте window.requestAnimationFrame() вместо window.setInterval() (en-US).
  • Будьте осторожны с тяжёлыми физическими библиотеками.

Оптимизация запуска JavaScript | Основы веб-технологий

Eng Менеджер по связям с веб-разработчиками

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

Сеть

Когда большинство разработчиков думают о стоимости JavaScript, они думают об этом в сроки загрузки и стоимость исполнения . Отправка большего количества байтов JavaScript по проводу занимает больше времени, чем медленнее соединение пользователя.

Это может быть проблемой даже в странах первого мира, поскольку эффективная сеть тип подключения , который имеет пользователь, на самом деле может не быть 3G, 4G или Wi-Fi. Вы можете быть на кофейня Wi-Fi, но подключена к сотовой точке доступа со скоростью 2G.

Вы можете уменьшить стоимость сетевой передачи JavaScript через:

  • Только отправка кода, необходимого пользователю .
    • Используйте разделение кода для взлома разберитесь в своем JavaScript в том, что критично, а что нет. Сборщики модулей как поддержка webpack расщепление кода.
    • Ленивая загрузка некритичного кода.
  • Минификация
  • Сжатие
    • Как минимум, используйте gzip для сжатия текстовых ресурсов.
    • Рассмотрите возможность использования Бротли ~ q11. Бротли превосходит gzip по степени сжатия. Это помогло CertSimple сэкономить 17% от размера сжатых байтов JS и сохранения в LinkedIn 4% на время их загрузки.
  • Удаление неиспользуемого кода .
  • Код кэширования для минимизации сетевых отключений.
    • Использовать HTTP кеширование чтобы браузеры эффективно кэшировали ответы. Определить оптимальный время жизни для скриптов (max-age) и токены проверки (ETag), чтобы избежать передача неизмененных байтов.
    • Кэширование
    • Service Worker может сделать сеть вашего приложения устойчивой и дать вам жадный доступ к таким функциям, как код V8 кеш.
    • Используйте долгосрочное кэширование, чтобы избежать повторной выборки ресурсов, которые не измененный. При использовании Webpack см. Имя файла хеширование.

Синтаксический анализ / компиляция

После загрузки одна из самых больших затрат JavaScript — это время для JS engine для разобрать / скомпилировать этот код. В Chrome DevTools, синтаксический анализ и компиляция являются частью желтого Время «написания сценария» на панели «Производительность».

Вкладки Bottom-Up и Call Tree показывают точное время синтаксического анализа / компиляции:

Хром Панель DevTools «Производительность»> «Снизу вверх». При включенной статистике вызовов V8 мы можно увидеть время, затраченное на такие этапы, как Parse и Compile. Примечание. Поддержка панели производительности для статистики вызовов времени выполнения в настоящее время является экспериментальной. Чтобы включить, перейдите в chrome: // flags / # enable-devtools-tests -> перезапустите Chrome -> перейдите в DevTools -> Настройки -> Эксперименты -> нажмите Shift 6 раз -> установите флажок называется Timeline: V8 Runtime Call Stats on Timeline и закройте, а затем снова откройте DevTools.

Но какое это имеет значение?

Затраты времени на синтаксический анализ / компиляцию кода могут сильно задержать то, как скоро пользователь может взаимодействовать с вашим сайтом. Чем больше JavaScript вы отправите, тем дольше он будет возьмите, чтобы проанализировать и скомпилировать его, прежде чем ваш сайт станет интерактивным.

байтов, JavaScript дороже для обработки браузером, чем изображение аналогичного размера или веб-шрифт — Tom Dale

По сравнению с JavaScript, обработка требует значительных затрат. изображения одинакового размера (их все равно нужно декодировать!), но в среднем на мобильных устройствах аппаратного обеспечения, JS с большей вероятностью негативно повлияет на интерактивность страницы.

JavaScript и байты изображений имеют очень разные затраты. Изображения обычно не блокируют основные нить или запретить интерактивность интерфейсов во время декодирования и растеризованный. Однако JS может задерживать интерактивность из-за синтаксического анализа, компиляции и затраты на исполнение.

Когда мы говорим о медленном синтаксическом анализе и компиляции; контекст важен — мы речь идет о средних мобильных телефонах здесь. У обычных пользователей могут быть телефоны с медленными процессорами и графическими процессорами, без кеша L2 / L3 и может даже быть памятью сдерживается.

Сетевые возможности и возможности устройств не всегда совпадают. Пользователь с отличным оптоволоконным соединением не обязательно иметь лучший процессор для анализировать и оценивать отправленный на их устройство JavaScript. Это также верно в обратное .. ужасное сетевое соединение, но невероятно быстрый процессор. — Кристофер Бакстер, LinkedIn

Ниже мы видим стоимость синтаксического анализа ~ 1 МБ распакованного (простого) JavaScript на низкое и высококачественное оборудование. Разница во времени синтаксического анализа / компиляции составляет 2–5 раз. код между самыми быстрыми телефонами на рынке и средними телефонами .

Этот график выделяет время синтаксического анализа для пакета JavaScript размером 1 МБ (~ 250 КБ в сжатом виде) через настольные и мобильные устройства разных классов. Если посмотреть на стоимость синтаксического анализа, следует учитывать данные в распакованном виде, например, ~ 250 КБ сжатого сжатого файла JS распаковывает до ~ 1 МБ кода.

А как насчет реального сайта, такого как CNN.com?

На iPhone 8 высокого класса для синтаксического анализа / компиляции JS CNN требуется всего ~ 4 секунды. до ~ 13 с для среднего телефона (Moto G4) . Это может существенно повлиять на то, как быстро пользователь может полностью взаимодействовать с этим сайтом.

Выше мы см. время синтаксического анализа, сравнивающее производительность чипа Apple A11 Bionic с производительностью Snapdragon 617 в более среднем оборудовании Android.

Это подчеркивает важность тестирования на среднем оборудовании (например, Moto G4) вместо телефона, который может быть у вас в кармане. Контекст имеет значение однако: оптимизируйте для устройств и условий сети, которые есть у ваших пользователей.

Google Аналитика может дать представление о мобильных классы устройств, с которыми ваши реальные пользователи заходят на ваш сайт.Это может дают возможность понять реальные ограничения CPU / GPU, которые они накладывают работает с.

Неужели мы действительно отправляем слишком много JavaScript? Эээ, возможно 🙂

Использование HTTP-архива (~ 500 тыс. Самых популярных сайтов) для анализа состояния JavaScript на мобильный, мы можем видите, что 50% сайтов становятся интерактивными за 14 секунд. Эти сайты тратят до 4 секунд только на парсинг и компиляцию JS.

Фактор времени, необходимого для получения и обработки JS и других ресурсов, и это возможно, неудивительно, что пользователям можно немного подождать, прежде чем они почувствуют страницы готовы к использованию.Мы определенно можем добиться большего здесь.

Удаление некритического кода JavaScript со страниц может уменьшить передачу раз, разбор и компиляция с интенсивным использованием ЦП и потенциальные накладные расходы на память. Этот также помогает сделать ваши страницы более интерактивными.

Время исполнения

Это не просто синтаксический анализ и компиляция, которые могут иметь свою цену. Выполнение JavaScript (запуск кода после синтаксического анализа / компиляции) — одна из операций, которые должны произойти в основном потоке. Длительное время выполнения также может повлиять на то, как скоро пользователь сможет взаимодействовать с вашим сайтом.

Если скрипт выполняется более 50 мс, время до интерактивности задерживается на всего времени, необходимого для загрузки, компиляции и выполнения JS — Алекс Рассел

Чтобы решить эту проблему, JavaScript извлекает выгоду из небольших фрагментов , чтобы избежать блокируя основной поток. Узнайте, можно ли сократить объем выполняемой работы сделано во время исполнения.

Прочие расходы

JavaScript может влиять на производительность страницы и другими способами:

  • Память.Страницы могут часто зависать или останавливаться из-за GC (мусор коллекция). Когда браузер освобождает память, выполнение JS приостанавливается, поэтому браузер, часто собирающий мусор, может приостанавливать выполнение чаще, чем нам может понравиться. Избегайте утечек памяти и частые паузы gc, чтобы страницы не зависали.
  • Во время выполнения долго работающий JavaScript может блокировать основной поток, вызывая страницы, которые не отвечают. Разделение работы на более мелкие части (используя requestAnimationFrame () или requestIdleCallback () для планирования) может минимизировать проблемы с быстродействием.

Шаблоны для снижения стоимости доставки JavaScript

Когда вы пытаетесь сохранить время синтаксического анализа / компиляции и передачи по сети для JavaScript медленный, есть шаблоны, которые могут помочь, такие как разбиение на фрагменты на основе маршрута или PRPL.

ПРПЛ

PRPL (Push, Render, Pre-cache, Lazy-load) — это шаблон, который оптимизирует интерактивность за счет агрессивного разделения кода и кеширования:

Давайте представим, какое влияние это может оказать.

Мы анализируем время загрузки популярных мобильных сайтов и прогрессивных веб-приложений, используя Статистика вызовов времени выполнения V8.Как мы видим, время синтаксического анализа (показано оранжевым) — это значительная часть того, где проводят время многие из этих сайтов:

Wego, сайту, использующему PRPL, удается поддерживать низкий уровень синтаксического анализа время для их маршрутов, становясь интерактивными очень быстро. Многие другие сайты выше принятые бюджеты на разделение кода и производительность, чтобы попытаться снизить их JS расходы.

Прогрессивная начальная загрузка

Многие сайты оптимизируют видимость контента ценой интерактивности.Получить Быстрая первая отрисовка, когда у вас есть большие пакеты JavaScript, разработчики иногда используют рендеринг на стороне сервера; затем «обновите» его, чтобы прикрепить событие обработчики, когда, наконец, будет получен JavaScript.

Будьте осторожны — это имеет свои издержки. Вы 1) обычно отправляете больших HTML ответ, который может подтолкнуть нашу интерактивность, 2) может оставить пользователя в жутком долина, где половина опыта не может быть интерактивной до тех пор, пока JavaScript заканчивает обработку.

Прогрессивная загрузка может быть лучшим подходом.Отправить минимально функциональная страница (состоящая только из HTML / JS / CSS, необходимых для текущего маршрута). По мере поступления дополнительных ресурсов приложение может выполнять отложенную загрузку и разблокировать больше функций.

Прогрессивный Начальная загрузка Пола Льюиса

Загрузка кода, пропорциональная тому, что находится в поле зрения, — это Святой Грааль. PRPL и Прогрессивная загрузка — это шаблоны, которые могут помочь в этом.

Выводы

Размер передачи имеет решающее значение для сетей низкого уровня. Время синтаксического анализа важно для устройств с привязкой к ЦП.Держать эти мелкие вопросы.

Команды

добились успеха, установив строгие бюджеты производительности для сохранения своих Низкое время передачи и синтаксического анализа / компиляции JavaScript. См. «Can You Позволить себе это?: Реальная производительность в Интернете Бюджеты » для руководства по бюджету для мобильных устройств.

Его полезно учитывать, насколько JS «запасает» архитектурные решения, которые мы принимаем может оставить нас для логики приложения.

Если вы создаете сайт, ориентированный на мобильные устройства, приложите все усилия, чтобы на типичном оборудовании сокращайте время синтаксического анализа / компиляции JavaScript и принять бюджет производительности, чтобы ваша команда могла следить за их стоимость JavaScript.

Узнать больше

optimize-js — npm

Оптимизируйте файл JavaScript для более быстрого начального выполнения и анализа, заключив в скобки все немедленно вызываемые функции или функции, которые могут быть вызваны.

Последние изменения см. В журнале изменений.

Установить

  npm install -g optimize-js
  

Использование

  optimize-js input.js> output.js
  

Пример ввода:

 

! Function () {} ()

function runIt (fun) {fun ()}

runIt (function () {})

Пример вывода:

 

! (Function () {}) ()

function runIt (fun) {fun ()}

runIt ((function () {}))

Обзор теста

Браузер Типичное увеличение / уменьшение скорости с использованием optimize-js
Хром 55 20.63%
Кромка 14 13,52%
Firefox 50 8,26%
Safari 10 -1,04%

Эти числа основаны на тесте общих библиотек JS. Подробные сведения о тестах см. В разделе тесты.

CLI

  Использование: optimize-js [параметры]

Параметры:
  --source-map включить исходную карту [логическое]
  -h, --help Показать справку [логическое]

Примеры:
  optimize-js input.js> output.js оптимизировать input.js
  optimize-js  output.js читается из stdin, записывается в stdout
  

JavaScript API

 

var optimizeJs = require ('optimize-js');

var input = "! Function () {console.log ('оберните меня!')}";

var output = optimizeJs (вход);

Вы также можете передать аргументы:

 

var optimizeJs = require ('optimize-js');

var input = "! Function () {console.log ('оберните меня!')}";

var output = optimizeJs (input, {

sourceMap: true

});

Почему?

Современные движки JavaScript, такие как V8, Chakra и SpiderMonkey, имеют эвристику, в которой они предварительно анализируют большую часть функции перед выполнением полного анализа.Этап предварительного анализа просто проверяет синтаксические ошибки, избегая затрат на полный синтаксический анализ.

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

К сожалению, это предположение не работает в случае немедленно вызываемых функциональных выражений (IIFE), таких как эти:

 

(функция () {console.log ('выполнено!')}) ();

(функция () {console.log ('выполнено в стиле Крокфорда!')} ());

! Function () {console.log ('выполнено в стиле UglifyJS!')} ();

Хорошая новость заключается в том, что JS-движки имеют дополнительную оптимизацию , где они пытаются обнаружить такие IIFE и пропустить этап предварительного анализа. Ура!

Плохая новость в том, что эта эвристика не всегда работает. потому что они основаны на жадном методе проверки токена '(' сразу слева от функции.(Парсер избегает чего-либо более сложного, потому что это равносильно синтаксическому анализу всего этого, сводя на нет преимущества предварительного синтаксического анализа). В случаях без парена (которые включают распространенные форматы модулей, такие как UMD / Browserify / Webpack / и т. д.), браузер фактически проанализирует функцию дважды , сначала как предварительный синтаксический анализ, а второй как полный разбор. Это означает, что код JavaScript в целом выполняется намного медленнее, поскольку на синтаксический анализ тратится больше времени, чем необходимо. См. «Стоимость небольших модулей», чтобы понять, насколько это плохо.

К счастью, поскольку оптимизация '(' для IIFE хорошо известна, мы можем использовать ее в процессе сборки, предварительный анализ всего файла JavaScript (роскошь, которую браузер не может себе позволить) и вставка скобок в тех случаях, когда мы знаем функция будет немедленно выполнена (или если у нас есть хорошая догадка). Это то, что делает optimize-js .

Более подробную информацию об оптимизации IIFE можно найти в этом обсуждении.Некоторые из моих мыслей о достоинствах оптимизации во время компиляции можно найти в этом посте.

Часто задаваемые вопросы

Как это работает?

Текущая реализация заключается в синтаксическом анализе синтаксического дерева и проверке функций, которые:

  1. Вызываются немедленно с помощью любого оператора вызова ( function () {} () , ! Function () {} () и т. Д.)
  2. Передаются напрямую в качестве аргументов другой функции

Первый способ — легкий выигрыш — эти функции выполняются немедленно.Второй метод более эвристический, но имеет тенденцию чтобы быть безопасной ставкой, учитывая распространенные шаблоны, такие как ошибки в стиле узла, цепочки обещаний и объявления модулей UMD / Browserify / Webpack.

Во всех таких случаях optimize-js заключает функцию в круглые скобки.

Но … вы добавляете байты!

Да, optimize-js может добавить до двух байтов (ужас!) На функцию, что практически равно нулю, если вы учтите gzip. Чтобы доказать это, вот размеры gzip для библиотек, которые я использую в тесте:

Скрипт Размер (байты) Разница (байты)
тесты / create-react-app.мин. js 160387
тесты / create-react-app.min.optimized.js 160824 + 437
тесты / immutable.min.js 56738
тесты / immutable.min.optimized.js 56933 + 195
тесты / jquery.min.js 86808
тесты / jquery.min.optimized.js 87109 + 301
тестов / lodash.мин. js 71381
тесты / lodash.min.optimized.js 71644 + 263
тесты / pouchdb.min.js 140332
тесты / pouchdb.min.optimized.js 141231 + 899
тестов / three.min.js 486996
тестов / three.min.optimized.js 487279 + 283

Предназначен ли

optimize-js для авторов библиотек?

Конечно! Если вы уже отправляете объединенную миниатюрную версию своей библиотеки, то нет причин не применять optimize-js (при условии, что вы протестируете свой код, чтобы убедиться, что он действительно помогает!).Однако обратите внимание, что optimize-js должен запускать после Uglify, поскольку Uglify удаляет лишние круглые скобки, а также отменяет IIFE по умолчанию. Это также означает, что если ваши пользователи применяют Uglification к вашему пакету, оптимизация будет отменена.

Также обратите внимание, что поскольку optimize-js оптимизирует некоторые шаблоны, которые основаны на эвристике, а не , известный активно вызывается функций, в некоторых случаях это может повредить вашей производительности. (Примеры см. В тестах ниже.Обязательно проверьте, что optimize-js — это помощь, а не помеха для вашей конкретной кодовой базы, используя что-то вроде:

 

Обратите внимание, что границы сценария на самом деле рекомендуются, чтобы действительно измерить полное время синтаксического анализа / компиляции.Если вы не хотите измерять накладные расходы сети, вы можете увидеть, как мы это делаем, в наших тестах.

Вы также можете проверить Марки, который позволяет вам легко устанавливать точки отметки / измерения, которые вы можете визуально проверять на шкале времени Dev Tools, чтобы убедиться, что время компиляции измеряется.

Также обязательно протестируйте в нескольких браузерах! Если вам нужна пограничная виртуальная машина, загляните на edge.ms.

Разве это не должно быть работой Углифи?

Возможно! Это бесплатная библиотека с открытым исходным кодом, поэтому я призываю всех позаимствовать код или хорошие идеи.:)

Почему бы не обернуть каждую функцию пареном?

Как описано выше, оптимизация предварительного анализа в браузерах — очень хорошая идея для подавляющего большинства веб-сайтов, где большинство функций не выполняются немедленно. Однако, поскольку optimize-js знает, когда ваши функции немедленно выполняются (или может сделать разумный догадки), может быть более разумным будет применить парен-хак.

Это действительно работает для каждого движка JavaScript?

Судя по моим тестам, эта оптимизация лучше всего работает для V8 (Chrome), за которым следует Chakra (Edge), а затем SpiderMonkey (Firefox).Для JavaScriptCore (Safari) это похоже на промывку, и на самом деле может быть небольшой регресс в целом в зависимости от вашей кодовой базы. (Опять же, вот почему так важно проводить измерения на вашей собственной кодовой базе, в браузерах, на которые вы на самом деле ориентируетесь!)

В случае с Chakra IIFE в стиле Uglify на самом деле уже оптимизированы, но использование optimize-js не повредит, потому что функция, перед которой стоит '(' по-прежнему переходит в быстрый путь.

Ориентиры

Эти тесты были запущены с использованием нескольких популярных библиотек, рассчитанных на производительность .now () измерений. В каждом тесте сообщалось о среднем 251 прогоне. optimize-js commit da51013 был протестирован. Минификация была применена с помощью uglifyjs -mc , Uglify 2.7.0.

Вы также можете попробовать живую версию теста.

Chrome 55, Windows 10 RS1, Surfacebook i5

Скрипт Оригинал Оптимизировано Улучшение Минифицированный мин. + Оптимизировано Улучшение
Создать приложение React 55.39 мс 51,71 мс 6,64% 26,12 мс 21,09 мс 19,26%
неизменяемый JS 11,61 мс 7,95 мс 31,50% 8,50 мс 5,99 мс 29,55%
jQuery 22,51 мс 16,62 мс 26,18% 19,35 мс 16,10 мс 16.80%
Лодаш 20,88 мс 19,30 мс 7,57% 20,47 мс 19,86 мс 3,00%
Чехол DB 43,75 мс 20,36 мс 53,45% 36,40 мс 18,78 мс 48,43%
Три JS 71,04 мс 72,98 мс -2,73% 54.99 мс 39,59 мс 28,00%

Общее улучшение: 20,63%

Edge 14, Windows 10 RS1, SurfaceBook i5

Скрипт Оригинал Оптимизировано Улучшение Минифицированный мин. + Оптимизировано Улучшение
Создать приложение React 32,46 мс 24,85 мс 23.44% 26,49 мс 20,39 мс 23,03%
неизменяемый JS 8,94 мс 6,19 мс 30,74% 7,79 мс 5,41 мс 30,55%
jQuery 22,56 мс 14,45 мс 35.94% 16,62 мс 12,99 мс 21,81%
Лодаш 22.16 мс 21,48 мс 3,05% 15,77 мс 15,46 мс 1,96%
Чехол DB 24,07 мс 21,22 мс 11,84% 39,76 мс 52,86 мс -32,98%
Три JS 43,77 мс 39,99 мс 8,65% 54,00 мс 36,57 мс 32.28%

Общее улучшение: 13,52%

Firefox 50, Windows 10 RS1, Surfacebook i5

Скрипт Оригинал Оптимизировано Улучшение Минифицированный мин. + Оптимизировано Улучшение
Создать приложение React 33,56 мс 28.02 мс 16,50% 24,71 мс 22.05 мс 10,76%
неизменяемый JS 6,52 мс 5,75 мс 11.80% 4,96 мс 4,58 мс 7,47%
jQuery 15,77 мс 13,97 мс 11,41% 12,90 мс 12,15 мс 5,85%
Лодаш 17,08 мс 16,63 мс 2.64% 13,11 мс 13,22 мс -0,80%
Чехол DB 19,23 мс 16,77 мс 12,82% 13,77 мс 12,89 мс 6,42%
Три JS 38,33 мс 37,36 мс 2,53% 33.01 мс 30,32 мс 8,16%

Общее улучшение: 8.26%

Safari 10, macOS Sierra, MacBook Pro i5 2013 года выпуска

Скрипт Оригинал Оптимизировано Улучшение Минифицированный мин. + Оптимизировано Улучшение
Создать приложение React 31,60 мс 31,60 мс 0,00% 23,10 мс 23,50 мс -1,73%
неизменяемый JS 5.70 мс 5,60 мс 1,75% 4,50 мс 4,50 мс 0,00%
jQuery 12,40 мс 12,60 мс -1,61% 10,80 мс 10,90 мс -0,93%
Лодаш 14,70 мс 14,50 мс 1,36% 11,10 мс 11,30 мс -1.80%
Чехол DB 14,00 мс 14.20 мс -1,43% 11,70 мс 12,10 мс -3,42%
Три JS 35,60 мс 36,30 мс -1,97% 27,50 мс 27,70 мс -0,73%

Общее улучшение: -1,04%

Обратите внимание, что эти результаты могут отличаться в зависимости от вашей машины, нагрузки на ваш ЦП, гремлинов и т. Д.Я запускал полный пакет несколько раз во всех браузерах и обнаружил, что эти цифры примерно репрезентативны. В нашем наборе тестов мы используем среднее значение 151 запуск, чтобы уменьшить вариабельность.

Плагины

См. Также

Спасибо

Спасибо @krisselden, @bmaurer и @pleath за объяснение этих концепций в различных выпусках GitHub. Также благодарим astexplorer, acorn и magic-string за то, что они сделали реализацию такой простой.

Спасибо Саше Айкину за щедрый вклад в улучшение этой библиотеки (особенно в v1.0,3) и подталкивает меня к повышению точности тестов.

Содействие

Сборка и запуск тестов:

Запустите тесты:

Покрытие тестового кода:

История изменений

  • v1.0.3
    • Намного более точный тест (# 37)
    • Исправления, связанные с Browserify (# 29, # 36, # 39)
    • Исправления, относящиеся к Webpack (# 7, # 34)
  • v1.0.2
    • Используйте estree-walker для правильного анализа ES6 (# 31)
  • v1.0,1:
    • Не вызывать process.exit (0) в случае успеха (# 11)
  • v1.0.0

Как оптимизировать доставку JavaScript для ускорения вашего сайта

JavaScript — важный аспект создания привлекательных сайтов, но он может существенно повлиять на способ загрузки страниц. Как и любой другой файл, создающий веб-страницу, JavaScript должен загрузиться, прежде чем он сможет работать. Размер файлов JavaScript, а также способ доставки этих файлов влияют на время загрузки. JavaScript также является динамическим языком и компилируется на лету, как только браузер получает его.Это делает обработку JavaScript более дорогостоящей, чем обработку файлов других типов.

Этот пост будет посвящен оптимизации доставки для JavaScript: почему вам следует заботиться, соображениям и передовым методам, а также некоторым ссылкам на соответствующие ресурсы. Оптимизация обработки JavaScript также невероятно важна для загрузки современных веб-сайтов, но я расскажу об этом в отдельной публикации.

Влияние размера файла JS

На миллионах сайтов, измеренных с помощью HTTP-архива, на JavaScript приходится 15% веса страниц для настольных компьютеров и 16% для мобильных страниц.Для пользователей настольных компьютеров это составляет около 400 КБ на каждую посещенную страницу и 360 КБ для мобильных пользователей. Если учесть, что первое соединение, открытое для загрузки страницы, передает только 14 КБ данных, становится очевидным, что уменьшение размера файла JS является важной оптимизацией.

Но 400 КБ JavaScript не равны 400 КБ загрузки изображения, отчасти потому, что обработка JavaScript происходит при несжатом файле. Байт за байтом, JavaScript дороже, чем любой другой тип файлов для обработки на странице с точки зрения ЦП и времени.Если учесть, что сжатие GZIP может уменьшить размер доставленного текстового файла на 70–90%, 400 КБ действительно превращаются в 1,3–4,0 МБ.


Снижение воздействия JS-доставки

Итак, как мы можем уменьшить время загрузки страницы, связанное с доставкой JavaScript? Есть два способа, для каждого из которых есть лучшие практики:

  1. Ускорьте загрузку JS в браузере.
    • Уменьшите объем JS, который вы используете для создания страницы.
    • Минимизируйте все ресурсы JS и используйте минимизированный сторонний JS.
    • Самостоятельное размещение стороннего JS (или использование сервис-воркера).
    • Сжать JS.
    • Используйте push и preload для критического JS.
  2. Загружайте JS только тогда, когда это необходимо.
    • Удалить мертвый код JS.
    • Разделение файлов JS для доставки основных компонентов.
    • Асинхронная загрузка некритических JS-компонентов.
    • Кэш JS.

Мы рассмотрим перечисленные передовые методы для достижения обеих целей, включая рекомендации по стороннему JavaScript, над которым вы, возможно, не имеете большого контроля.

В следующих случаях важно убедиться, что ваша пользовательская база поддерживает реализованные методы браузером. Real User Monitoring позволяет вам увидеть, какие версии наиболее распространены среди ваших пользователей, и их следует считать необходимыми для тестирования любых изменений, которые вы вносите на свой сайт.

Ускорение загрузки JS в браузере

Уменьшите объем JS, который вы используете для создания страницы

Если вы предоставите меньше JavaScript, страница будет загружаться быстрее.

Не знаете, с чего начать? Мы уже знаем, что JS — это самый дорогой вид файлов, используемых для создания вашего сайта, поэтому вы также можете подумать о нем с точки зрения обработки. Для интерактивности на странице рекомендуется использовать JavaScript для функций, которые улучшают взаимодействие с пользователем — ожидаемых переходов, анимации и событий — а не для вещей, которые могут нарушить работу, например ярких, растянутых анимаций.

Существуют ли сторонние фрагменты JavaScript, которые являются избыточными или не важны для того, что вы хотите, чтобы страница делала? Подумайте об их устранении.

Разработчики Google разработали рекомендации, основанные на восприятии пользователями задержек производительности, которые вы можете использовать, чтобы судить о необходимости JS на странице в сочетании с тестированием.

Восприятие пользователем задержек производительности

от 0 до 16 мс

Пользователи исключительно хороши в отслеживании движения, и им не нравится, когда анимация не плавная.Они воспринимают анимацию как плавную, если каждую секунду рендерится 60 новых кадров. Это 16 мс на кадр, включая время, необходимое браузеру, чтобы отобразить новый кадр на экране, оставляя приложению около 10 мс для создания кадра.

от 0 до 100 мс

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

от 100 до 300 мс

У пользователей наблюдается небольшая заметная задержка.

от 300 до 1000 мс

В этом окне все кажется частью естественного и непрерывного выполнения задач. Для большинства пользователей Интернета загрузка страниц или изменение представлений представляет собой задачу.

1000 мс или более

По истечении 1000 миллисекунд (1 секунда) пользователи теряют внимание к выполняемой задаче.

10000 мс или более

При превышении 10000 миллисекунд (10 секунд) пользователи разочаровываются и, скорее всего, бросят задачи.Они могут вернуться, а могут и не вернуться позже.

Использовать минимизированные файлы JS

Минификация удаляет ненужные знаки препинания, пробелы и символы новой строки. Истинная минификация также использует обфускацию, которая переименовывает переменные в имена, которые требуют меньшего количества байтов данных для чтения браузером, чем имена переменных, удобочитаемые человеком.

В сети есть много инструментов для минификации, не все из которых используют обфускацию. Подумайте, что лучше всего подходит для вашего сайта, и всегда используйте какую-либо форму минификации.Чем меньше байтов данных вы передаете на файл JavaScript, тем быстрее он загружается и тем быстрее браузер сможет его проанализировать.

Самостоятельное размещение стороннего JS, если применимо (или использование сервис-воркера)

Размещение стороннего JavaScript в вашем собственном домене может быть менее удобным в обслуживании — вы не получите автоматических обновлений для скрипта, а изменения в API могут произойти без предупреждения — но это все равно может быть полезно, если скрипт критически важен для рендеринга вашего страница. Сценарий будет использовать вашу сеть и протоколы безопасности, что может привести к лучшим результатам.Вы также можете включать в библиотеки только те компоненты, которые используются в вашем исходном коде (см. «Устранение мертвого кода» ниже).

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

Сжатие JS

Сжатие текстовых файлов на стороне сервера может существенно уменьшить размер файла.Этот передаваемый размер JavaScript позволяет загружать больше несжатых данных, чем обычно, устраняя необходимость в дальнейших циклах. Сжатие JavaScript вместе с CSS и другими текстовыми файлами может снизить вес страницы вдвое.

Используйте толчок и предварительную нагрузку для критических JS

Server push и предварительная загрузка могут использоваться для доставки файлов, критически важных для рендеринга страницы, раньше при загрузке страницы, чем обычно.

Файл загружается с помощью push, если указано на стороне сервера — сервер получает запрос и ему заранее сказано, что ресурсы x, y и z должны быть загружены вместе с ним.Примечательно, что методологию push можно использовать только в HTTP / 2.

Preload немного отличается, где связанным ресурсам может быть присвоен атрибут «preload» в файле HTML. Как только страница будет доставлена ​​и пока только начинается синтаксический анализ HTML, эти ресурсы запрашиваются с сервера. Это быстрее, чем обычный анализ HTML, потому что ресурсы затем запрашиваются не в том порядке, в котором они перечислены в HTML.

Загружать JS только тогда, когда это необходимо

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

Устранение мертвого кода при встряхивании дерева

Встряхивание дерева, или устранение мертвого кода, избавляет, как вы уже догадались, от кода, которого нет на вашей странице. Например, предположим, что вы загружаете миниатюрную библиотеку JQuery, но при создании страницы используете только несколько функций, предлагаемых JQuery, в собственном коде.Удаление мертвого кода позволит вам загружать только те части библиотеки JQuery, которые вы используете.

Термин «встряхивание дерева» популяризировал Rollup, который реализует эту функцию, но он также доступен через webpack и source-map-explorer. Примечательно, что эта функция работает только с модулями ES2015, используя синтаксис для ссылки на пакеты JS в других файлах. Если вы используете CommonJS, доступны некоторые параметры, например webpack-common-shake, но при использовании CommonJS вы, скорее всего, столкнетесь с ограничениями.В долгосрочной перспективе, если вы хотите использовать встряхивание деревьев, наиболее полезным будет ES2015 или более поздняя версия.

Доставка основных компонентов с разбиением на фрагменты на основе маршрута или разбиением кода

Блокирование на основе маршрутов, или разделение кода, применяется к веб-сайтам, которые загружают одностраничные приложения, прогрессивные веб-приложения или любую другую платформу, для которой требуется большой пакет JS для создания первой страницы, которую видит пользователь. Использование фрагментов на основе маршрутов позволяет сначала загружать на страницу только необходимые фрагменты пакета JS для первоначального рендеринга и интерактивности, что сокращает общий объем JavaScript, передаваемого для построения страницы, а также время, необходимое для визуализации значимого содержание.

То, как вы определяете, где разделить код, зависит от типа загружаемого приложения, от того, кто ваши пользователи и какова ваша серверная архитектура. Есть несколько типов разделения кода:

  • Разделение на поставщика отделяет ваш JS от JS, предоставленного вашим поставщиком фреймворка, например React или Vue. Разделение по поставщику предотвращает перезагрузку более крупного пакета при изменении функции в любом из источников кода. Разделение на поставщиков должно выполняться в каждом веб-приложении.
  • Разделение с помощью точек входа разделяет ваш код в зависимости от того, где в вашем коде веб-пакет начинает определять зависимости в вашем приложении.Если ваш сайт не использует маршрутизацию на стороне клиента (например, SPA использует маршрутизацию на стороне клиента), использование точек входа для разделения кода может иметь смысл. При таком разбиении использование такого инструмента, как Bundle Buddy, чтобы гарантировать, что повторяющиеся пакеты не включены в дерево зависимостей, может помочь страницам загружаться быстрее.
  • Динамическое разделение кода хорошо работает с приложениями, использующими маршрутизацию на стороне клиента, например одностраничными приложениями, потому что не все пользователи будут использовать все функции на странице. Это можно сделать с помощью динамического оператора import () , который возвращает обещание.По этой причине вы также можете использовать динамический импорт с помощью async / await. Parcel и webpack будут искать динамический оператор import () для отложенной загрузки ресурсов по мере необходимости.
Асинхронная загрузка некритических JS-компонентов

Использование атрибутов async и defer для внешних сценариев очень важно, особенно со сторонними сценариями. И async , и defer являются асинхронными для загрузки и анализа помеченных ими ресурсов.Почему это важно? Для JavaScript поведение по умолчанию для загрузки и анализа сценария является синхронным, что означает, что почти все остальные процессы на странице останавливаются, пока выполняются эти шаги.

Атрибут async имеет приоритет над defer в современных браузерах, поскольку современные движки браузеров лучше приспособлены для обработки JavaScript. В старых браузерах все наоборот.

Примечательно, что выполнение JavaScript происходит в одном и том же потоке браузера.JavaScript с пометкой async всегда будет выполняться до JavaScript с пометкой defer . Синхронный JavaScript выполняется немедленно, и его следует использовать только для кода, который отображает страницу (и, вероятно, даже не тогда).

Кэш JS

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

Кэширование

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

Takeaways and TL; DR

Использование функций современных фреймворков делает JavaScript более удобным в обслуживании, чем когда-либо. Хотя на первый взгляд это может показаться запутанным, есть всего несколько целей, к которым стремятся лучшие практики JavaScript:

  1. Меньшие размеры страницы
  2. Быстрая доставка
  3. Более эффективная обработка

В этом посте мы рассмотрим первые два, которые связаны между собой.Меньшие размеры страниц возможны, если вы уменьшите объем кода, который вы доставляете своим пользователям, тем самым доставляя их быстрее.

TL; DR
  • Устранение ненужного JavaScript, минимизация и сжатие JavaScript, встряхивание дерева и разделение кода — все это снижает объем JavaScript, доставляемого на страницу.
  • Доставка ресурсов с помощью сервис-воркера и использование кэширования может дополнительно контролировать, загружается ли JavaScript на страницу.
  • Асинхронная загрузка скриптов с предварительной загрузкой и принудительной загрузкой критического JavaScript также позволяет странице загружаться быстрее.

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

<<< Часть 1: Как оптимизировать изображения для повышения производительности в Интернете

<< Часть 2: Как оптимизировать CSS для повышения производительности в Интернете

<Часть 3: Как оптимизировать HTML для повышения производительности сети

Как оптимизировать производительность JavaScript — Stackify

JavaScript — это общий язык в разработке мобильных и веб-приложений.Из-за своей популярности оптимизация JavaScript становится все более необходимой для повышения производительности приложений. Давайте узнаем о некоторых проблемах, связанных с JavaScript, и о том, как оптимизировать производительность js.



Типичные проблемы производительности js

Существует ряд проблем, которые могут повлиять на производительность JavaScript. Вот общие проблемы, связанные с производительностью js:

Обработка событий низкого качества :

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

Важно отслеживать все обработчики событий, чтобы обработчики не работали без вашего ведома.

Неорганизованный код

JavaScript нечеткий, что является одновременно плюсом и минусом.

Мелкие подмножества лексических конструкций позволяют разработчикам добиться многого. Однако отсутствие организации в коде может привести к недостаточному распределению ресурсов.

Это может сильно снизить производительность JavaScript .Понимание ECMA важно для понимания JavaScript. .

Слишком много зависимостей

Иногда зависимости JavaScript плохо управляются или чрезмерны. Когда это произойдет, это отрицательно скажется на производительности приложения.

Например, мобильные пользователи с ограниченной пропускной способностью должны будут дольше ждать визуализированных объектов.

Неэффективные итерации

Обработка итераций занимает много времени. Однако это тоже полезно.Длительное время обработки создает идеальную отправную точку для оптимизации JavaScript. По мере исправления нерелевантных вызовов или циклов в коде производительность JavaScript значительно улучшится.

Советы по оптимизации производительности js

Обрезка HTML

JavaScript HTML сложен и играет решающую роль во времени запросов для запросов и изменения объектов DOM.

Если вдвое сократить HTML-код приложения, можно вдвое увеличить скорость DOM.Это может быть сложно, но это возможно, если отказаться от таких тегов, как

и .

Пакетирование изменений DOM

Пакетирование преобразований DOM для предотвращения повторяющихся отображений экрана. При изменении стиля вносите все изменения сразу, а не применяйте изменения к каждому стилю по отдельности.

Изучение методов асинхронного программирования

Приложениям JavaScript требуется множество внутренних вызовов многочисленных API для выборки данных.

Промежуточное ПО необходимо для каждой функции, потому что JavaScript является однопоточным.

Синхронные компоненты иногда могут блокировать все приложение. JavaScript управляет асинхронным кодом с помощью async.js.

Асинхронный код не блокирует поток. Вместо этого угроза попадает в очередь событий, которая срабатывает после выполнения других кодов.

С помощью асинхронных функций JavaScript можно непреднамеренно использовать внешнюю библиотеку для возврата к асинхронным вызовам с подавлением вызовов.

Это может снизить производительность JavaScript . Вместо этого используйте в коде асинхронные API-интерфейсы, особенно в критически важных разделах производительности.

Использование сжатия gzip

Файлы JavaScript могут быть огромными. Используйте GZip для распаковки и сжатия файлов. GZip уменьшает время задержки, повышает производительность приложений и экономит полосу пропускания. С помощью GZip сервер сжимает ресурс перед его отправкой в ​​браузер.

Использовать HTTP / 2

Последней версией HTTP является HTTP / 2 с улучшениями для повышения производительности JavaScript и для повышения производительности веб-сайтов.

HTTP / 2 использует мультиплексирование и позволяет одновременно отправлять несколько ответов и запросов. Буферизация DOM

Если есть прокручиваемые DIV, можно использовать буфер, чтобы избавиться от элементов DOM, которые в настоящее время не видны в области просмотра. Эти методы позволяют сэкономить как на обходе DOM, так и на использовании памяти.

Ограничить зависимости библиотек

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

Лучший способ избавиться от зависимостей внешних библиотек — это использовать встроенные в браузер технологии.

При использовании селекторов CSS используйте Sizzle.js вместо jQuery. Когда библиотеки представляют собой одну функцию, жизненно важно добавлять селекторы CSS отдельно.

Сохранение компактности и легкости кодов

Сохранение компактности кода JavaScript снизит задержку и повысит производительность. При оптимизации производительности JavaScript спросите себя:

  • Существует ли реальная потребность в этом модуле?
  • В чем причина использования этого фреймворка?
  • Стоят ли накладные расходы?
  • Есть способ сделать это попроще?

Оптимизация производительности JavaScript путем преобразования нескольких файлов JS в один.

Реализация инструментов управления производительностью приложений для js Производительность:

Когда дело доходит до оптимизации производительности JavaScript, важно использовать инструмент управления производительностью приложений. Инструменты управления производительностью приложений, такие как Retrace, поставляются с Real User Monitoring (RUM). RUM ускоряет веб-производительность, позволяя одновременно отслеживать внешний и внутренний код. Такой более комплексный подход упрощает выявление узких мест и позволяет лучше определить правильное решение.По мере оптимизации производительности веб-страницы веб-страницы реагируют быстрее и становятся более интерактивными. Конечные пользователи довольны, становятся более заинтересованными и, в конечном итоге, с большей вероятностью совершат покупку.

РУМ включает разбивки по ресурсам. Разбивка ресурсов помогает определить, нужно ли оптимизировать изображения, минимизировать или кэшировать таблицы стилей и скрипты. Функциональность сегментации RUM позволяет получить более глубокое понимание. Используйте сегментацию для отслеживания времени загрузки в зависимости от браузера, географии и типа устройства. Это упрощает определение возможностей для улучшения общего опыта за счет определения оптимальных местоположений для сетей CDN.Попробуйте бесплатную 14-дневную пробную версию Retrace RUM сегодня.

Как настроить автоматическую оптимизацию для вашего сайта WordPress

Autoptimize — это бесплатный плагин для оптимизации WordPress. Помимо оптимизации HTML, CSS и JavaScript, Autoptimize также включает функции оптимизации, ориентированные на другие аспекты современных сайтов WordPress.

В этом посте мы расскажем о лучших настройках плагина Autoptimize для повышения производительности и скорости страницы вашего сайта WordPress.

Зачем нужна автоматическая оптимизация?

Прежде чем мы углубимся в лучшие настройки автоматической оптимизации, давайте быстро рассмотрим три причины, по которым Autoptimize является отличным плагином для оптимизации.

  1. Бесплатная версия Autoptimize имеет полный набор функций для оптимизации вашего сайта WordPress.
  2. Autoptimize — это строго плагин оптимизации и не выполняет кэширование HTML-страниц. Это означает, что он совместим со всеми веб-хостами — даже с настраиваемыми конфигурациями кеширования страниц, такими как Kinsta.
  3. Autoptimize имеет более 1 миллиона активных установок в репозитории WordPress и постоянно обновляется новыми функциями и исправлениями ошибок.

Автоматическая оптимизация настроек JS, CSS и HTML

HTML, CSS и JavaScript — это хлеб с маслом для Autoptimize.Как и в случае с другими плагинами оптимизации, изучение обширного набора функций и настроек Autoptimize может оказаться непростой задачей. Чтобы упростить задачу, мы собрали лучшие настройки автоматической оптимизации для повышения производительности вашего сайта.

Параметры JavaScript

Оптимизация JavaScript в Autoptimize.

Оптимизация кода JavaScript

Мы рекомендуем включить эту опцию. Когда включена «оптимизация кода JavaScript», функция Autoptimize минимизирует ваши файлы JavaScript.

Совокупные файлы JS
Опция

Autoptimize «агрегировать файлы JS» объединит все ваши файлы JavaScript в один файл.В прошлом объединение файлов JS и CSS было ключевым шагом в оптимизации WordPress. В Kinsta мы используем современные серверы HTTP / 2, которые поддерживают параллельную загрузку и мультиплексирование — это означает, что объединение файлов уже не так важно, как раньше, потому что HTTP / 2 позволяет загружать несколько файлов одновременно. С учетом сказанного, агрегирование файлов CSS и JS по-прежнему будет приводить к увеличению скорости для определенных типов сайтов WordPress, поэтому мы рекомендуем проверить скорость вашей страницы с включенной и отключенной этой опцией.

Также агрегатировать встроенный JS

Параметр «также агрегировать встроенный JS» извлекает встроенный JS в ваш HTML и объединяет его с оптимизированным файлом JS Autoptimize. Поскольку этот параметр может привести к быстрому увеличению размера кэша автоптимизации, мы рекомендуем оставить этот параметр отключенным, если у вас нет особых причин для его включения.

Принудительно использовать JavaScript в

В большинстве случаев мы не рекомендуем принудительно загружать файлы JavaScript в элемент HTML вашего сайта.Принуждение к ранней загрузке JS может привести к элементам, блокирующим рендеринг, которые могут замедлить скорость вашей страницы. Если у вас есть файлы JavaScript, которые необходимо загрузить в элемент , мы рекомендуем исключить эти сценарии из Autoptimize.

Исключить сценарии из автоматической оптимизации

Этот параметр позволяет исключить определенные каталоги и файлы JavaScript из агрегирования. По умолчанию Autoptimize исключает следующие сценарии.

  • wp-включает / js / dist /
  • wp-включает / js / tinymce /
  • js / jquery / jquery.js

Обратите внимание, что добавление сценария для исключения влияет только на агрегирование по умолчанию. Исключенные файлы JavaScript будут по-прежнему минимизированы, если только «минимизировать исключенные файлы CSS и JS» не будет снят флажок в разделе «Разные параметры».

Добавить упаковку Try-Catch

При включении опции «добавить упаковку try-catch» ваш код JavaScript будет заключен в блоки try-catch. Эта опция полезна для отладки проблем, вызванных минификацией и агрегацией JS. Если ваш сайт работает только с включенной функцией «добавить упаковку try-catch», мы рекомендуем работать с разработчиком, чтобы просмотреть ваши файлы JavaScript, чтобы определить тот, который вызывает проблему, поскольку чрезмерное использование блоков try-catch может снизить производительность JS.

Autoptimize: бесплатный плагин для оптимизации WordPress, о котором вы не знали … но он сделает ваш сайт молниеносным ⚡️Это руководство точно объясняет, зачем вам это нужно 🚀Нажмите, чтобы твитнуть

Параметры CSS

Автоматическая оптимизация CSS.

Оптимизация кода CSS

Мы рекомендуем включить эту опцию. Когда включена «оптимизация кода CSS», функция Autoptimize минимизирует ваши файлы CSS.

Совокупные файлы CSS
Параметр «агрегировать файлы CSS» в

Autoptimize объединит все ваши файлы CSS в один файл.Как мы упоминали ранее, эта функция может не принести пользу сайтам, поддерживающим HTTP / 2. Мы рекомендуем A / B-тестирование этой опции на вашем сайте, чтобы определить, оказывает ли какое-либо положительное влияние на скорость страницы.

Также объединить встроенный CSS

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

Создание данных: URI для изображений

Когда эта опция включена, Autoptimize будет кодировать в base64 небольшие фоновые изображения и вставлять их в CSS.Мы рекомендуем протестировать эту опцию, чтобы оценить влияние на скорость вашей страницы. Хотя кодирование изображений в формат base64 снижает количество HTTP-запросов, файлы представлений base64 обычно на 20-30% больше, чем их двоичные аналоги.

Встроенный и отложенный CSS

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

Встраивая эти ключевые элементы, можно загрузить более крупный полный CSS-файл позже, не влияя на внешний вид страницы. Хотя критические стили можно извлекать вручную, мы рекомендуем использовать такой инструмент для создания стилей в качестве отправной точки.

Сгенерируйте критический CSS.

После создания критического CSS скопируйте и вставьте его в настройки автоптимизации.

Встроить и отложить CSS в Autoptimize.

Следующим шагом будет проверка интерфейса вашего сайта.Если вы заметили какие-то странные вспышки нестилизованного содержимого (FOUC), вам, вероятно, потребуется идентифицировать эти нестилированные элементы и добавить соответствующие стили в Autoptimize для встраивания.

Autoptimize предлагает «усиление», которое автоматически генерирует критический CSS для ваших страниц WordPress. По нашему опыту, эта функция может иногда замедлять работу вашего сайта, поскольку использует внешние вызовы API для генерации критически важного CSS. Таким образом, начальная критическая генерация CSS зависит от скорости отклика внешнего сервера.В большинстве случаев вышеупомянутый метод, который не требует каких-либо внешних вызовов API, является более чистым решением.

Встроить все CSS

Для большинства сайтов мы не рекомендуем встраивать весь CSS, так как это может значительно увеличить размер страницы. Кроме того, встраивание всего CSS делает невозможным кэширование CSS в веб-браузере.

Исключить CSS из автоматической оптимизации

По умолчанию Autoptimize исключает следующие каталоги и файлы CSS из агрегирования. Если вы хотите, чтобы функция Autoptimize не объединяла какие-либо из ваших файлов CSS, вы можете добавить их в этот список.Подобно исключению JavaScript, поведение этой функции по умолчанию не препятствует минификации файлов CSS, а только агрегированию.

  • WP-контент / кеш /
  • WP-контент / загрузки /
  • админ-bar.min.css
  • dashicons.min.css

Параметры HTML

Оптимизация HTML

Autoptimize может помочь уменьшить размер ваших страниц за счет удаления пробелов.

Оптимизация HTML в Autoptimize.

Оптимизировать HTML-код

Мы рекомендуем включить функцию «оптимизировать HTML», поскольку она уменьшает размер страницы за счет удаления ненужных пробелов в HTML.Хотя эта функция совместима с большинством сайтов, удаление пробелов может вызвать сбои на некоторых сайтах. Таким образом, мы рекомендуем тщательно протестировать оптимизацию HTML-кода, прежде чем использовать ее в производственной среде.

Подпишитесь на информационный бюллетень

Мы увеличили наш трафик на 1187% с помощью WordPress.

Мы покажем вам, как это сделать.

Присоединяйтесь к 20 000+ другим, кто получает нашу еженедельную рассылку с инсайдерскими советами по WordPress!

Подпишитесь сейчас
Сохранить комментарии HTML

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

Опции CDN

Если вы используете CDN, например KinstaCDN, для ускорения статических ресурсов, вам необходимо добавить URL-адрес CDN в Autoptimize. Если вы используете прокси-сервис с возможностями CDN, например Cloudflare, вам не нужно ничего настраивать в параметрах CDN Autoptimize.

Настройте параметры CDN в Autoptimize.

Информация о кэше

«Информация о кеше»

Autoptimize отображает важную информацию, такую ​​как расположение и права доступа к папке с кешем, а также общий размер кэшированных стилей и скриптов.Если вы видите «Нет» рядом с «Можем ли мы написать?», Вам нужно будет обратиться к своему хосту, чтобы исправить разрешения для папки.

Автоматическая оптимизация кеша.

Разные параметры

Autoptimize имеет несколько различных настроек оптимизации. Если у вас возникают проблемы с загрузкой оптимизированных файлов CSS и JS на ваш сайт, возможно, вам придется изменить некоторые настройки, указанные ниже.

Разные оптимизации в Autoptimize.

Сохранить агрегированные скрипты / CSS как статические файлы

Мы рекомендуем включить этот параметр, чтобы сохранять агрегированные файлы как статические файлы локально.Вам может потребоваться отключить это, если ваш сервер не настроен для обработки сжатия и истечения срока действия файлов.

Сократить исключенные файлы CSS и JS

Мы рекомендуем включить этот параметр, чтобы все файлы CSS и JS были минимизированы. Однако, если вы заметили некоторые проблемы, связанные с минимизацией, в некоторых исключенных файлах CSS и JS, вы можете отключить эту опцию.

Также оптимизировать для зарегистрированных редакторов / администраторов

Мы рекомендуем включить это, чтобы гарантировать, что ресурсы оптимизированы для авторизованных редакторов и администраторов.Это важно, если вы тестируете параметры автоматической оптимизации как зарегистрированный пользователь.

Оптимизация изображения в Autoptimize

Autoptimize имеет встроенную интеграцию с ShortPixel для оптимизации изображений. В дополнение к настройке качества изображения интеграция Autoptimize также позволяет вам создавать и обслуживать версии ваших изображений WEBP.

Для пользователей Kinsta мы не рекомендуем использовать функцию оптимизации изображения в Autoptimize. Вместо этого мы рекомендуем напрямую использовать полнофункциональные плагины от ShortPixel или Imagify.С полным плагином у вас будет более детальный контроль над настройками оптимизации, включая перезапись изображений для использования тега , который необходим для поддержки WEBP на Kinsta.

Изображения с отложенной загрузкой с функцией автоматической оптимизации.

Autoptimize также включает функцию отложенной загрузки изображений. Мы рекомендуем включить эту функцию, чтобы повысить скорость загрузки страниц с большим количеством изображений. Когда включена отложенная загрузка, Autoptimize позволяет исключить определенные классы изображений и имена файлов из отложенной загрузки.

Параметр исключения полезен для изображений, таких как логотипы, значки социальных сетей и других важных элементов изображения, которые не следует загружать лениво. Если вы ищете решение, которое предлагает больший контроль над отложенной загрузкой, ознакомьтесь с нашим руководством по отложенной загрузке изображений и видео в WordPress.

Дополнительные оптимизации в Autoptimize

Дополнительные оптимизации в Autoptimize.

Google Шрифты

Autoptimize имеет несколько различных вариантов оптимизации шрифтов Google.Лучший вариант для вас будет зависеть от того, как ваш сайт использует шрифты Google.

  • Оставить как есть.
  • Удалить шрифты Google.
  • Скомбинировать и связать в голове.
  • Комбинирование и предварительная нагрузка в головке.
  • Асинхронно комбинируйте и загружайте шрифты с webfont.js.

Не рекомендуется использовать параметр «оставить как есть», поскольку он не дает преимущества в скорости.

Если шрифты Google Fonts не являются критически важным требованием для вашего сайта, их удаление и использование вместо них системного стека шрифтов может иметь огромное положительное влияние на скорость вашей страницы.

Если вы хотите сохранить шрифты Google на своем сайте, мы рекомендуем протестировать последние три варианта, чтобы определить, какой из них лучше всего подходит для вашего сайта.

Удалить смайлы

Эта опция автоматической оптимизации удаляет CSS и JavaScript, связанные с основными смайликами WordPress. Мы рекомендуем включить этот параметр, поскольку он помогает уменьшить размер страницы. Кроме того, большинство основных операционных систем поставляются со стеками шрифтов, которые включают смайлики. Конечно, есть и другие способы отключить эмодзи на вашем сайте WordPress.

Удалить строки запроса из статических ресурсов

Если вы хотите удалить строки запроса (например,? Ver =) из статических ресурсов, вы можете включить эту опцию. Удаление строк запроса не повлияет на время загрузки, но может помочь улучшить оценку вашего сайта в GTmetrix, Google Pagespeed и других службах тестирования производительности.

Предварительное подключение к сторонним доменам

Директива preconnect позволяет вашему браузеру подключаться к указанным доменам для обработки DNS-запросов и согласования SSL-подтверждения перед отправкой полного HTTP-запроса.

Например, если на вашем сайте есть изображение логотипа, которое обслуживается с https://site.kinsta.cdn.com/logo.png , вы можете указать Autoptimize добавить директиву preconnect для обработки начальных подключений DNS и SSL в элемент перед выполнением HTTP-запроса в элементе вашего HTML.

Вы можете использовать инструменты разработчика или инспектор вашего браузера, чтобы найти важные внешние домены для предварительного подключения. На приведенной ниже странице примера есть внешние запросы к следующим доменам.

  • https://cdn.brianli.com
  • https://www.google-analytics.com
  • https://www.googletagmanager.com

Эти три домена можно добавить в список предварительного подключения Autoptimize.

Найдите внешние ресурсы с помощью инструментов разработчика.

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

Предварительная загрузка специальных запросов
Директивы

Preload предписывают вашему веб-браузеру как можно скорее загрузить ресурс. Эта директива полезна для загрузки ресурсов, которые необходимы в самом начале процесса загрузки страницы. На практике предварительная загрузка часто используется для ускорения загрузки пользовательских шрифтов, загружая их до того, как они будут запрошены в CSS страницы.

Мы рекомендуем проконсультироваться с разработчиком относительно того, какие активы, если таковые имеются, предварительно загрузить на ваш сайт WordPress.Как и в случае со многими другими настройками, связанными с производительностью, предварительная загрузка слишком большого количества ресурсов может замедлить загрузку вашего сайта.

Асинхронные файлы JavaScript
Функция «асинхронные файлы JavaScript» в

Autoptimize позволяет указать определенные внешние файлы JavaScript для асинхронной загрузки с помощью флага async HTML. Хотя асинхронная загрузка файлов JS может повысить скорость загрузки страниц, мы рекомендуем провести соответствующее тестирование, чтобы убедиться, что это не влияет на работу сайта.

Если вы еще не используете Autoptimize, вы захотите добавить этот плагин оптимизации WordPress на свой сайт как можно скорее после прочтения этого руководства 🚀Нажмите, чтобы твитнуть

Сводка

Если вы знаете, как настроить его параметры, плагин Autoptimize — надежный вариант для пользователей WordPress, которые хотят повысить производительность сайта.

Обладая базовыми функциями, такими как оптимизация HTML и CSS, и более продвинутыми, такими как интеграция с CDN и возможностью указывать директивы preconnect и preload, Autoptimize имеет все необходимое для оптимизации производительности внешнего интерфейса вашего сайта WordPress.

Если вы хотите узнать больше об оптимизации WordPress и о том, как оптимизировать серверную часть своего сайта, обязательно ознакомьтесь с нашим подробным руководством по производительности WordPress.


Если вам понравилась эта статья, то вам понравится хостинговая платформа Kinsta WordPress.Ускорьте свой сайт и получите круглосуточную поддержку от нашей опытной команды WordPress. Наша инфраструктура на базе Google Cloud ориентирована на автоматическое масштабирование, производительность и безопасность. Позвольте нам показать вам разницу в Kinsta! Ознакомьтесь с нашими тарифами

Основные функции: Оптимизация изображения | Next.js

Примеры

Начиная с версии 10.0.0 , Next.js имеет встроенный компонент изображения и автоматическую оптимизацию изображения.

Компонент изображения Next.js, next / image , является расширением элемента HTML , разработанного для современной сети.

Автоматическая оптимизация изображений позволяет изменять размер, оптимизировать и обслуживать изображения в современных форматах, таких как WebP, если браузер поддерживает это. Это позволяет избежать отправки больших изображений на устройства с меньшим окном просмотра. Он также позволяет Next.js автоматически принимать будущие форматы изображений и передавать их браузерам, поддерживающим эти форматы.

Автоматическая оптимизация изображения работает с любым источником изображения. Даже если изображение размещено во внешнем источнике данных, таком как CMS, его все равно можно оптимизировать.

Вместо оптимизации изображений во время сборки Next.js оптимизирует изображения по запросу, когда их запрашивают пользователи. В отличие от генераторов статических сайтов и статических решений, время сборки не увеличивается, независимо от того, отправлено ли 10 изображений или 10 миллионов изображений.

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

Изображения всегда обрабатываются таким образом, чтобы избежать кумулятивного сдвига макета, ключевого элемента сети, который Google собирается использовать для ранжирования в поиске.

Чтобы добавить изображение в приложение, импортируйте компонент next / image :

  импорт изображения из 'next / image'

function Home () {
  возвращаться (
    <>
       

Моя домашняя страница

<Изображение src = "/ me.png" alt = "Изображение автора" ширина = {500} высота = {500} />

Добро пожаловать на мою домашнюю страницу!

) } экспорт по умолчанию домой

Просмотр всех свойств, доступных для компонента next / image .

В дополнение к использованию свойств, доступных для компонента next / image , вы можете дополнительно настроить оптимизацию изображения для более сложных случаев использования через next.config.js .

Домены

Чтобы включить оптимизацию изображений для изображений, размещенных на внешнем веб-сайте, используйте абсолютный URL-адрес для изображения src и укажите, какой доменов разрешено оптимизировать. Это необходимо для предотвращения злоупотреблений внешними URL-адресами. Когда загрузчик настроен на внешний сервис изображений, этот параметр игнорируется.

  module.exports = {
  изображений: {
    домены: ['example.com'],
  },
}
  

Погрузчик

Если вы хотите использовать облачного провайдера для оптимизации изображений вместо использования встроенной в Next.js оптимизации изображений, вы можете настроить загрузчик и префикс пути. Это позволяет использовать относительные URL-адреса для Image src и автоматически генерировать правильный абсолютный URL-адрес для вашего провайдера.

  module.exports = {
  изображений: {
    загрузчик: 'imgix',
    путь: 'https: // example.com / myaccount / ',
  },
}
  

Включены следующие облачные провайдеры для оптимизации изображений:

  • Vercel: работает автоматически при развертывании на Vercel, настройка не требуется. Узнать больше
  • Imgix: загрузчик: imgix
  • Cloudinary: загрузчик: cloudinary
  • Akamai: погрузчик: 'akamai'
  • По умолчанию: автоматически работает с next dev , next start или настраиваемым сервером

Если вам нужен другой провайдер, вы можете использовать загрузчик prop с next / image .

Загрузчик по умолчанию для компонента next / image не поддерживается при использовании next export . Однако подойдут и другие варианты загрузчика.

Ниже описан алгоритм кэширования для загрузчика по умолчанию. Для всех остальных загрузчиков обратитесь к документации вашего облачного провайдера.

Изображения оптимизируются динамически по запросу и сохраняются в каталоге / cache / images . Оптимизированный файл изображения будет использоваться для последующих запросов, пока не истечет срок его действия.Когда делается запрос, соответствующий кэшированному, но просроченному файлу, кешированный файл удаляется перед созданием нового оптимизированного изображения и кэшированием нового файла.

Срок действия (или, скорее, максимальный возраст) определяется заголовком Cache-Control вышестоящего сервера.

Если s-maxage находится в Cache-Control , он используется. Если s-maxage не найден, используется max-age . Если max-age не найден, используется 60 секунд.

Вы можете настроить deviceSizes и imageSizes , чтобы уменьшить общее количество возможных сгенерированных изображений.

Следующая конфигурация предназначена для расширенных вариантов использования и обычно не требуется. Если вы решите настроить указанные ниже свойства, вы переопределите любые изменения значений по умолчанию для Next.js в будущих обновлениях.

Размеры устройства

В некоторых случаях, когда вы знаете ожидаемую ширину устройства от пользователей вашего веб-сайта, вы можете указать список контрольных точек ширины устройства с помощью свойства deviceSizes .Эти значения ширины используются, когда компонент next / image использует layout = "responsive" или layout = "fill" , чтобы на устройстве, посещающем ваш веб-сайт, показывалось правильное изображение.

Если конфигурация не указана, используется значение по умолчанию, указанное ниже.

  module.exports = {
  изображений: {
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
  },
}
  

Размеры изображения

Список ширины изображения можно указать с помощью свойства imageSizes .Эти значения должны отличаться (обычно меньше) от значений, определенных в параметре deviceSizes , поскольку массивы будут объединены. Эти значения ширины используются, когда компонент next / image использует layout = "fixed" или layout = "intrinsic" .

Если конфигурация не указана, используется значение по умолчанию, указанное ниже.

  module.exports = {
  изображений: {
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}
  

Для получения дополнительной информации о дальнейших действиях мы рекомендуем следующие разделы:

Оптимизировать · Bootstrap v5.0

Lean Sass импорт

При использовании Sass в конвейере ресурсов убедитесь, что вы оптимизировали Bootstrap, добавив только @import необходимых вам компонентов. Ваши самые большие оптимизации, вероятно, будут происходить из раздела Layout & Components нашего bootstrap.scss .

  // Конфигурация
@import "функции";
@import "переменные";
@import "миксины";
@import "коммунальные услуги";

// Макет и компоненты
@import "корень";
@import "перезагрузка";
@import "тип";
@import "изображения";
@import "контейнеры";
@import "сетка";
@import "таблицы";
@import "формы";
@import "кнопки";
@import "переходы";
@import "выпадающий список";
@import "группа кнопок";
@import "nav";
@import "навигационная панель";
@import "карта";
@import "аккордеон";
@import "хлебные крошки";
@import "разбивка на страницы";
@import "значок";
@import "предупреждение";
@import "прогресс";
@import "список-группа";
@import "закрыть";
@import "тосты";
@import "модальный";
@import "подсказка";
@import "всплывающее окно";
@import "карусель";
@import "блесны";
@import "offcanvas";

// Помощники
@import "помощники";

// Утилиты
@import "утилиты / api";
  

Если вы не используете компонент, закомментируйте его или удалите полностью.Например, если вы не используете карусель, удалите этот импорт, чтобы сохранить некоторый размер файла в скомпилированном CSS. Имейте в виду, что между импортом Sass есть некоторые зависимости, которые могут затруднить пропуск файла.

Lean JavaScript

JavaScript

Bootstrap включает все компоненты в наших основных файлах dist ( bootstrap.js и bootstrap.min.js ) и даже нашу основную зависимость (Popper) с нашими файлами пакетов ( bootstrap.bundle.js и bootstrap. .bundle.min.js ). Пока вы настраиваете с помощью Sass, не забудьте удалить связанный JavaScript.

Например, если вы используете собственный пакет JavaScript, такой как Webpack или Rollup, вы должны импортировать только тот JavaScript, который планируете использовать. В приведенном ниже примере мы показываем, как просто включить наш модальный JavaScript:

  // Импортируйте именно то, что нам нужно

// импортируем 'bootstrap / js / dist / alert';
// импортируем 'bootstrap / js / dist / button';
// импортируем 'bootstrap / js / dist / carousel';
// импортируем 'bootstrap / js / dist / collapse';
// импортируем 'bootstrap / js / dist / dropdown';
импортировать 'bootstrap / js / dist / modal';
// импортируем 'bootstrap / js / dist / popover';
// импортируем 'bootstrap / js / dist / scrollspy';
// импортируем 'bootstrap / js / dist / tab';
// импортируем 'bootstrap / js / dist / toast';
// импортируем 'bootstrap / js / dist / tooltip';
  

Таким образом, вы не включаете JavaScript, который не собираетесь использовать для таких компонентов, как кнопки, карусели и всплывающие подсказки.Если вы импортируете раскрывающиеся списки, всплывающие подсказки или всплывающие окна, обязательно укажите зависимость Popper в файле package.json .

Экспорт по умолчанию

Файлы в bootstrap / js / dist используют экспорт по умолчанию , поэтому, если вы хотите использовать один из них, вам нужно сделать следующее:

  импорт модального окна из bootstrap / js / dist / modal

const modal = новый модальный (document.getElementById ('myModal'))
  

Автопрефиксатор .browserslistrc

Bootstrap зависит от Autoprefixer для автоматического добавления префиксов браузера к определенным свойствам CSS.Префиксы продиктованы нашим файлом .browserslistrc , который находится в корне репозитория Bootstrap. Настройка этого списка браузеров и перекомпиляция Sass автоматически удалит часть CSS из вашего скомпилированного CSS, если есть префиксы поставщика, уникальные для этого браузера или версии.

Неиспользуемый CSS

Требуется помощь с этим разделом, рассмотрите возможность открытия PR. Спасибо!

Хотя у нас нет готового примера использования PurgeCSS с Bootstrap, есть несколько полезных статей и пошаговых руководств, написанных сообществом.Вот несколько вариантов:

Наконец, в этой статье CSS Tricks о неиспользуемом CSS показано, как использовать PurgeCSS и другие подобные инструменты.

Minify и gzip

По возможности обязательно сжимайте весь код, который вы показываете своим посетителям. Если вы используете файлы дистрибутива Bootstrap, постарайтесь придерживаться минимизированных версий (обозначенных расширениями .min.css и .min.js ). Если вы собираете Bootstrap из исходного кода с помощью собственной системы сборки, обязательно реализуйте собственные минификаторы для HTML, CSS и JS.

Неблокирующие файлы

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

Если вы используете плагин Lighthouse в Google Chrome, возможно, вы наткнулись на FCP. Метрика First Contentful Paint измеряет время с момента начала загрузки страницы до отображения на экране любой части содержимого страницы.

Вы можете улучшить FCP, отложив некритичный JavaScript или CSS.Что это обозначает? Просто JavaScript или таблицы стилей, которые не должны присутствовать при первом отрисовке вашей страницы, должны быть помечены атрибутами async или defer .

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

Если вы хотите узнать об этом больше, об этом уже есть много отличных статей:

Всегда использовать HTTPS

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

Сайты

, обслуживаемые по HTTPS, также должны иметь доступ ко всем таблицам стилей, скриптам и другим ресурсам через HTTPS-соединения. В противном случае вы отправите пользователям смешанный активный контент, что приведет к потенциальным уязвимостям, при которых сайт может быть взломан путем изменения зависимости.Это может привести к проблемам с безопасностью и отображению предупреждений в браузере для пользователей. Независимо от того, получаете ли вы Bootstrap из CDN или обслуживаете его самостоятельно, убедитесь, что вы получаете доступ к нему только через HTTPS-соединения.

.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *