Улучшение использования памяти переднего плана в 30 раз при загрузке карусели


Во втором квартале 2020 года мы провели технический рефакторинг на странице впечатлений, переписав его на React и использовав REST API. Но в процессе реализации мы обнаружили интересную проблему.

На странице впечатлений около 20 каруселей, каждая из которых содержит не менее 60 плиток. Таким образом, страница будет отображать более 1200 событий, включая соответствующую информацию, такую ​​как их заголовок, рейтинг пользователей, одновременные пользователи и миниатюры. В каждой карусели щелчок правой прокрутки отправит запрос на загрузку следующей партии опытов, если их будет больше. Затем новые данные, полученные в результате запроса, будут добавлены в карусель, что означает добавление дополнительных узлов в DOM и отображение большего количества эскизов в браузере. Использование памяти в браузере будет расти по мере того, как пользователи прокручивают страницу для запроса дополнительных данных, а затем UX замедляется и начинает отставать.

Профиль памяти

Мы можем использовать инструменты разработчика Chrome, чтобы профилировать эту проблему. Первый снимок делается при первоначальной загрузке страницы, а второй — после того, как пользователь щелкает следующую прокрутку в одной карусели 12 раз. Мы видим увеличение использования памяти почти на 9,7 МБ за счет более 100 строковых узлов и увеличенного рендеринга эскизов.

Решение

Когда карусель прокручивается, пользователи просматривают элементы только из окна карусели. Например, на ноутбуке с разрешением 1920 × 1080 в полноэкранном браузере каждый раз будет отображаться только ~ 9 элементов. Следовательно, нет необходимости отображать все невидимые узлы и эскизы вместе или переносить больше данных, возвращаемых из запроса, в DOM.

Итак, идея в том, что после того, как мы в первый раз извлекаем необработанные данные из запроса API, мы строим массив той же длины, готовящийся к рендерингу в DOM. Внутри массива рендеринга мы можем заполнить данные, достаточные только для заполнения дисплея и перехода к следующему. Остальная часть массива будет заполнена только тогда, когда окно дисплея будет прокручено близко к нему. Дадим два индекса для записи диапазона данных рендеринга: рендерингStartIndex и рендерингEndIndex. Мы устанавливаем курсор, чтобы указать, какая начальная позиция в списке видна. При прокрутке нам нужно постоянно обновлять курсор до индекса первого видимого элемента. Прежде чем анимация прокрутки будет завершена, нам нужно будет проверить, находится ли следующий курсор внутри массива данных рендеринга. По размеру окна карусели и размеру карточки мы можем легко определить, сколько видимых элементов поместится в окне отображения. Затем нам нужно убедиться, что элементы из текущего и следующего окна находятся внутри диапазона массива данных рендеринга. Если нет, мы берем элементы из необработанных данных, чтобы заполнить пустой список, а также очищаем данные до позиции курсора. Это будет применяться, когда пользователи прокручивают вправо или влево. Когда пользователи прокручивают вправо, получая больше данных в фоновом режиме, мы будем заполнять необработанные данные каждый раз после получения новых данных. Однако необработанные данные не будут задействованы в рендеринге страницы.

Вот как это выглядит с улучшением:

Профиль памяти

Давайте снова посмотрим на Инструменты разработчика Chrome. Как и раньше, первый снимок делается в инициализированное время, а второй — после 12-кратной прокрутки вправо. Теперь загрузка 100+ элементов стоит всего 0,3 МБ увеличенной памяти по сравнению с 9,7 МБ ранее.

Что дальше?

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

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

— — —

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

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

© 2021 Корпорация Роблокс. Roblox, логотип Roblox и Powering Imagination являются нашими зарегистрированными и незарегистрированными товарными знаками в США и других странах.



Источник: https://blog.roblox.com

Вам может понравиться...

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