性能优化建议
KMP 项目的性能优化涉及编译时间、运行时性能和包体积三个方面。本文提供实用的优化策略。
编译时间优化
Gradle 配置优化
properties
# gradle.properties
# 启用配置缓存
org.gradle.configuration-cache=true
# 并行构建
org.gradle.parallel=true
# 增加堆内存
org.gradle.jvmargs=-Xmx4g -XX:+HeapDumpOnOutOfMemoryError
# 启用构建缓存
org.gradle.caching=true
# Kotlin 增量编译
kotlin.incremental=true
kotlin.incremental.js=true
# Kotlin 守护进程
kotlin.daemon.jvmargs=-Xmx2gKotlin 编译器选项
kotlin
// build.gradle.kts
kotlin {
sourceSets.all {
languageSettings {
// 启用实验性 API(减少警告编译)
optIn("kotlin.RequiresOptIn")
}
}
targets.all {
compilations.all {
kotlinOptions {
// 减少冗余检查
allWarningsAsErrors = false
// 增量编译
freeCompilerArgs += listOf(
"-Xbackend-threads=4" // 并行编译
)
}
}
}
}模块化拆分
shared/
├── core/ # 核心工具(变化少)
├── data/ # 数据层
├── domain/ # 业务层
├── feature-auth/ # 认证功能
└── feature-main/ # 主功能优势:
- 仅重新编译修改的模块
- 并行编译多个模块
- 清晰的依赖关系
运行时性能优化
避免过度分配
kotlin
// ❌ 不推荐:频繁创建对象
fun processUsers(users: List<User>): List<String> {
return users.map { user ->
"${user.name} - ${user.email}" // 每次都创建新字符串
}
}
// ✅ 推荐:使用 StringBuilder
fun processUsers(users: List<User>): List<String> {
return users.map { user ->
buildString {
append(user.name)
append(" - ")
append(user.email)
}
}
}缓存策略
kotlin
class UserRepository {
private val cache = mutableMapOf<String, User>()
suspend fun getUser(id: String): User {
return cache.getOrPut(id) {
api.fetchUser(id)
}
}
fun clearCache() {
cache.clear()
}
}懒加载
kotlin
class AppConfig {
// ❌ 立即初始化
val database = createDatabase()
// ✅ 懒加载
val database by lazy { createDatabase() }
}协程优化
kotlin
// 避免阻塞主线程
suspend fun loadData(): List<Data> = withContext(Dispatchers.IO) {
// 耗时操作
database.query()
}
// 并发请求
suspend fun loadMultiple(): List<User> = coroutineScope {
val requests = ids.map { id ->
async(Dispatchers.IO) {
api.fetchUser(id)
}
}
requests.awaitAll()
}iOS Framework 优化
减小 Framework 体积
kotlin
// build.gradle.kts
kotlin {
iosTargets.forEach { target ->
target.binaries.framework {
isStatic = true // 静态库比动态库小
// 启用优化
freeCompilerArgs += listOf(
"-Xoverride-konan-properties=minification.enabled=true",
"-opt" // 优化级别
)
// 仅导出必要的类
export(project(":shared:api"))
}
}
}按架构分离
kotlin
// 仅为需要的架构构建
./gradlew linkReleaseFrameworkIosArm64 # 真机
./gradlew linkReleaseFrameworkIosX64 # Intel 模拟器
./gradlew linkReleaseFrameworkIosSimulatorArm64 # M1 模拟器Fat Framework 优化
bash
# 创建通用 Framework (仅测试用)
xcodebuild -create-xcframework \
-framework shared.framework-iphoneos \
-framework shared.framework-iphonesimulator \
-output shared.xcframework
# 生产环境:App Store 自动处理架构Android 优化
ProGuard/R8 配置
proguard
# shared/proguard-rules.pro
# 保留必要的类
-keep class com.example.shared.api.** { *; }
# 移除日志
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
}
# 优化
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
-optimizationpasses 5APK 体积优化
kotlin
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
// 分包
splits {
abi {
isEnable = true
reset()
include("arm64-v8a", "armeabi-v7a")
}
}
}数据库优化
SQLDelight 索引
sql
-- User.sq
CREATE INDEX user_email_idx ON User(email);
CREATE INDEX post_user_id_idx ON Post(user_id);
CREATE INDEX post_created_at_idx ON Post(created_at DESC);批量操作
kotlin
// ✅ 使用事务批量插入
database.transaction {
users.forEach { user ->
queries.insertUser(user)
}
}
// ❌ 逐条插入(慢)
users.forEach { user ->
database.transaction {
queries.insertUser(user)
}
}分页查询
sql
-- 大数据集分页
SELECT * FROM User
LIMIT :pageSize OFFSET :offset;网络优化
Ktor Client 配置
kotlin
HttpClient {
// 连接池
engine {
threadsCount = 4
pipelining = true
}
// 超时配置
install(HttpTimeout) {
connectTimeoutMillis = 10_000
requestTimeoutMillis = 30_000
}
// 重试机制
install(HttpRequestRetry) {
retryOnServerErrors(maxRetries = 3)
exponentialDelay()
}
}请求合并
kotlin
class BatchingRepository {
private val pendingRequests = mutableListOf<String>()
suspend fun getUsersBatched(ids: List<String>): List<User> {
return api.fetchUsersBatch(ids) // 一次请求获取多个
}
}内存优化
及时释放资源
kotlin
class ImageLoader {
private val cache = LruCache<String, Bitmap>(cacheSize)
fun clear() {
cache.evictAll()
}
}
// 在适当时机清理
override fun onTrimMemory(level: Int) {
if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
imageLoader.clear()
}
}避免内存泄漏
kotlin
// ❌ 持有 Activity 引用
class Presenter(private val activity: Activity)
// ✅ 使用接口
interface View {
fun showData(data: String)
}
class Presenter(private val view: View)性能监控
自定义指标
kotlin
object PerformanceMonitor {
private val metrics = mutableMapOf<String, Long>()
inline fun <T> measure(name: String, block: () -> T): T {
val start = System.currentTimeMillis()
return block().also {
val duration = System.currentTimeMillis() - start
metrics[name] = duration
if (duration > 100) {
Logger.w { "$name took ${duration}ms" }
}
}
}
fun getMetrics() = metrics.toMap()
}
// 使用
val users = PerformanceMonitor.measure("fetchUsers") {
repository.getUsers()
}Firebase Performance
kotlin
// androidMain
import com.google.firebase.perf.FirebasePerformance
val trace = FirebasePerformance.getInstance().newTrace("fetch_users")
trace.start()
try {
val users = repository.getUsers()
trace.putMetric("user_count", users.size.toLong())
} finally {
trace.stop()
}优化检查清单
编译时间:
- ☑️ 启用 Gradle 配置缓存
- ☑️ 使用 Gradle 构建缓存
- ☑️ 模块化拆分
- ☑️ 增加 JVM 堆内存
运行时性能:
- ☑️ 避免频繁对象创建
- ☑️ 使用缓存减少重复计算
- ☑️ 协程替代回调
- ☑️ 懒加载非必需资源
包体积:
- ☑️ 启用代码混淆(R8/ProGuard)
- ☑️ 移除未使用代码
- ☑️ 优化图片资源
- ☑️ 使用静态 Framework(iOS)
内存:
- ☑️ 使用 LRU 缓存
- ☑️ 及时释放资源
- ☑️ 避免内存泄漏
- ☑️ 监控内存使用
性能优化是持续的过程,需要根据实际场景选择合适的策略,并通过监控数据验证效果。