Ember.js: Потеря производительности между версиями 2.X и 3.X

Созданный на 14 мая 2020  ·  28Комментарии  ·  Источник: emberjs/ember.js

Между версиями 2.X и 3.X потеря производительности составляет 60%. Смотрите журналы времени рендеринга внизу скриптов в разных версиях. Примеры упрощены для демонстрации чистой производительности рендеринга без каких-либо стилей и вычислений.

2. 18 время рендеринга скрипки : ~ 500 мс
3.18 время рендеринга

Bug Regression Rendering

Самый полезный комментарий

Просто хотел вкратце рассказать об этом:

Мы запустили тест TracerBench, аналогичный тому, который @runspired настроил с помощью emberobserver.com , которое является одним из наших обычных тестовых приложений, чтобы увидеть, не произошло ли кипение лягушки (например, небольшие изменения производительности, которые были незначительными от версии к версии). версия, но подвел к большому сдвигу). Вот результаты этого теста:

уголек-наблюдатель-2.18-3.18.pdf

Из этих результатов видно, что есть два вполне определенных скачка:

  1. Ember 3.0 - Ember 3.1
  2. Ember 3.16 - Ember 3.17

Регресс в версии 3.17 связан с обновлением виртуальной машины Glimmer, и в настоящее время мы сосредоточены на его сокращении, поскольку оно было довольно недавним и, вероятно, скоро начнет влиять на приложения, которые обновляются в цикле LTS.

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

В общем, сценарий {{each}} который был поднят в начале этой проблемы, похоже, регрессировал больше и по-разному, чем emberobserver.com. После того, как мы углубимся в регрессию 3.17, мы сосредоточимся на оптимизации {{each}} чтобы увидеть, что можно улучшить в целом.

Спасибо всем за терпение!

Все 28 Комментарий

После нескольких запусков в Chrome 81 на моем компьютере я получил:

2.18 лучшее время: 283 мс
3. 18 лучшее время: 471 мс

Это работало с закрытыми DevTools.

Затем я преобразовал твиддл 3.18 в Ember Octane:

  • Использование собственных классов для компонентов и контроллеров.
  • Использование @tracked без использования @computed .
  • Преобразование компонента t-r компонент, состоящий только из шаблона, потому что ему не требовался вспомогательный класс.
  • Использование синтаксиса угловых скобок при вызове компонентов.
  • Использование именованных аргументов и this. там, где это необходимо в шаблонах.

После этого лучшее время, которое я получил от 3.18.1, составило 276 мс, так что значимое улучшение по сравнению с числом 2.18.

Однако эти тесты производительности не были особенно научными, и я не исследовал, какое изменение было наиболее важным с точки зрения производительности.

Профилирование в твиддле довольно подвержено ошибкам, можем ли мы перенести на обычное репозиторий приложения ember-cli (используя ветку для каждой из двух версий) для профилирования?

@rwjblue Я получаю те же результаты в обычном приложении ember-cli. Можно протестировать здесь

@ richard-winey Возможно, стоит подумать об улучшениях, но проблема в том, что в обеих версиях не используется устаревший код и наблюдается потеря производительности, что кажется неприемлемым.

  • Использование только-шаблона-компонента может привести к повышению производительности, но tr определенно понадобится вспомогательный класс для вычисления некоторых внутренних стилей. Пример был упрощен, чтобы продемонстрировать проблему.
  • После всего рефакторинга вы получите 2% (283 мс -> 276 мс) прирост производительности против 2,18. Рассмотрим обновление существующего приложения 2.18 до 3.X. Рефакторинг всех компонентов только для того, чтобы получить эти 2% прироста, определенно невозможен.

@barisnisanci Согласен, я не имел в виду, что такой рефакторинг необходим, чтобы избежать значительного снижения производительности при обновлении. Это был эксперимент, чтобы увидеть, есть ли какое-либо влияние от использования современных соглашений, поскольку это могло бы помочь изолировать проблему и / или позволить ее решить, если необходимо.

Было бы интересно узнать, в каком выпуске (-ах) Ember произошло снижение производительности, также протестировав промежуточные версии LTS, то есть 3.4, 3.8, 3.12 и 3.16.

@barisnisanci Ember ember serve по умолчанию работают в режиме разработки. Во время разработки включается множество дополнительных инструментов, которые могут серьезно снизить производительность. Обычно мы не рассматриваем это как регресс или проблему, если только она не настолько серьезна, чтобы повлиять на эргономику разработчика. Итак, во-первых, я бы дважды проверил, что вы используете обе версии в производственном режиме.

Я загрузил ваш пример и одновременно обслужил версии 2.8 и 3.18 в рабочем режиме. Я обнаружил, что, возможно, вы правы, в среднем время между двумя вспомогательными операциями (это то, что здесь измеряется) кажется больше в версии 3.18, чем в версии 2.8. Это основано на том, что я взял несколько образцов на своем рабочем ноутбуке без множества элементов управления, поэтому трудно сказать наверняка, но, глядя на это, может быть небольшое изменение.

