包瘦身-资源优化

资源文件通常占iOS应用包体积的40-60%,是优化的重要方向。本文介绍各种资源优化手段及其原理。 图片优化 Asset Catalog原理 Asset Catalog(.xcassets)编译后生成Assets.car文件,这是一个优化过的资源容器: 编译前: Images.xcassets/ ├── AppIcon.appiconset/ │ ├── icon-60@2x.png │ └── icon-60@3x.png ├── Logo.imageset/ │ ├── logo@2x.png │ └── logo@3x.png └── Contents.json 编译后: Assets.car ← 单一文件,包含所有资源 Assets.car的优化: 图片被重新编码,使用更高效的压缩 支持App Thinning,按设备分发 运行时高效加载(内存映射) 可以使用assetutil查看Assets.car内容: assetutil --info Assets.car 图片压缩原理 PNG压缩原理: PNG使用DEFLATE无损压缩,但可以通过以下方式减小体积: 原始PNG结构: ┌────────────────┐ │ PNG Header │ ├────────────────┤ │ IHDR (图像信息) │ ├────────────────┤ │ IDAT (图像数据) │ ← 压缩的像素数据 ├────────────────┤ │ 辅助chunks │ ← 可以移除 └────────────────┘ 优化方向: 1. 移除不必要的chunks(如tEXt、iTXt) 2. 优化DEFLATE压缩参数 3. 减少颜色数量(有损) 4. 使用更高效的滤波器 有损压缩原理(pngquant): ...

May 2, 2026

包瘦身

包体积(IPA大小)是iOS应用的重要质量指标。App Store对蜂窝网络下载有200MB的提示阈值,超过这个大小会弹窗询问用户是否使用流量下载(iOS 13之前是强制要求Wi-Fi)。这个弹窗会增加用户的决策成本,影响下载转化率。因此,包体积优化对于用户获取和留存都有重要影响。 包格式介绍 iOS开发中常见的包格式有三种: 格式 扩展名 说明 .app 目录 应用程序包,是一个包含可执行文件和资源的目录结构 .xcarchive 目录 Xcode归档包,包含.app、dSYM符号文件、构建信息等 .ipa 文件 安装包,本质是ZIP压缩的.app,用于分发和安装 日常使用场景: 开发调试:Xcode直接将.app安装到模拟器或真机 测试分发:使用.ipa通过TestFlight、蒲公英、fir.im等平台分发给测试人员 App Store上架:通过Xcode或Transporter将.xcarchive导出并上传到App Store Connect(实际上传的是从xcarchive导出的IPA或直接上传xcarchive中的内容) .app(Application Bundle) .app是macOS/iOS应用的标准格式,实际上是一个目录(Finder中显示为单个文件)。包含: 可执行文件(Mach-O格式) Info.plist配置文件 资源文件(图片、音频、本地化文件等) Frameworks目录(动态库) PlugIns目录(App Extension) .xcarchive(Xcode Archive) .xcarchive是Xcode的归档格式,用于保存完整的构建产物。目录结构: YourApp.xcarchive/ ├── Products/ │ └── Applications/ │ └── YourApp.app # 应用程序包 ├── dSYMs/ │ └── YourApp.app.dSYM # 符号文件(用于崩溃解析) ├── Info.plist └── SCMBlueprint/ # 源码管理信息 主要用途: 保存dSYM符号文件,用于线上崩溃日志符号化 导出不同分发渠道的IPA(App Store、Ad Hoc、Enterprise) 上传到App Store Connect .ipa(iOS App Store Package) .ipa是iOS应用的安装包格式,本质是一个ZIP压缩文件。结构: ...

May 2, 2026

性能优化 面试题

共 52 道 性能优化 面试题。答案默认折叠,便于先自行作答。 1. 响应式开发中,如何避免窗口大小监听导致的重排抖动? 难度:2 · 类型:QA 题目要点 响应式开发中 resize 导致抖动的本质原因是窗口变化会高频触发事件,从而反复触发布局计算。常见优化方式包括对 resize 事件进行节流或防抖以降低执行频率,避免在回调中混合 DOM 读写以减少强制同步布局,利用 requestAnimationFrame 控制更新时机,以及使用 ResizeObserver、媒体查询或容器查询等浏览器能力,让布局响应更多地交给浏览器完成,从而降低重排和重绘的成本。 参考答案 在响应式开发中,如果直接监听 resize 事件并在回调中执行布局计算或 DOM 操作,很容易引发频繁的 重排(reflow)和重绘(repaint)。原因在于浏览器在拖动窗口尺寸时会持续触发 resize 事件,如果每次触发都进行样式读取和 DOM 更新,就会造成布局计算不断被打断,从而出现明显的抖动或性能下降。 实际工程中通常会从 事件触发频率控制、布局计算方式优化、浏览器能力利用 三个层面进行处理。 首先是对 resize 事件进行频率控制。浏览器在拖拽窗口时可能每秒触发几十到上百次 resize,如果每次都重新计算布局,主线程压力会非常大。常见做法是通过 节流(throttle)或防抖(debounce) 将计算频率降低。例如在节流策略下,每隔一段时间才执行一次布局更新,从而避免在连续拖动过程中频繁触发布局计算。对于布局实时性要求较低的场景,防抖也比较适合,即在窗口停止变化后再执行计算。 其次是避免在 resize 回调中混合 DOM 读写操作。浏览器在读取布局信息(例如 offsetWidth、getBoundingClientRect)时,如果之前存在未提交的样式修改,会强制触发布局计算,这被称为 强制同步布局(Forced Reflow)。因此更好的方式是将读取和写入操作进行分离,例如先批量读取尺寸,再统一修改样式,或者借助 requestAnimationFrame 将 DOM 更新安排到浏览器下一帧执行,避免频繁打断渲染流程。 另外一个更现代的方案是尽量减少对 window.resize 的依赖,而是使用 元素级尺寸监听机制。浏览器已经提供了 ResizeObserver API,可以直接监听某个容器尺寸变化。当布局响应依赖的是容器宽度而不是窗口宽度时,这种方式更加精确,同时也减少无关 resize 触发带来的性能损耗。 在 CSS 层面也可以减少 JavaScript 的参与。例如使用 媒体查询(media query) 或 容器查询(container query) 来处理布局变化,让浏览器在样式计算阶段直接完成响应式适配。CSS 驱动的响应式布局通常比 JavaScript 监听 resize 更高效,因为浏览器可以对样式计算进行统一调度。 ...