Инструменты:
Choreographer
Что ищем:
I/Choreographer: Skipped 42 frames! The application may be doing too much work on its main thread.
Проблемы и решения:
a) Переиспользование View:
class ProductViewHolder(view: View) : RecyclerView.ViewHolder(view) {
// Инициализация View один раз в конструкторе
private val imageView = view.findViewById<ImageView>(R.id.product_image)
private val titleView = view.findViewById<TextView>(R.id.product_title)
fun bind(product: Product) {
// Только обновление данных
}
}
b) Оптимизация layout:
merge
и include
Решение:
Glide.with(context)
.load(product.imageUrl)
.placeholder(R.drawable.placeholder)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.override(TARGET_WIDTH, TARGET_HEIGHT) // Оптимальный размер
.into(holder.imageView)
Дополнительно:
a) Дифференциальные обновления:
val diffCallback = object : DiffUtil.ItemCallback<Product>() {
override fun areItemsTheSame(old: Product, new: Product) = old.id == new.id
override fun areContentsTheSame(old: Product, new: Product) = old == new
}
val adapter = ListAdapter(diffCallback)
b) Пагинация данных:
viewModel.products.pagingData
.cachedIn(viewModelScope)
.collectLatest { pagingData ->
adapter.submitData(pagingData)
}
a) Вынос тяжелых операций:
// Плохо:
holder.itemView.setOnClickListener {
calculateStatistics() // Тяжелая операция в UI потоке
}
// Хорошо:
holder.itemView.setOnClickListener {
viewModelScope.launch {
withContext(Dispatchers.Default) {
calculateStatistics()
}
}
}
b) Оптимизация анимаций:
RecyclerView.ItemAnimator
Настройки в XML:
<RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layerType="hardware"
android:hasFixedSize="true"/>
Команды для тестирования:
adb shell dumpsys gfxinfo <package_name> framestats
adb shell setprop debug.layout false
recyclerView.itemAnimator = DefaultItemAnimator().apply {
supportsPredictiveItemAnimations = true
}
onDraw()
без аллокацийcanvas.clipRect()
для частичного рендерингаДля плавного скроллинга списка товаров необходимо комплексно подойти к оптимизации: от улучшения работы адаптера и ViewHolder до грамотной загрузки изображений и управления памятью. Ключевые моменты — минимизация работы в UI потоке, эффективное переиспользование View и оптимизация layout-файлов. После всех изменений важно проверить результат на реальных устройствах, особенно низкого ценового сегмента.