Полуночные Зарисовки – Telegram
Полуночные Зарисовки
362 subscribers
11 photos
27 links
Моментами пишу о мыслях, Android и Kotlin

ЛС: @secundans
Download Telegram
Квиз закончился неоднозначно, поэтому попробую чуть подробнее описать, что будет в первом и втором случае.

Начнем с того, что ViewModel стабильный, так как пустой и никакого стейта внутри не держит, а значит все оптимизации, которые генерирует, Compose будут работать.

Разница будем именно в генерации кода для ссылки на функцию и лямбды, которые принимают аргументы. В данном случае value: Int

Для ссылки на функцию ничего не сгенерируется.

А вот лямбда будет обертнута в выражение.
rember(viewModel) { { value -> viewModel.doAction(value) }}
То есть в Compose, если лямбда захватывает переменные, то она будет оборачиваться в remember, если все захваченные переменные стабильные.
Выражение:
val modifier = Modifier
val modifierProvider = { modifier.fillMaxSize() }
Превратится в:
val modifier = Modifier
val modifierProvider = remember(modifier) { { modifier.fillMaxSize() } }
Только потому что Modifier стабильный.

В случае ссылки на функцию, если уберем value: Int в doAction
class ViewModel {
fun doAction() {...}
}
То мемоизация уже будет работать. А код сгенерируется следующий:
remember(viewModel, { viewModel::doAction }
Почему же так? Просто в Compose три года назад написали так, что если ссылка на функцию принимает аргументы, то она не оборачивается в remember. И там же коммент, что надо бы это поправить в будущем, но оно пока не наступило)
👍2🗿1
Скинул свои находки коллегам, а в ответ мне скинули доклад уважаемых людей из ex-Twitter.

Там 40ой минуте(или на 129 слайде) ровно такой же пример, но рекомендуют они использовать ссылки на функцию вместо лямбд.

Показалось странным, но они ссылаются на статью еще одного уважаемого человека, где изначально была рекомендация. На эту же статью ссылаются еще две по оптимизациям в Compose: первая и вторая

Произошел какой-то скам или я попал в матрицу? :) Давайте разбираться и доказывать.
На первой картинке код, который сгенерирует Compose Compiler. Все получается ровно так, как описывалось ранее: лямбда оборачивается в remember, а ссылка на функцию нет.

Второй скриншот уже того, как это будет в байткоде (добавил еще аргумент со строкой для очевидности)

И наконец то, как это может повлиять на практите. Compose ссылки на функцию проверяет не через equlas, а ссылочно, поэтому мы получаем (третий скриншот):
1. лишние рекомпозиции
2. лишнее создания ссылки на функцию на каждую рекомпозицию
🔥8
А что там по issues?

Из свежего нашел такой - как low priority штуку все таки будут фиксить.

Почему тогда везде предлагают использовать ссылки на функцию?
У меня есть несколько объяснений этому:
1. Никто просто не проверил и лычки staffов в крупных компаниях хорошо сработали :)
2. Возможно раньше, когда в Kotlin Compiler был старый backend, это работало, а эта рекомендация тянется с тех пор. Но потом когда на стримах компилятор переписывали на IR, то этот случай пропустили?

Что же касается статьи, на которую много ссылок, то там же есть ссылка на github, где уже заведен одинокий issue на использование ссылки на функцию :)

Upd. Пофикшено тут, но теперь следите за context recievers или включайте strong skipping mode)
👏4
С большим опозданием, но все же опубликовал исходный код с доклада.

Там самые разные компиляторные плагины, такие как:
- подсветка рекомпозиций
- логирование причин рекомпозиций
- удаление вызовов функции sourceInformation
- генерация/удаление/отображение testTag
- анализ стабильности параметров composable функций

Все компиляторные плагины подключаются к проекту как gradle plugin. Можно все по отдельности, а можно вместе - так удобнее настраивать.

В проверках стабильности параметров поддержаны самые последние обновления Compose Compiler, а именно возможность задавать в файле классы, которые надо пропустить в проверках. Подробнее писали тут.

Кроме этого есть ещё idea plugin. Правда в виде jar, так как получил отказ при попытке публикации в JetBrains Marketplace.
Он умеет отображать какие testTag будут сгенерированы компиляторным плагином, а так же проверять стабильность параметров функций и отображать ошибку в редакторе кода. Конечно, не на 100%, как это в компиляторном плагине сделано, но, думаю, в большинстве случаев правильно.

Ну и получил несколько просьб по поводу detekt правила для проверки параметров функций. Его тоже добавил. И там же есть возможность исключать классы, которые не нужно проверять.

Если будут проблемы или вопросы - пишите. Попробуем решить)

github.com/VKCOM/vkompose
🔥28
Подлодка

Тут относительно недавно был сезон про оптимизации UI. О своих впечатлениях и о том, что интересного подчерпнул, написал в чате @devex_and_dpe

Podlodka Android Crew #11
🔥12👍3