Непредсказуемые последствия оптимизации производительности Chrome

в 20:18, , рубрики: Google Chrome, indexeddb, javascript, асинхронность, разработка сайтов

Привет! В последнем релизе Chrome обнаружил очень необычное поведение браузера. Это поведение вызывало новые необычные ошибки в моём веб-скрипте. И я решил поделиться, как оптимизируют производительность Chrome, и про то, с какими необычными последствиями можно столкнуться.

Непредсказуемые последствия оптимизации производительности Chrome - 1

Поехали.

Аномалия с которой мы столкнулись, выглядит так: 

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

Причина аномалии

Это выглядит очень странно. Такое ощущение, что Хром полностью блокирует старую вкладку при переключении на новую. 
Оказалось, что недавно (релиз 57, 14 марта, 2017) Хромиум выпустил релиз с значительной оптимизацией производительности. Одна из оптимизаций — сокращение ресурсов, выделенных для работы фоновых вкладок. Пруф: https://blog.chromium.org/2017/03/reducing-power-consumption-for.html
Эта оптимизация и блокирует фоновую вкладку сразу (!) после открытия новой. Причём снижение производительности касается не только работы джаваскрипта, но и прочего API. Например, в нашем случае, начали фантастически медленно работать операции на IndexedDB в браузере. 

Как исправить

Чтобы обойти такие “особенности поведения”, нам пришлось вызывать собственные асинхронные коллбэки синхронно, и уменьшить зависимость от системных асинхронных API.

Автор: Kaigorodov

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js