Однако, глядя на другие более значимые показатели, я не вижу изменений. Если посмотреть на общее время рендеринга контента, в целом они выглядят примерно одинаково. Время до первой краски, например, примерно такое же.

Screen Shot 2020-05-18 at 11 10 15 AM

Важно помнить, что у нас много работы, распределенной по множеству мест, и когда мы вносим изменения, иногда эта работа перемещается, но не влияет на общие показатели. Вот почему мы используем TracerBench для проверки изменений производительности, потому что он предназначен для учета общих этапов рендеринга и учета всех изменений на уровне _macro_, а не на уровне _micro_, как время между запусками помощников.

Вероятно, нам следует попробовать провести тест TracerBench в ближайшее время в течение более длительного периода времени, просто чтобы проверить эти результаты и убедиться, что мы не поскользнулись в целом (мы обычно используем его для небольших изменений, где мы ожидаем потенциальных регрессий). Мы также должны просто попытаться запустить его через равные промежутки времени, чтобы мы могли видеть линию тренда.

@pzuraq Только что обновил репозиторий с помощью rowsCount:300 и columnsCount:20 разница должна быть более заметной. Оба работают с --environment production

  • 3.18 Первая отрисовка: 3489 мс
    3 18
  • 2.18 Первая краска: 2814 мс
    2 18

Также заметил, что JS Heap никогда не выпускался в 3.18, но, возможно, немного не повезло с GC.

Я могу добавить привязки стилей, внедрение сервисов, более тяжелые вычисления для компонентов вместо увеличения количества, однако они могут затенять основную проблему.

Как вы упомянули, общие показатели намного важнее, чем незначительные изменения. Однако незначительные отличия в нашем случае приводят к значительному падению производительности. Начальное время рендеринга нашего коммерческого приложения увеличилось с 15 до 20 секунд после обновления до версии 3.18. Надеюсь, вы рассмотрите регрессию с точки зрения процентных, а не небольших изменений в миллисекундах.

Наша компания страдает от этой проблемы. Мы обновили версию ember с 2.18 до 3.16. затем время рендеринга увеличилось более чем на 50 процентов. Когда мы используем сложные структуры, разница во времени рендеринга становится более очевидной, чем небольшие изменения в миллисекундах. Есть новости по этой проблеме? У нас есть тесты, показывающие увеличение времени рендеринга на 50%. Решил пока держаться на 2.18. Мы можем подумать о смене фреймворка, если это потребует серьезного рефакторинга.

@ Caglayan06 Не могли бы вы подтвердить, что работаете с производственным флагом? Просто хочу удостовериться, что цифры от яблока к яблоку!

@ Caglayan06 - Вряд ли это что-то одно. Воспроизведение, предоставленное @barisnisanci, может не соответствовать тому, что показывает профиль вашего приложения. Можете ли вы воспроизвести общую проблему в своем приложении (или подтвердить, что пример репозитория @barisnisanci , приведенный выше, представляет ваши сценарии использования / выходные данные профиля)?

Есть ли у вас какие-либо комментарии к последнему сообщению @barisnisanci в этой теме?
У нас были аналогичные проблемы с производительностью после обновления 2.18 до 3.16. У нас была потеря производительности 40%. Мы понизили рейтинг до 3,12, но смогли сэкономить только 20% от этого убытка, что все еще не так хорошо, как 2,18. Рефакторинг, как вы упомянули ранее, занимает почти столько же времени, сколько и переключение фреймворка. Ждать каких-либо действий по этому поводу?

недавно мы обновились до ember 3.16.8, у нас нет тестового примера производительности и мы не обнаружили очевидных проблем с производительностью прямо сейчас.
но я хотел бы с нетерпением ждать решения и закрытия проблем с производительностью в ближайшее время.
>

PS больше памяти и процессора используется в ie11. иногда это вызывает сбой ie11.

@ Caglayan06 - Вряд ли это что-то одно. Воспроизведение, предоставленное @barisnisanci, может не соответствовать тому, что показывает профиль вашего приложения. Можете ли вы воспроизвести общую проблему в своем приложении (или подтвердить, что пример репозитория @barisnisanci , приведенный выше, представляет ваши сценарии использования / выходные данные профиля)?

Пример @rwjblue @barisnisanci для меня работает так же, как говорит @barisnisanci .

@ Caglayan06 Не могли бы вы подтвердить, что работаете с производственным флагом? Просто хочу удостовериться, что цифры от яблока к яблоку!

@scottmessinger да, мы работаем с производственным флагом. Наши результаты аналогичны результатам @barisnisanci .

