精选文章

30. 启动优化

2018-03-21 · 启动

30. 启动优化

启动优化的目标是“冷启动更短、首屏更快、任务更少”。关键是分清启动链路与非关键任务。

一、冷启动链路

  • App 启动
  • 加载动态库
  • 执行 main
  • application(_:didFinishLaunchingWithOptions:)
  • 创建首屏

二、启动耗时统计

1. 使用时间戳

let launchStart = CFAbsoluteTimeGetCurrent()

func recordLaunchEnd() {
    let end = CFAbsoluteTimeGetCurrent()
    print("Launch time: \(end - launchStart)")
}

2. 使用 Signpost

import os.signpost

let log = OSLog(subsystem: "com.jj.app", category: .pointsOfInterest)
let signpostID = OSSignpostID(log: log)

func markLaunchBegin() {
    os_signpost(.begin, log: log, name: "Launch", signpostID: signpostID)
}

func markLaunchEnd() {
    os_signpost(.end, log: log, name: "Launch", signpostID: signpostID)
}

三、拆分启动任务

1. 必须任务

  • 基础配置
  • 崩溃上报初始化
  • 首屏数据准备

2. 可延迟任务

  • 日志/统计 SDK
  • 远程配置拉取
  • 大型缓存加载
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    setupEssential()

    DispatchQueue.global().async {
        setupAnalytics()
        preloadCache()
    }

    return true
}

四、减少主线程阻塞

  • 避免同步 IO
  • 不在启动阶段做大 JSON 解析
  • 图像解码异步处理
DispatchQueue.global().async {
    let data = try? Data(contentsOf: url)
    DispatchQueue.main.async {
        // 更新 UI
    }
}

五、减少动态库与加载成本

  • 能静态的尽量静态
  • 删除未使用的依赖
  • 合并小型库

六、首屏渲染策略

  • 先渲染骨架屏
  • 数据到达后刷新
  • 保证首屏快速可见
func showSkeleton() {
    // 先显示占位视图
}

func renderContent() {
    // 数据返回后更新
}

七、持续优化的方法

  • 记录每次版本的启动耗时
  • 对关键版本做对比分析
  • 明确启动指标目标(如 1.5s 以内)

启动优化是一条长期工程线,拆分与监控是关键。

JJ

作者简介

专注于内容创作、产品策略与设计实践。欢迎交流合作。

下一篇