From 3a501f4530243b33276828dfd4f4e4549c12a935 Mon Sep 17 00:00:00 2001 From: Ben Trengrove Date: Mon, 31 Oct 2022 07:59:43 +1100 Subject: [PATCH] Allow InterestsItem to be skipped on recomposition Add a benchmark for topics state change --- .../interests/InterestsActions.kt | 12 ++++ .../TopicsScreenRecompositionBenchmark.kt | 61 +++++++++++++++++++ .../feature/interests/TabContent.kt | 7 ++- 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 benchmark/src/main/java/com/google/samples/apps/nowinandroid/interests/TopicsScreenRecompositionBenchmark.kt diff --git a/benchmark/src/main/java/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt b/benchmark/src/main/java/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt index 474aefe74..3ee8a442e 100644 --- a/benchmark/src/main/java/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt +++ b/benchmark/src/main/java/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt @@ -19,6 +19,7 @@ package com.google.samples.apps.nowinandroid.interests import androidx.benchmark.macro.MacrobenchmarkScope import androidx.test.uiautomator.By import androidx.test.uiautomator.Direction +import androidx.test.uiautomator.Until fun MacrobenchmarkScope.interestsScrollTopicsDownUp() { val topicsList = device.findObject(By.res("interests:topics")) @@ -33,3 +34,14 @@ fun MacrobenchmarkScope.interestsScrollPeopleDownUp() { device.waitForIdle() peopleList.fling(Direction.UP) } + +fun MacrobenchmarkScope.interestsWaitForTopics() { + device.wait(Until.hasObject(By.text("Accessibility")), 30_000) +} + +fun MacrobenchmarkScope.interestsToggleBookmarked() { + val topicsList = device.findObject(By.res("interests:topics")) + val checkable = topicsList.findObject(By.checkable(true)) + checkable.click() + device.waitForIdle() +} diff --git a/benchmark/src/main/java/com/google/samples/apps/nowinandroid/interests/TopicsScreenRecompositionBenchmark.kt b/benchmark/src/main/java/com/google/samples/apps/nowinandroid/interests/TopicsScreenRecompositionBenchmark.kt new file mode 100644 index 000000000..69f02d235 --- /dev/null +++ b/benchmark/src/main/java/com/google/samples/apps/nowinandroid/interests/TopicsScreenRecompositionBenchmark.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.interests + +import androidx.benchmark.macro.CompilationMode +import androidx.benchmark.macro.FrameTimingMetric +import androidx.benchmark.macro.StartupMode +import androidx.benchmark.macro.junit4.MacrobenchmarkRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.uiautomator.By +import com.google.samples.apps.nowinandroid.PACKAGE_NAME +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class TopicsScreenRecompositionBenchmark { + @get:Rule + val benchmarkRule = MacrobenchmarkRule() + + @Test + fun benchmarkStateChangeCompilationBaselineProfile() = + benchmarkStateChange(CompilationMode.Partial()) + + private fun benchmarkStateChange(compilationMode: CompilationMode) = + benchmarkRule.measureRepeated( + packageName = PACKAGE_NAME, + metrics = listOf(FrameTimingMetric()), + compilationMode = compilationMode, + iterations = 10, + startupMode = StartupMode.WARM, + setupBlock = { + // Start the app + pressHome() + startActivityAndWait() + + // Navigate to interests screen + device.findObject(By.text("Interests")).click() + device.waitForIdle() + } + ) { + interestsWaitForTopics() + repeat(3) { + interestsToggleBookmarked() + } + } +} diff --git a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt b/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt index b34181d96..aeab2d3e4 100644 --- a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt +++ b/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt @@ -46,14 +46,15 @@ fun TopicsTabContent( contentPadding = PaddingValues(top = 8.dp) ) { topics.forEach { followableTopic -> - item { + val topicId = followableTopic.topic.id + item(key = topicId) { InterestsItem( name = followableTopic.topic.name, following = followableTopic.isFollowed, description = followableTopic.topic.shortDescription, topicImageUrl = followableTopic.topic.imageUrl, - onClick = { onTopicClick(followableTopic.topic.id) }, - onFollowButtonClick = { onFollowButtonClick(followableTopic.topic.id, it) } + onClick = { onTopicClick(topicId) }, + onFollowButtonClick = { onFollowButtonClick(topicId, it) } ) } }