Pull to refresh

Comments 6

Вычисление метрики fmp, не учитывает ещё одну вещь – Браузер, который во время работы
занимается парсингом и отрисовкой и выполнением джс (ну и борьбой за ресурсы). Такой код:

requestAnimationFrame(function() { 
  var renderTreeFormed = performance.now(); // начало
  requestAnimationFrame(function() {
    var fmp = performance.now(); // окончание
    // видимость && отправка(окончание - начало)
  });
});


Будет работать верно в случае, когда страница распарсилась и всё происходит не во время загрузки страницы. Иначе с точки зрения работы браузера тут есть 2 ошибки:
— у браузерного парсера нет обязательств, движок в любой момент может прервать парсинг и отрисовать картинку (причем в хромиумы нацелены чаще рисовать, а не быстрее парсить большие документы – это хорошо видно на открытии github, когда огромная простыня кода отрисовывается долго, а вот firefox наоборот).
— ваш xxx рядом с которым стоит метка точно не распарсится, если он еще не загрузился ¯\_(ツ)_/¯ т.е. браузер может распарсить открывающий тег следующего div, а потом приходит очередной BeginFrame, и парсить больше нечего — тогда точно (ну почти) нарисуется еще один белый кадр, и второй rAF засечет время перед ним.

Т.е. фундаментально метрика показывает правду исключая влияние парсинга страницы. Но если вдруг у вас страница состоит больше, чем из примеров HelloWorld, то скорее всего тут будет ошибка. Проверить её можно достаточно просто:

Пример было:

<script>window.performance.mark('fmp_body')</script>
<div class="body">
    xxx
</div>


Попробуйте сделать так:

<script>window.performance.mark('fmp_body')</script>
<div class="body" data-test="вот тут очень много ненужных символов, которые будут влиять на парсинг">
    <!-- или вот сюда можно наставить -->
    xxx
</div>


Могу сказать результат: метрика будет улучшаться, но это false-positive улучшение, т.к. пользователю не стало лучше) В итоге контент xxx не нарисуется, а метрика будет отправляться и стремиться к 0, тк белый экран отрисовывать достаточно дёшево.

Ну или посмотреть и поподбирать параметры страницы и посмотреть внутри Rendering chrome://tracing как и что происходит.

да, все верно, но метрика fmp_body у нас стоит перед концом самого боди:


<body>
<div class="root" data-test="вот тут очень много ненужных символов, которые будут влиять на парсинг">
    <!-- или вот сюда можно наставить -->
   Куча контента, который рисуется на сервере
</div>
<script>window.performance.mark('fmp_body')</script>
</body>

На картинке:


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

Речь тогда про вложенные requestAnimationFrame. Они ведь будут где-то вызываться? Сами таймарки ок, а вот значения которые лягут в window.globalVars.performance.fmp могут зависеть от тех искажений о которых писал выше.

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


От RAF как раз отказались из-за искажений

Привет!) Спасибо за интересную статью.

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

Привет!
Не писал в этой статье, потому что ответом будет: "it depends" :) В общем случае, мы начинаем профилировать страницу на предмет проблем.


Самый ТОП проблем у нас был из-зи большого (огромного) количества мусорных объектов.
Скриншотов у меня уже не осталось, но вот пример:
время рендера на сервере увеличивается до 120мс, гидрейта драмматически больше.
По логам смотрим requiresId пользователя, смотрим на объем данных отправляемых ему.
Смотрим вызовы GC через profile — для node.js и\или браузера. Поняв, что он вызывается крайне часто, собираем JS Heap.
В хипе выясняется, что у нас каждый компонент генерировал свой объект переводов (сами переводы инкапсулируются в redux стор при запросе страницы, но каждый компонент добирал себе переводы). Компонентов очень много, особенно на поисковых страницах.
Итого меняем систему переводов, делаем общий прокси, который по ключу валидирует доступ к объекту переводов. Избавляемся от кучи объектов. Для того, чтобы понимать порядок, на странице поиска резюме у нас активно более 9000 react компонентов.
Время рендера на сервере падает до 90мс, при гидрейте видим также падение на графиках

Sign up to leave a comment.