Мы улучшили структуру нашего кода. Это увеличило производительность, но все же не так быстро, как версия ember 2.18. Если мы внесем эти изменения в 2.18, мы добьемся лучших результатов.

Мы не можем пересмотреть нашу систему кода, чтобы изменить синтаксис кода 3.16 и новые функции. Для нас это слишком дорого, потому что наш проект огромен. Наверное, рефакторинг всего проекта дороже, чем изменение фреймворка. Будут ли предприняты какие-либо действия по этой проблеме?

Будут ли предприняты какие-либо действия по этой проблеме?

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

Пример @rwjblue @barisnisanci для меня работает так же, как говорит @barisnisanci .

@ Caglayan06 - Хм, я не об этом спрашивал. Я знаю, что пример @barisnisanci работает, я прошу вас просмотреть его / профилировать / сравнить характеристики производительности с вашим приложением и посмотреть, соответствует ли _ способ, которым работает пример (и работает он медленнее), вашему приложению.

@ Caglayan06 - Хм, я не об этом спрашивал. Я знаю, что пример @barisnisanci работает, я прошу вас просмотреть его / профилировать / сравнить характеристики производительности с вашим приложением и посмотреть, соответствует ли _ способ, которым работает пример (и работает он медленнее), вашему приложению.

@rwjblue Я интегрировал репозиторий @barisnisanci в наше приложение, он дал аналогичные результаты. Когда мы изменили версию с 3.16 на 3.12, наша производительность повысилась.
Но все же не так быстро, как версия 2.18.

В нашем приложении несколько примеров:
2977

В следствии:
Даже мы улучшили структуру кода, общее среднее время рендеринга;
2.18 время рендеринга: 1x сек
3.16 время рендеринга: 1,6x сек.
3.12 время рендеринга: 1,4x сек.

В 3.20 есть обновление виртуальной машины, поэтому мне интересно, поможет ли это здесь

@NullVoxPopuli не повезло с 3.20.0-beta.2 FP: 3,4 секунды (то же самое с 3,18)

Поскольку 3.12 показывает лучшие результаты, я думаю, проблема может быть связана с автоматическим отслеживанием. Также # 18225 может быть связан с учетом общего падения производительности приложения в тестах 3.12 -> 3.16 @ Caglayan06 .

Хм. Интересно, сколько накладных расходов на обратную совместимость

Несколько общих вопросов:

  • Какое значение имеет флаг необязательной функции асинхронного наблюдателя?
  • Использует ли рассматриваемое приложение QP?
  • Отрицательная скорость влияет на все маршруты или только на некоторые?

Несколько общих вопросов:

  • Какое значение имеет флаг необязательной функции асинхронного наблюдателя?
  • Использует ли рассматриваемое приложение QP?
  • Отрицательная скорость влияет на все маршруты или только на некоторые?

@rwjblue

  1. Флаг асинхронных наблюдателей не используется. Я думаю, что по умолчанию 3.12 установлено значение false. На 3.16 тестировал с обоими особой разницы не имеет.
  2. QP широко используются на основных маршрутах. Однако падение производительности наблюдается и без них.
  3. Затронуты все маршруты

Также репозиторий примеров не использует ничего из вышеперечисленного, но все еще медленнее в 3.X. Время рендеринга могло постепенно увеличиваться в каждой второстепенной версии, поэтому мы не можем точно определить проблему.

Отчеты Tracerbench показывают, что с 2.18 до 3.18 действительно регрессирует на ~ 17% для этого сценария, но также улучшается вместо регресса на ~ 18%, если выполняется преобразование в компонент glimmer.

2.18–3.18 Других изменений нет
Компоненты от 2.18 до 3.18 + Octane + Glimmer

У меня есть собственный форк, в который я добавил для этого автоматизированный бегун, и я работаю над его улучшением, чтобы мы могли быстро сузить круг по версии / фиксации, чтобы найти, где произошла регрессия. https://github.com/runspired/version-performance/runs/801596557

Большое спасибо @runspired за настройку этих тестов! Теперь, когда у нас есть надежная настройка для надежного измерения регрессии, мы можем продолжить работу по устранению этих проблем.

Для контекста @krisselden разработал TracerBench как инструмент специально для комплексного тестирования производительности, и мы использовали его для внутренних внутренних рефакторов, таких как реализация декораторов и автоматическое отслеживание / отслеживание изменений . В LinkedIn мы используем его для тестирования наших приложений перед каждым обновлением Ember, и мы не наблюдали такого уровня регресса.

Однако это определенно могло быть то, что мы упустили. В конце концов, мы тестируем определенные приложения, у которых есть определенные варианты использования и поведения. Это могло быть проблемой, которую мы не заметили, потому что наши тестовые приложения не использовали регрессивную функциональность, такую ​​как воспроизведение @barisnisanci . Также возможно, что даже если мы исправим проблемы в этом воспроизведении, мы не сможем исправить другие, поэтому, если вы столкнетесь с регрессом, мы определенно будем признательны за воспроизведение для вашего варианта использования. Мы будем работать над тем, чтобы упростить настройку TracerBench, чтобы вы могли протестировать ее локально и отправить репро, например

