[优化] 性能优化

This commit is contained in:
HapeLee committed 2026-05-01 12:26:35 +08:00
1 parent 03d0528dd2
commit f309e03b23
32 files changed
+971 -313

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ description: Review existing Legado Jetpack Compose code for architecture, behav
Review existing Compose code before rewriting it. Focus on concrete defects, architectural drift, behavior risks, and missing verification, especially in early Compose screens that may predate the current MVI/UDF, Clean Architecture, and `MainActivity` navigation expectations.
Read `references/review-checklist.md` for the project-specific checklist and severity guidance.
Read `references/review-checklist.md` for the project-specific checklist, current Compose state/performance checks, and severity guidance.
## Workflow
@@ -39,11 +39,26 @@ Flag issues when:
- `Screen` functions own business state instead of receiving `state` and callbacks.
- `remember` / `rememberSaveable` stores source-of-truth data that should survive process or route recreation through ViewModel state.
- User-driven transient state that should survive recreation, such as a pending delete-confirmation target, is held with plain `remember` instead of `rememberSaveable` or ViewModel state.
- `LaunchedEffect` keys are unstable or cause repeated data loading, duplicate navigation, duplicate toasts, or repeated service calls.
- A long-lived `LaunchedEffect` collector captures parent callbacks or context-dependent values that can change without using `rememberUpdatedState`, unless the effect is intentionally keyed to restart.
- Flows are collected without lifecycle awareness in UI routes where `collectAsStateWithLifecycle()` should be used.
- List items lack stable keys where mutation, selection, or animation can make state attach to the wrong row.
- Heterogeneous lazy lists or grids provide `key` but omit `contentType`, reducing composition reuse quality when headers, rows, ads, loading items, or expanded content mix in the same lazy layout.
- Selection, search query, sorting, filtering, loading, and error states are not represented in a single coherent `UiState`.
- Derived values are recomputed expensively on every recomposition instead of living in ViewModel state or `remember(key)`.
- UI effects write list-derived consistency back into the ViewModel, such as pruning selection from `LaunchedEffect(uiState.items)`. Prefer deriving this in the ViewModel with `combine(...)` or reducing it when the data flow updates.
- State is hoisted higher than the lowest common owner, such as a top-level route collecting a child ViewModel flow only needed inside a conditional branch or one popup menu.
## Compose Stability and Collection Checks
Flag issues when:
- Collection-heavy `UiState` exposed to Compose uses ordinary Kotlin `List`, `Set`, or `Map` in hot paths. Kotlin 2.x strong skipping is helpful but does not make standard Kotlin collections stable to Compose.
- DAO or repository lists are passed directly through `UiState` to deep composables without conversion to `ImmutableList` / `ImmutableSet` / `ImmutableMap` or a stable UI model wrapper.
- Review recommendations imply replacing every internal collection. Keep the finding scoped to Compose-facing render state; temporary accumulators, sorting inputs, Room DAO signatures, and domain APIs can remain normal collections unless they are the actual recomposition boundary.
- Mutable collections such as `ArrayList`, `MutableList`, or mutable maps are stored in Compose state or ViewModel `UiState`.
- Entity classes from non-Compose modules are passed deeply through composables and cause visible recomposition churn; prefer stable UI render models if measurement or code shape shows this matters.
## Navigation and Compatibility Checks