Поделиться через


Минимизация влияния расширения на время загрузки страницы

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

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

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

Профилирование скрипта содержимого расширения

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

Профилирование скрипта содержимого с помощью средств разработки Microsoft Edge

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

В этом разделе вы узнаете, как использовать средство "Производительность " в средствах разработки для профилирования скрипта содержимого расширения. Дополнительные сведения о средстве производительности см. в статье Анализ производительности среды выполнения (учебник).

  1. Чтобы открыть Средства разработки, щелкните веб-страницу правой кнопкой мыши и выберите пункт Проверить. Или нажмите клавиши CTRL+SHIFT+I (Windows, Linux) или COMMAND+OPTION+I (macOS). Откроется devTools.

  2. В средствах разработки на панели действий выберите вкладку Производительность (значок средства производительности). Если эта вкладка не отображается, выберите Дополнительные инструменты (значок дополнительных инструментов) >Производительность.

  3. Чтобы начать запись профиля производительности, нажмите кнопку Запись (значок записи).

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

    Записанный профиль производительности, отображаемый в средстве повышения производительности средств разработки

  5. Чтобы найти события производительности, вызванные скриптом содержимого, нажмите клавиши CTRL+F в Windows/Linux или COMMAND+F в macOS. Текстовое поле Найти появится в нижней части средства Производительность .

  6. Введите Evaluate script и нажмите клавишу ВВОД , пока средство производительности не выделит события производительности, вызванные скриптом содержимого. Вы узнаете, что нашли правильное событие производительности, если в метке Скрипт на панели Сводка отображается имя скрипта содержимого:

    Событие Оценки производительности скрипта из-за скрипта содержимого расширения, выполняемого во время загрузки страницы

Профилирование скрипта содержимого с помощью средства трассировки Edge

Средство трассировки Edge, доступное edge://tracing по URL-адресу, — это мощное средство, которое может обеспечить подробный анализ производительности расширения. В этом разделе вы узнаете, как использовать средство трассировки Edge, чтобы понять влияние расширения на время загрузки страницы. Дополнительные сведения об этом средстве трассировки, основанном на средстве Perfetto , см. в статье Пользовательский интерфейс Perfetto в документации по трассировке Perfetto.

  1. Чтобы открыть средство трассировки Edge, откройте новую вкладку или окно и перейдите к edge://tracing. Откроется пользовательский интерфейс трассировки.

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

  3. Нажмите кнопку Выбрать параметры вручную . Отобразится список категорий.

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

    • Расширения
    • v8
    • средства разработки
    • средства разработки. временная шкала
  5. Нажмите кнопку Записать . Диалоговое окно закрывается, и средство трассировки Edge начинает запись трассировки.

  6. Откройте новую вкладку и загрузите веб-страницу, на которую влияет расширение. Средство трассировки собирает данные о влиянии расширения на производительность веб-страницы.

  7. Откройте вкладку, на которой запущено средство трассировки Edge, и нажмите кнопку Остановить . В средстве появятся новые сведения о трассировке.

Фильтрация результатов

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

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

  1. На странице нажмите клавиши edge://tracingSHIFT+ESC , чтобы открыть диалоговое окно Диспетчер задач браузера .

  2. В диалоговом окне Диспетчер задач браузера найдите вкладку, соответствующую веб-странице, на которую повлияло расширение, и запишите номер в столбце Идентификатор процесса . Закройте диалоговое окно.

  3. На панели инструментов средства трассировки Edge щелкните Процессы, а затем установите флажок, соответствующий идентификатору процесса, который вы записали. Снимите все остальные флажки.

  4. В правом верхнем углу средства трассировки Edge щелкните поле поиска, введите ScriptInjection::InjectJS и нажмите клавишу ВВОД , пока на нижней панели не будет выделено событие, соответствующее вашему расширению.

    На нижней панели отображается время начала и общая длительность события:

    Средство трассировки Edge, показывающее событие внедрения скрипта

Поиск ключевых событий

Чтобы продолжить анализ влияния на производительность скрипта содержимого расширения на веб-странице, найдите следующие ключевые события в событии ScriptInjection::InjectJS :

  • v8.compile — показывает время компиляции скрипта содержимого.
  • v8.run — указывает время выполнения скомпилированного скрипта.

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

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