Мы собираемся разобраться, в чем именно заключается проблема, и найти решение. Самое главное, что этот уровень регрессии не является приемлемым для _любой_ API, даже если мы видим , скорость с Octane. Если пользователи не могут обновляться и переключаться постепенно, значит, мы не все поднимаемся на гору вместе.

Следите за обновлениями, мы дадим вам знать, как только разберемся!

Большое спасибо @runspired за его крутой крутой https://github.com/TracerBench/tracerbench-compare-action

Просто хотел вкратце рассказать об этом:

Мы запустили тест TracerBench, аналогичный тому, который @runspired настроил с помощью emberobserver.com , которое является одним из наших обычных тестовых приложений, чтобы увидеть, не произошло ли кипение лягушки (например, небольшие изменения производительности, которые были незначительными от версии к версии). версия, но подвел к большому сдвигу). Вот результаты этого теста:

уголек-наблюдатель-2.18-3.18.pdf

Из этих результатов видно, что есть два вполне определенных скачка:

  1. Ember 3.0 - Ember 3.1
  2. Ember 3.16 - Ember 3.17

Регресс в версии 3.17 связан с обновлением виртуальной машины Glimmer, и в настоящее время мы сосредоточены на его сокращении, поскольку оно было довольно недавним и, вероятно, скоро начнет влиять на приложения, которые обновляются в цикле LTS.

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

В общем, сценарий {{each}} который был поднят в начале этой проблемы, похоже, регрессировал больше и по-разному, чем emberobserver.com. После того, как мы углубимся в регрессию 3.17, мы сосредоточимся на оптимизации {{each}} чтобы увидеть, что можно улучшить в целом.

Спасибо всем за терпение!

Можем ли мы получить последнюю информацию по этому вопросу? Прошло около двух месяцев.

Да! Прошло два долгих месяца, мы усердно работали над этой проблемой и продолжаем наши рефакторинги в Glimmer VM, которые хорошо согласились с этим.

Как я упоминал ранее, мы сосредоточились на двух отдельных наборах исправлений:

  1. Рефакторы с низким уровнем риска попадут в выпуск 3.20 LTS для людей, пытающихся перейти на следующий LTS
  2. Рефакторы крупномасштабного производства должны стать хозяевами для повышения производительности в долгосрочной перспективе

Для первого набора исправлений мы реорганизовали приличный объем классического кода Ember, так как это был код, который больше всего пострадал. Таким образом, мы смогли снизить общую потерю производительности с 3,16–3,20 до статистически незначимых величин, основываясь на тестировании в наших внутренних приложениях в LinkedIn. К сожалению, у меня не было возможности запустить тесты против Ember Observer, но я думаю, что это будет аналогичный результат, поскольку они обычно довольно близко отслеживают друг друга.

Что касается второго набора исправлений, мы добавили их относительно недавно, поскольку многие из них были очень большими, в том числе:

  • Обновление виртуальной машины для полного внутреннего отслеживания на основе автоматического отслеживания, избавление от лишних тегов
  • Рефакторинг виртуальной машины для использования одного мономорфного ссылочного класса вместо множества реализаций с большой сложностью
  • Удаление неиспользуемого режима компиляции AoT

Результаты отличные!

results.pdf

Это сравнение текущего мастера Ember с Ember 2.18, с приведенным выше воспроизведением из @barisnisanci. Как уже упоминалось ранее, это тест для очень специфического варианта использования, который также слишком прост. Мы _не_ увидели такого резкого улучшения ни в одном из наших тестов реальных приложений, в целом оно было гораздо скромнее. Надеюсь, это поможет @barisnisanci и другим приложениям, и нам определенно интересно услышать от них

Протестированное репо выше с основной веткой ember. Тем не менее первая краска: (3035,7 мс) кажется больше, чем 2,18 (2752,3 мс)

Также протестирован на нашей продукции с различными версиями углей. Основная ветвь в нашем приложении кажется на% 25-40 медленнее, чем 3,12. С результатами ниже мы не можем обновить ember без серьезного рефакторинга.

perf

@barisnisanci Извините, похоже, это так! Как я уже упоминал ранее в этой беседе, нам нужно будет воспроизвести эти результаты статистически обоснованным образом, чтобы иметь возможность A. подтвердить проблему, а B. итеративно продвигаться к улучшениям и лучшему решению в целом. Я рекомендую либо добавить TracerBench в ваше приложение, чтобы вы могли запустить эти тесты самостоятельно, либо сделать еще одно воспроизведение, демонстрирующее проблему сейчас на master .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги