⚠️ 5 ошибок, которые Android-разработчики до сих пор допускают при работе с Jetpack Compose
Jetpack Compose — это не столько новый набор инструментов для создания пользовательского интерфейса, сколько новая парадигма, и с ней приходит необходимость отказаться от некоторых старых привычек разработки Android-приложений.
1️⃣ Вызов функций внутри Composable
Это самая большая проблема, снижающая производительность, которую я вижу в приложениях Compose:
@Composable
fun UserProfile(userId: String) {
val userData = fetchUserData(userId) // DON'T DO THIS
Text(text = userData.name)
}
Обратите внимание, что вызов функции запускает каждую перекомпозицию. Всегда используйте LaunchedEffect или запоминайте это с помощью соответствующих ключей.
@Composable
fun UserProfile(userId: String) {
var userData by remember { mutableStateOf(null) }
LaunchedEffect(userId) {
userData = fetchUserData(userId)
}
userData?.let { user ->
Text(text = user.name)
}
}
2️⃣ Игнорирование CompositionLocals
Разработчики в итоге создают кошмар с передачей свойств через посредников, вместо того чтобы использовать CompositionLocal для данных темы, пользовательских настроек или внедрения зависимостей.
// Instead of passing theme through 5 levels of composables
val LocalAppTheme = compositionLocalOf { AppTheme() }
@Composable
fun MyApp() {
CompositionLocalProvider(LocalAppTheme provides currentTheme) {
MainScreen()
}
}
3️⃣ Чрезмерное использование поднятия состояния (State Hoisting)
Не все состояния должны находиться на верхнем уровне. Если что-то является локальным состоянием пользовательского интерфейса, например, развернутое/свернутое состояние, состояние фокуса или анимация, храните это в компоненте, в котором оно используется.
@Composable
fun ExpandableCard() {
// This state doesn't need to be hoisted
var isExpanded by remember { mutableStateOf(false) }
Card(
modifier = Modifier.clickable { isExpanded = !isExpanded }
) {
// Card content
}
}
4️⃣ Неправильное понимание ключей remember()
Запоминание без ключей приводит к устаревшим данным и сбивающему с толку поведению:
@Composable
fun ProductList(products: List) {
// Wrong: remembers first products list forever
val processedProducts = remember { processProducts(products) }
// Right: recomputes when products change
val processedProducts = remember(products) { processProducts(products) }
}
5️⃣ Создание объектов в теле композабл
Это приводит к пустой работе, поскольку каждая перекомпозиция создает новые объекты, как в этом примере:
@Composable
fun AnimatedIcon() {
// Creates new AnimationSpec every recomposition
val animationSpec = tween(durationMillis = 300)
// Better: remember expensive objects
val animationSpec = remember { tween(durationMillis = 300) }
}
📌 Лучшие вакансии для мобильных разработчиков
🐸 Библиотека мобильного разработчика
#буст #MiddlePath #Kotlin
Jetpack Compose — это не столько новый набор инструментов для создания пользовательского интерфейса, сколько новая парадигма, и с ней приходит необходимость отказаться от некоторых старых привычек разработки Android-приложений.
1️⃣ Вызов функций внутри Composable
Это самая большая проблема, снижающая производительность, которую я вижу в приложениях Compose:
@Composable
fun UserProfile(userId: String) {
val userData = fetchUserData(userId) // DON'T DO THIS
Text(text = userData.name)
}
Обратите внимание, что вызов функции запускает каждую перекомпозицию. Всегда используйте LaunchedEffect или запоминайте это с помощью соответствующих ключей.
@Composable
fun UserProfile(userId: String) {
var userData by remember { mutableStateOf(null) }
LaunchedEffect(userId) {
userData = fetchUserData(userId)
}
userData?.let { user ->
Text(text = user.name)
}
}
2️⃣ Игнорирование CompositionLocals
Разработчики в итоге создают кошмар с передачей свойств через посредников, вместо того чтобы использовать CompositionLocal для данных темы, пользовательских настроек или внедрения зависимостей.
// Instead of passing theme through 5 levels of composables
val LocalAppTheme = compositionLocalOf { AppTheme() }
@Composable
fun MyApp() {
CompositionLocalProvider(LocalAppTheme provides currentTheme) {
MainScreen()
}
}
3️⃣ Чрезмерное использование поднятия состояния (State Hoisting)
Не все состояния должны находиться на верхнем уровне. Если что-то является локальным состоянием пользовательского интерфейса, например, развернутое/свернутое состояние, состояние фокуса или анимация, храните это в компоненте, в котором оно используется.
@Composable
fun ExpandableCard() {
// This state doesn't need to be hoisted
var isExpanded by remember { mutableStateOf(false) }
Card(
modifier = Modifier.clickable { isExpanded = !isExpanded }
) {
// Card content
}
}
4️⃣ Неправильное понимание ключей remember()
Запоминание без ключей приводит к устаревшим данным и сбивающему с толку поведению:
@Composable
fun ProductList(products: List) {
// Wrong: remembers first products list forever
val processedProducts = remember { processProducts(products) }
// Right: recomputes when products change
val processedProducts = remember(products) { processProducts(products) }
}
5️⃣ Создание объектов в теле композабл
Это приводит к пустой работе, поскольку каждая перекомпозиция создает новые объекты, как в этом примере:
@Composable
fun AnimatedIcon() {
// Creates new AnimationSpec every recomposition
val animationSpec = tween(durationMillis = 300)
// Better: remember expensive objects
val animationSpec = remember { tween(durationMillis = 300) }
}
📌 Лучшие вакансии для мобильных разработчиков
🐸 Библиотека мобильного разработчика
#буст #MiddlePath #Kotlin