建筑师之家IOS / NOTES

IOS PERFORMANCE / ARCHITECTURE

建筑师之家

我是做 iOS 开发的,网上的名字是建筑师。这个站用来记性能和架构,只写具体做法:时间怎么量、边界怎么划、代码放在哪一层。

PERFORMANCE / 15

01

启动时间要拆开看

pre-main、main 到首帧、首帧之后,这三段不是同一个问题,优化手段也完全不同。

性能
02

主线程只负责提交这一帧

卡顿先分清是单帧超时还是主线程被占住几秒。两种问题用的工具不一样。

性能
03

图片的内存按像素算

文件只有几百 KB,解码后仍可能是几十 MB。要降的是解码尺寸,不是再压一遍 JPEG。

性能
04

列表卡,多半不是 cell 复用没写

复用标识稳定之后,时间通常花在高度、富文本和没有取消的图片任务上。

性能
05

包体积要看链接进去的东西

业务代码往往不是大头。镜像、资源、被整包拉进来的依赖才是。

性能
06

性能问题按这个顺序查

先复现并量化,再改一处。Debug 下的好转,多数不能当结论。

性能
07

掉帧先看图层,不要先怪业务

圆角、阴影、遮罩和光栅化都会把工作丢给 GPU。主线程空着,滚动一样会卡。

性能
08

首屏慢,先画请求瀑布

一个页面串行打四五个接口,用户等到的是最后一条的尾巴,不是你本地解析有多快。

性能
09

泄漏先查谁把谁留住了

闭包、定时器、委托默认是强引用。退了页面内存不掉,就从引用关系往回看。

性能
10

耗电是后台还在干活

定位、轮询、动画和常亮屏幕,比一次重的启动更容易把电吃掉。

性能
11

MainActor 不是把所有东西都标上

界面类型隔离到主线程。解码、解析、入库放在外面,再把结果送回来。

性能
12

启动缺页多,就做二进制重排

启动链路的函数如果散在很多内存页上,每次缺页都要读盘和解密。把它们排到连续页上,能少做这些事。

性能
13

启动项按四步砍

能删就删,不能删就延后,不能延后再并发,最后才是把剩下的代码写快。

性能
14

首刷请求不要跟别人排队

启动后用户等的是第一屏内容。别的请求、别的列表,都该让开这条关键路径。

性能
15

线上卡顿看主线程 RunLoop

实验室用 Instruments。线上要知道主线程是不是长时间没有往下走,并把当时的栈留下。

性能

ARCHITECTURE / 09

01

先划边界,再选 MVVM

MVC 或 MVVM 只是界面那一层怎么分工。工程变乱,通常是界面、状态、副作用缠在一起。

架构
02

一份状态,别存两遍

加载中、失败、列表内容应该在同一个类型里。派生值不要再写进第二份存储。

架构
03

功能模块不要互相引用

App 目标是组装的地方。功能之间只通过协议和路由模型说话。

架构
04

导航是一条独立的流程

页面不要自己 new 下一个业务页面。路由集中之后,深链和按钮走同一条路。

架构
05

单例留在组合根里

全局入口可以有,但只在 App 启动时创建一次。功能代码不要自己去拿 .shared。

架构
06

错误往上交,不要就地弹窗

网络层返回错误值。要不要提示、提示成什么样,由当前界面决定。

架构
07

接口模型不要直接拿去画界面

解码用的结构和 cell 用的结构分开。接口一改,不会把整个界面一起改掉。

架构
08

模块之间怎么说话

URL、Target-Action、协议匹配,都能解开直接 import。差别在编译检查和你要不要动态跳转。

架构
09

站内跳转不必先绕一层 URL

URL 是给外部和动态开关用的。App 里面的调用,用带类型的方法更清楚。

架构