Skip to content

性能优化建议

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=-Xmx2g

Kotlin 编译器选项

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 5

APK 体积优化

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 缓存
  • ☑️ 及时释放资源
  • ☑️ 避免内存泄漏
  • ☑️ 监控内存使用

性能优化是持续的过程,需要根据实际场景选择合适的策略,并通过监控数据验证效果。