11 November 2018

Заглядываем под капот нового Gmail

Website developmentJavaScriptClient optimizationGoogle Chrome

Полгода назад Google представила обновленную версию своего почтового сервиса. Несмотря на то что многие пользователи были недовольны редизайном, в том числе и на Хабре, это теперь основной интерфейс для пользователей.


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


Исходные данные


Для начала, нужно понять, с чем мы имеем дело. В Google Chrome Devtools встроен инструмент Lighthouse, который строит простой и понятный отчет о производительности вашего сайта. В нем Gmail получает двойку за производительность (из максимальных 100 баллов!)



Если честно, это не тот результат, который ожидаешь от продукта Google. Тем не менее, посмотрим на эту ситуацию детальнее. Отключим кеш, и загрузим интерфейс Gmail с включенными devtools. На вкладке Network будут показаны все запросы, сделанные для загрузки этой страницы. Получилось 6.9 Мб. Это внушительный размер, учитывая, что даже Youtube, еще один недавно обновленный сервис, загружает всего 2 Мб ресурсов.


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

Теперь попробуем посмотреть на загрузку страницы в замедленной съемке. В документации Google Chrome, объясняется, как это сделать. Получим набор скриншотов с разных этапов загрузки страницы:



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


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


Блокируем ресурсы


Теперь посмотрим на список загружаемых скриптов:



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


Опытным путем выяснилось, что запросы на https://mail.google.com/_/scs/* являются критичными для работы интерфейса, а вот следующие запросы можно заблокировать:


  • www.gstatic.com/og/*Google API Сlient Library, билиотека для запросов к сервисам Google
  • ssl.gstatic.com/inputtools/*Google Input Tools – виджет экранной клавиатуры
  • hangouts.google.com — отвечает за виджет handgouts

Помимо этих запросов, установленный у меня AdBlock уже блокировал запросы на https://play.google.com/log, их мы в расчет не берем, так как они не делались и до начала экспериментов с блокировками.

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


Смотрим в профайлер


Итак, мы минимизировали загрузку ресурсов как могли, но страница все равно грузится долго. Надо посмотреть, что же происходит в течение этих 4 секунд. Тут нам на помощь придет встроенный в Chrome профайлер. Он показывает нам такую картинку:



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


Рассматриваем оставшийся код


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


По итогам просмотра нашлось следующее:


  • Код очень сильно обфусцирован. Скорее всего, использовался Google Closure Compiler в Advanced Mode. То есть, разработчики Gmail выжали максимум из современных технологий минификации.
  • В коде собираются метрики производительности, так что разработчики должны быть в курсе, о том, насколько медленно загружается интерфейс у пользователей.
  • Исходники содержат полифиллы для Promise, Map, Set и других современных API, которые могли бы не грузиться в современные браузеры.
  • Код Gmail написан на Google Closure Libary

На последнем пункте стоит остановится поподробнее. Closure Library – это фреймворк для разработки интерфейсов, появившийся в 2009 году, и с тех пор мало изменился. Например, там до сих пор поддерживается Ajax через ActiveXObject: который нужен только для IE6 и ниже, хотя текущий Gmail официально поддерживает только IE 10+.


Кроме того, UI-часть Closure основывается на иерархии классов в "лучших" традициях GWT – подходе, c большим количеством многословных абстракций, которые, очевидно, влияют на производительность рендеринга. Современные UI-фреймворки (React или Vue, например) предлагают намного более легковесные абстракции – компоненты – которые намного дешевле в рендеринге.


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


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


Выводы


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


  • В легаси проектах обычно встречается ненужный код, например, хаки для устаревших браузеров. Пересматривайте свои исходники и избавляйтесь от тех вещей, которые стали уже неактуальными.
  • Абстракции не бесплатны. Если вы хотите решить задачу, используя изящный архитектурный паттерн, сначала подумайте, а не будет ли это слишком тяжелым инструментом, может есть вариант попроще.
  • Не загружайте второстепенные элементы на страницу изначально. В данном случае, виджет Hangouts мог бы не блокировать канал, мешая загрузке основных ресурсов Gmail, а загружаться в фоне, уже после отрисовки основной функциональности.
  • Не стоит пренебрегать современными технологиями. В них могут быть принципиально новые решения для ваших задач, более производительные и удобные. Странно увидеть в 2018 году редизайн сервиса от Google, в котором не используются веб-компоненты, за которые Google так активно топит на конференциях.
  • Ну и не забывайте уделять внимание измерениям производительности для своих проектов. Для этого сейчас имеется много удобных инструментов, как браузерные, так и для запуска в CI.
Tags:ковыряние в чем нибудь непонятномgoogleтакие дела
Hubs: Website development JavaScript Client optimization Google Chrome
+134
57k 142
Comments 94