Недавно я читал и пробовал разные вещи, касающиеся оптимизации события макета браузера (не рисовать или составлять), но именно макет.
Тестовое приложение, которое я использую
У меня есть очень упрощенное приложение, похожее на социальные сети, которое просто отображает некоторую информацию о профиле для пользователя и список обоев (каждый с двумя ответами, с отступом справа). Вы можете проверить его код в этой песочнице . И я предлагаю проверить само приложение во всем окне браузера здесь . Первоначально отрисовывается 1000 стенных постов, щелкнув Показать больше внизу страницы, вы добавите еще 1000, и количество элементов DOM будет соответствовать количеству, используемому в тестах ниже. Вы можете проверить шаг вновь отрисованных настенных постов из fakeApi. js в строке 79 , но по крайней мере 2000 настенных постов должны быть загружены, чтобы соответствовать среде в тесте. Там есть поле для комментариев, которое появляется под стеной, когда вы нажимаете ---- Ответить ---- для данного сообщения.
Моя цель
Я хочу сократить время создания дерева макета / слоя обновления для довольно большого дерева DOM при вводе в поле для комментариев (показывается только по одному за раз ниже заданной стены), но я хочу оптимизировать без использования виртуализации сейчас.
Настройка
- Процессор машины - мобильная версия (на ноутбуке) Intel Core i7-6700HQ@2.60-3.50Ghz
- DOM-элементы ~ 45k
- Браузер - Chrome 80.0.3987.163
- Технический стек фронтэнда - React, Bootstrap только для CSS, чистый CSS
Измеренные результаты
График производительности и кольцевая диаграмма для таймфрейма набора текста
![enter image description here](https://i.stack.imgur.com/MUS6T.png)
Как вы видите на временной шкале производительности, при вводе нескольких символов в поле для комментариев есть Макет (фиолетовым цветом под желтым цветом, который является событием нажатия клавиши), а сразу после этого другой фиолетовый блок - Обновить дерево слоев . Время для каждого нажатия одной клавиши:
- Макет ~ 12 мс
- Обновление дерева слоев ~ 21-22 мс
- Средний FPS при наборе текста - 20FPS
Вещи, которые я пробовал для оптимизации
- Реакция, приложение уже оптимизировано с shouldComponentUpdate и React.memo (для функциональных компонентов)
- Удалено e.target.innerText ссылка в обработчике события нажатия клавиши и даже весь обработчик
- Используйте БЭМ-подход для пользовательского CSS ( в активах / сайте. css), сохраняя селекторы простыми, 1-уровень
- Используйте абсолютную позицию для поля комментария
- Удалите некоторые текстовые узлы (уменьшили их примерно на 20 КБ)
- Удалите весь пакет bootstrap CSS (приложение, конечно, не выглядело хорошо )
- Удалены все изображения
- Используется will-change: преобразуйте для области комментариев, чтобы перевести ее в отдельный макет Показатели слоев, но все же слоев показали, что весь слой DOM (слой прокрутки) также обновляется после ввода.
Пример использования приложений Simlar
Из Конечно, Facebook - самый близкий из всех, о чем я могу думать. Я записал некоторые статистические данные для этого, на главной странице с новостной лентой я прокрутил вниз, чтобы элементов DOM было достаточно, и в конце я остановился на ~ 45k , как в тестовом приложении. Результаты на кольцевой диаграмме были интересны ... Как вы видите, при рендеринге с одинаковым количеством символов выполнялось гораздо меньше операций, несмотря на одинаковое количество элементов DOM. Конечно, обработчики событий FB предположительно намного сложнее, чем мои, которые просто добавляют еще один комментарий, если нажата клавиша Enter (что приводит к увеличению времени обработки событий в FB). Также при вводе в поле для комментариев (из первых элементов, появившихся в новостной ленте) FB достиг 37FPS , что также значительно лучше.
Вопрос: Как я могу улучшить время раскладки для клавиш, возможно ли это вообще? Может быть, причина в разной HTML структуре? Вы можете видеть, что FB содержит больше вложенных элементов в местах, тестовое приложение имеет меньше вложенности, но отображается больше отдельных элементов публикации. Также, если мне нужно добавить больше деталей, пожалуйста, прокомментируйте! :)