Вы можете использовать отложенные методы загрузки и разделения кода, чтобы свести к минимуму объем кода, выполняемого в скрипте содержимого:

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

  • Разделение кода — это процесс разделения кода на небольшие блоки или модули, которые можно загружать отдельно или по требованию.

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

  • Точки входа загружаются при каждой загрузке страницы.

  • Динамические импорты загружаются только по запросу, например, когда пользователь взаимодействует с веб-страницей или с пользовательским интерфейсом расширения:

    // When the user clicks on the page.
    document.addEventListener("click", async () => {
      // Dynamically load the code that's needed to handle the click event.
      const module = await import("chunk.js");
      // Do something with the newly loaded module code.
    });
    

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

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

Чтобы настроить страницы и кадры, на которые загружаются скрипты содержимого, определите шаблоны URL-адресов в файле манифеста matches расширения с помощью свойства в content_scripts разделе . Дополнительные сведения см. в статье Внедрение скриптов в скрипты содержимого в документации по расширениям Chrome.

Api расширений chrome.scripting также можно использовать для программного внедрения скрипта содержимого на веб-страницу. Этот API позволяет внедрять скрипт содержимого на основе действий пользователя, содержимого веб-страницы или логики расширения. Дополнительные сведения см. в статье chrome.scripting в документации по расширениям Chrome.

При настройке места загрузки скриптов содержимого используйте следующие рекомендации.

  • Используйте наиболее конкретные шаблоны URL-адресов, возможные matches для свойств и exclude_matches в файле манифеста расширения. Например, если скрипт содержимого должен выполняться только на веб-страницах example.com домена, используйте https://example.com/* вместо "*://*/*.

  • Чтобы управлять выполнением скрипта содержимого только в кадре верхнего уровня или во вложенных кадрах веб-страницы, которая соответствует шаблону all_frames URL-адреса, используйте свойство в файле манифеста расширения.

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

    • Если скрипту содержимого требуется доступ к модели DOM или ее изменение во вложенных кадрах, задайте для параметра значение all_framestrue. Это увеличивает объем кода, выполняемого на веб-странице.

Загрузка скриптов содержимого только при необходимости

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

Настройка времени загрузки скриптов содержимого в файл манифеста расширения

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

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

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

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

Чтобы программно загружать скрипты содержимого во время выполнения, только при необходимости используйте chrome.scripting API . chrome.scripting API обеспечивает больший контроль над временем и местом загрузки скрипта содержимого.

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

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

Избегайте блокировки вызовов или длительных синхронных задач

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

Блокирующие вызовы — это операции JavaScript, которые препятствуют выполнению другого кода до завершения. Например, использование XMLHttpRequestAPI , localStorageили chrome.storage.sync (синхронных) предотвращает выполнение веб-страницы другого кода.

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

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

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

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

// Asynchronously load data from a JSON file.
fetch("data.json")
  .then(response => response.json())
  .then(data => {
    // Do something with the data.
  });

Асинхронное хранение данных

Чтобы хранить данные в расширении, используйте chrome.storage.local API вместо localStorage API, который является синхронным API. chrome.storage.local API является асинхронным и может более эффективно хранить и извлекать данные, не влияя на производительность веб-страницы, на которой запущено расширение. Например, можно использовать chrome.storage.local.get метод для получения ранее сохраненного значения, а затем использовать результат в функции обратного вызова:

chrome.storage.local.get("key", result => {
  // Do something with the result.
});

Асинхронная отправка сообщений

Для взаимодействия между скриптом содержимого и фоновой страницей расширения или другим сценарием содержимого используйте chrome.runtime.sendMessage методы или chrome.tabs.sendMessage . Эти методы являются асинхронными и неблокирующими и позволяют отправлять и получать сообщения между различными частями расширения. Для обработки ответа на сообщения можно использовать обещания или обратные вызовы. Например, можно использовать метод для отправки chrome.runtime.sendMessage сообщения на фоновую страницу, а затем использовать возвращенный Promise объект для обработки ответа:

chrome.runtime.sendMessage({type: 'request', data: 'some data'})
  .then(response => {
    // Do something with the response.
  });

Выполнение интенсивных задач вне потока main

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

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

Для взаимодействия между скриптом содержимого и веб-рабочей ролью postMessage используйте API и onmessage . Например, чтобы создать новую рабочую веб-роль и отправить ей сообщение, используйте следующий код:

// Create a new Web Worker.
cons worker = new Worker('worker.js');

// Send a message to the Web Worker.
worker.postMessage({type: 'task', data: 'some data'});

Для получения сообщений в веб-рабочей роли и отправки сообщений обратно:

// Listen to messages that are sent to the Web Worker.
onmessage = event => {
  const type = event.data.type;
  const data = event.data.data;

  // Do something with the type and data.
  // ...

  // Send a message back.
  postMessage({type: 'result', data: 'some result'});
};

См. также

Документация по расширению Chrome:

MDN: