
搞 Android 构建优化的谁没被 Gradle 折磨过我见过太多团队代码质量还不错结果每次构建都要等三到五分钟一天下来光等编译就浪费一两个小时。更别提 CI 上跑一次全量构建动不动就十几分钟那体验真是酸爽。其实 Gradle 构建慢这件事绝大多数情况下不是 Gradle 本身的问题而是我们对它不够了解配置不够合理甚至是在关键环节用错了方式。这次我梳理了一份从 Java 核心到底层 Android 物理性能压榨的完整指南核心思路很简单先搞清楚 Gradle 构建的完整链路再一层一层往下优化。本文会覆盖 JVM 层、Gradle 配置层、Android 工程层、再到机器硬件层的全链路优化方案包括我实际踩过的坑和验证过的手段希望能帮你把构建时间真正压下来。1. 内容整体设计与思路拆解1.1 构建链路全景先搞清楚时间都去哪了Gradle 的一次构建说白了就是一条流水线先启动 Gradle 守护进程Daemon然后解析 settings.gradle 和 build.gradle 脚本接着解析项目依赖编译 Java/Kotlin 源码处理资源打包 APK最后签名。这个链条上每一步都有优化的空间但前提是你得知道时间花在了哪里。我常用的一种手段是打开 Gradle 构建的 profiling 报告。执行构建时加上--profile参数构建完成后会在 build/reports/profile 目录下生成一份 HTML 报告里面按阶段列出了耗时分布。还有一个更直观的方式是在 Android Studio 的 Build 窗口里直接看各个 Task 的执行耗时或者在命令行里通过--info参数查看详细日志。按照我的经验耗时大户通常集中在几个地方全量编译、资源合并、Dex 打包、以及依赖下载。前三个跟工程规模直接相关依赖下载则跟网络和仓库配置强相关。只有先定位到具体环节后面的优化才有明确方向否则就是盲人摸象。1.2 方案选型背后的考量为什么先调 JVM 再调 Gradle很多人在优化构建时上来就改 Gradle 配置比如开并行、开缓存结果效果不明显。我个人的建议是按层级从底往上调JVM 层 → Gradle 守护进程 → 依赖解析 → 编译配置 → 资源与打包。原因很简单底层的东西没调好上层再折腾也是事倍功半。打个比方Gradle 本身运行在 JVM 上就像一辆车跑在赛道上。你光想着换更宽的轮胎改 Gradle 配置但发动机JVM 内存和垃圾回收不给力照样跑不快。我见过太多人把org.gradle.workers.max调到 8结果堆内存只有 512MB一跑就 OutOfMemoryError或者频繁 Full GC构建反而更慢。另外一个容易被忽略的点是 JDK 版本。Gradle 7 之后对 JDK 版本非常敏感不同的 JDK 版本在类编译、代码生成上的性能差异很大。我自己实测过同一台机器、同一个工程从 JDK 8 切到 JDK 11 再切到 JDK 17配置相同的增量构建耗时差距在 10% 到 20% 之间。所以说优化不能一概而论要找到瓶颈再对症下药。1.3 避免误区和反模式无效优化盘点在讲具体方案之前先盘点一下我在各处看到过的无效甚至有害的“优化姿势”。第一个就是把org.gradle.daemon设为 false这样每次构建都重新起一个 JVM前面的预热全部白费只在极少数特殊环境下才需要关。第二个是不做区分地把所有 Task 都并行Gradle 并行执行是有条件限制的如果 Task 之间没有做依赖声明并行反而可能引入安全性问题或重复劳动。第三个是盲目开org.gradle.caching却不配置缓存后端本地缓存能起到一定作用但在 CI 环境里没配置远程缓存就失去了最大的意义。这些误区我在带团队时反复强调一定不要为了优化而优化每一步都要有可量化的收益。否则看似在追求效率实际上是把系统弄得更脆弱。2. 核心细节解析与实操要点2.1 JVM 层内存、垃圾回收和并行 GC 调优Gradle 跑得稳不稳首先看 JVM 参数。默认情况下Gradle 守护进程的堆内存只有 1GB 左右这局对大多数 Android 工程来说是不够的。我通常在gradle.properties里设置org.gradle.jvmargs-Xmx4096m -XX:MaxMetaspaceSize1024m -XX:UseParallelGC-Xmx控制最大堆内存-XX:MaxMetaspaceSize控制元空间大小-XX:UseParallelGC使用并行垃圾回收器。为什么用 ParallelGC 而不是 G1我实测在 Gradle 这种以吞吐量为导向的场景下ParallelGC 的停顿更少整体吞吐量更高。不过如果你的机器内存很大比如 32GB并且工程超大可以试试 G1但一定要做对比测试不要人云亦云。还有一种常见的报错java: OutOfMemoryError: insufficient memory。这通常不是因为系统真实内存不够而是 JVM 堆内存设置得太小或者 Gradle 守护进程被系统限制住了。检查一下gradle.properties里的org.gradle.jvmargs以及系统环境变量里的GRADLE_OPTS把内存调到合理值基本就能解决。2.2 Gradle 守护进程与并行构建的正确姿势Gradle 守护进程说白了就是常驻内存的构建服务它的意义在于复用已经加载的类和 JIT 编译结果。很多新手不知道第一次构建会比较慢就是因为在做守护进程的预热。我在实践中会把org.gradle.daemontrue显式写进配置并且要求团队不要手动去 kill 守护进程除非出现内存泄漏或配置变更。并行构建也非常重要在gradle.properties里加上org.gradle.paralleltrue org.gradle.workers.max4org.gradle.parallel是让多个模块并行编译org.gradle.workers.max控制 worker 数量通常设置成 CPU 核心数减 1 比较稳妥。我之前在一台 8 核 16 线程的机器上把 workers.max 设为 16结果发现大量时间花在线程切换上编译效率不升反降。后来改成 7效果好了很多。所以这里建议如果你的工程是多模块的并行编译收益非常明显但 worker 数量一定要结合自己的机器配置来微调。2.3 依赖解析加速本地仓库、镜像和缓存策略依赖下载是构建时间的大头之一尤其是首次构建。我见过不少团队在build.gradle里直接写google()和mavenCentral()在国内网络环境下这些仓库的下载速度有时候会慢到让你怀疑人生。解决方案之一是配置国内镜像比如阿里云镜像或者腾讯云镜像。这里特别提醒使用镜像时要遵循相关服务和网络使用规范确保合规。另一个非常实用的手段是让 Gradle 优先使用本地 Maven 仓库。在settings.gradle里配置仓库时把mavenLocal()放在前面dependencyResolutionManagement { repositories { mavenLocal() maven { url https://maven.aliyun.com/repository/public } maven { url https://maven.aliyun.com/repository/google } maven { url https://maven.aliyun.com/repository/gradle-plugin } google() mavenCentral() } }这样做的逻辑很简单本地仓库的访问速度远高于网络仓库尤其是在多模块依赖同一份构件时能省下大量重复下载的时间。但是也要注意mavenLocal()放在前面可能会引入本地旧版本污染的问题需要团队约定好本地仓库的维护规范只放可控的构件。还有gradle 拉取本地 maven 仓库包这个需求其实你只要把依赖坐标写对然后在本地的~/.m2/repository下放好对应目录结构的 jar/aarGradle 就能通过mavenLocal()直接命中不需要去远程拉。2.4 编译加速增量编译、Kotlin 增量与应用缓存Java 和 Kotlin 的编译是整个构建链路里最耗时的一环。Gradle 从 4.10 左右开始默认启用增量编译也就是只编译修改过的类。但这里有一个前提增量编译的收益取决于模块的拆分是否合理。如果你的所有代码都堆在一个app模块里那增量编译的粒度依然会很粗随便改一行代码都可能触发大面积重编。在多模块工程里把业务代码拆分成独立的 library 模块能显著提升增量编译命中率。与此同时Kotlin 工程的kotlin.incrementaltrue也要保持一致并且 Kotlin 编译器 daemon 的内存和 JVM 参数要与 Gradle 守护进程协调好避免各自为政。另外一个容易忽略的点是 annotation processor。如果你用了 ButterKnife、ARouter 这类在编译期生成代码的库它们会拖慢编译速度。我后面会单开一节讲这块因为处理不当增量编译会被这些 processor 直接打断。3. 实操过程与核心环节实现3.1 环境准备JDK、Gradle 版本和 Android Studio 版本的正确匹配在动手优化前先把环境对齐。Gradle 版本和 AGP 版本之间有着严格的兼容关系不匹配的话轻则警告重则构建失败。比如网上常见的一个报错The projects Gradle version 6.7.1 is incompatible with the Gradle JVM version这种错误本质上是 Gradle 要求的 JVM 版本和当前环境的 JVM 版本不一致。一般遇到这种情况先确认三件事JDK 版本、Gradle 版本、AGP 版本。这里我给出一个自己常用的版本匹配表Gradle 版本最低 JDK 版本推荐 JDK 版本常见 AGP 版本6.7.1JDK 8JDK 113.1.0 ~ 4.2.07.0.2JDK 11JDK 117.0.07.4JDK 11JDK 177.2.0 ~ 7.4.08.0JDK 17JDK 178.0.09.1JDK 17JDK 218.5.0在 Android Studio 里还有一个常见问题Android Studio Hedgehog | 2023.1.1 Patch 2 支持 AGP 8 版本吗。答案是支持的但要注意 JDK 版本。Hedgehog 内置的 JBR 17 跑 AGP 8.0 没有问题但如果你在系统环境里单独配了 JDK 8AGP 8 构建肯定会挂。所以当你升级 AGP 到 8.x 时一定检查一下File - Project Structure - SDK Location - Gradle Settings里的 Gradle JVM 是否指向了 JDK 17。3.2 gradle.properties 的最优配置清单来一份我目前在生产环境验证过的gradle.properties配置直接复制后根据自己机器调整即可# JVM 调优 org.gradle.jvmargs-Xmx4096m -XX:MaxMetaspaceSize1024m -XX:UseParallelGC -XX:HeapDumpOnOutOfMemoryError # 构建行为 org.gradle.daemontrue org.gradle.paralleltrue org.gradle.workers.max4 org.gradle.cachingtrue # 配置缓存 org.gradle.configuration-cachetrue # 文件系统监听 org.gradle.vfs.watchtrue # Kotlin 编译 kotlin.incrementaltrue kotlin.compiler.execution.strategyin-process这里重点说说org.gradle.configuration-cachetrue。它是 Gradle 7.4 以后一直推进的特性配置缓存可以把配置阶段的执行结果缓存起来二次构建时跳过配置阶段直接进入 task 执行。我实测过一个两百多个模块的工程开启配置缓存后冷启动构建时间能减少 40% 左右。但是这个特性对工程里的一些“不走正道”的写法不太友好比如在配置阶段读取动态变量、自定义 Task 里引用外部进程等都可能触发不兼容警告。所以在正式开启前先在分支上验证一遍所有构建任务尤其是自定义的打包、签名任务。3.3 依赖与仓库优化实操从下载超时到缓存命中依赖下载超时是很多国内团队踩过的大坑。报错长这样Could not install Gradle distribution from https://services.gradle.org/distributions/...原因多半是网络连接不稳定。这里有两个解决思路第一个思路是手动下载 Gradle Distribution。不要用 Gradle Wrapper 去在线下载而是直接到 Gradle 官网手动下载对应版本的 bin 包解压到本地目录然后在 Android Studio 里设置Gradle user home或直接指定 distributionUrl 为本地文件路径。比如distributionUrlfile\:/D:/soft/gradle-8.10.2-bin.zip这样能完全绕开网络限制构建时不再有下载环节。第二个思路是配置网络超时时间。在gradle.properties里加上systemProp.org.gradle.internal.http.connectionTimeout120000 systemProp.org.gradle.internal.http.socketTimeout120000这样可以避免因为短暂网络波动导致的构建失败。但要注意这只能解决超时的问题如果仓库本身不通设置再长也没用。所以更根本的办法是确保仓库地址可访问、稳定优先使用本地或内网镜像。还有一个经常被忽略的小技巧依赖锁定和版本固定。很多团队用动态版本号比如或者latest.releaseGradle 每次构建都要远程检查这些版本是否存在严重拖慢依赖解析速度还能引发构建不一致。建议把所有依赖版本固定使用 Gradle 的 dependency locking 功能。开启方式是在 settings.gradle 里dependencyLocking { lockAllConfigurations() }首次运行会生成gradle.lockfile之后构建直接读锁文件不再去远程探测版本解析速度会快不少。3.4 Android 构建链路资源合并、Dex 与打包的底层压榨当 Gradle 配置和依赖解析都优化完接下来就是 Android 构建链路本身的优化了。这条链路包含资源合并、AAPT2 编译资源、Java/Kotlin 编译、Dex 打包、APK 打包和签名每一步都可能成为瓶颈。先说资源合并。如果你的工程启用了大量resValues或者多语言资源合并阶段会比较吃 CPU。Android Studio 3.6 之后引入了资源优化工具可以把未使用的资源移除。开启方式是在build.gradle里设置android { buildTypes { release { shrinkResources true minifyEnabled true } } }需要注意的是shrinkResources和minifyEnabled必须同时开启才会生效且开启后要仔细检查哪些资源被错误地移除了。我建议在开启之后用手工过一遍主要界面和图片资源特别是动态引用的资源。再来说 Dex。AGP 8 之后D8 和 R8 已经成为默认的 dex 编译器和混淆器。D8 的增量构建能力不错但当你修改了某个类D8 可能还是要重新处理所有类。这时候合理拆分 multidex 配置是有帮助的。比如把multidexEnabled true打开并使用androidx.multidex:multidex库。多 dex 的构建并行度更高尤其是在低版本 Android 设备上加载速度也快一些。不过 Android 5.0 及以上原生支持 multidex所以如果 minSdkVersion 大于等于 21其实不需要额外引入 multidex 库。最后说打包。如果你有签名任务签名其实也可以并行。在build.gradle里给签名任务配置maxParallelForks是不行的签名任务的耗时一般不大真正耗时的是资源压缩和 zipalign。想要快一点可以尝试把android.enableAppCompileTimeRClasstrue打开这个配置可以让 R 类直接使用常量值而不是字段引用减少 R 类相关的编译时间。3.5 火焰图与性能分析Android Studio 里怎么定位构建瓶颈Android Studio 里有一个很实用的功能叫火焰图。不过很多人知道它用于运行时性能分析却不知道它也可以用在构建性能剖析上。实际上Gradle 自身的 profiling 报告就是一张变相的火焰图。操作路径在命令行跑构建时加--profile然后打开生成的 HTML 报告。你会看到每个 Task 的耗时柱状图还可以展开看每个 Task 内部的细分阶段。这是整个构建优化里最重要的一步我一直强调没有数据支撑的优化都是耍流氓。我还习惯配合 Android Studio 的Build Analyzer功能。它可以直接在 IDE 里展示构建中的瓶颈点并给出优化建议。AGP 8 内置了这个功能你只需要在 Build 窗口点击Build Analyzer标签即可。它能把重复执行的 Task、未命中的缓存项标出来非常直观。4. 常见问题与排查技巧实录4.1 版本兼容性报错处理速查构建优化过程中版本兼容性报错是我遇到最多的一类问题。整理一份速查表报错信息根因解决方案The projects Gradle version 6.7.1 is incompatible with the Gradle JVM versionGradle 与 JDK 版本不匹配统一 JDK 版本升级 Gradle 或降级 JDKYou arent using a compiler supported by Lombok, so Lombok will not workLombok 版本与 JDK 编译器不兼容升级 Lombok 版本或更换 JDK 版本Could not install Gradle distribution from https://...网络无法下载 Gradle 发行包手动下载并指定本地 distributionUrljava: OutOfMemoryError: insufficient memoryJVM 堆内存不足增大 org.gradle.jvmargs 的 -XmxApplying Flutters main Gradle plugin imperatively with the apply method导入 Flutter 插件方式过时按新方式使用 plugins DSL这里重点说下 Lombok 那个报错。它出现的原因是老版本 Lombok 不认识新版本的 JDK 编译器。解决办法是升级到 1.18.20 以上然后用-Djps.track.ap.dependenciesfalse或类似的参数关掉一些增强编译的特性。如果你只做 Android 开发其实不太推荐用 Lombok因为 Android 生态里更常用的是自己的注解处理器。4.2 依赖下载超时与仓库配置实战依赖超时的处理我在前面依赖优化一节已经写了不少这里再补充一个场景gradle 下载太慢 android studio。如果你是新创建的工程第一次 Sync 时Gradle Wrapper 要下载 Gradle 发行包Gradle 又要下载所有依赖这个流程在网络环境不好的时候会非常痛苦。我建议分两步走第一步单独去下载 Gradle 发行包。如果你用的是 8.10.2就去官网下载gradle-8.10.2-bin.zip然后按照刚才的方法改 distributionUrl。关键是 gradle-wrapper.properties 里的distributionUrl指向本地路径后每次构建都不再网络下载。第二步依赖仓库统一走镜像。在根目录的settings.gradle里把pluginManagement和dependencyResolutionManagement里的仓库地址统一配置成可稳定访问的镜像源。另外如果你用的是 IntelliJ IDEA 来开发 Java 项目想在 IDEA 里配置 Gradle路径是File - Settings - Build, Execution, Deployment - Build Tools - Gradle在这里指定 Gradle user home 和 Gradle JVM。IDEA 的 Gradle 配置和 Android Studio 类似但注意不要和 Android Studio 共用一个 gradle user home否则缓存文件互相冲突会产生一些奇怪的问题。4.3 排除缓存陷阱为什么有时配置缓存看似没用配置缓存Configuration Cache虽然强大但很多人反馈开启后好像没什么变化甚至反而变慢了。我排查过不少这种情况给你分享两个最可能的原因。第一个原因是缓存命中率低。配置缓存是跨进程的缓存但只缓存配置阶段的结果。如果你的构建脚本里存在大量在配置阶段动态生成的 Task而这些 Task 的输入参数每次都不相同那缓存基本无法命中。检查方法很简单看构建日志里有没有Configuration cache entry reused字样如果没有就说明没有命中。第二个原因是缓存序列化开销过大。配置缓存会把构建脚本的执行结果序列化到磁盘如果工程里有很多自定义 Task、很多插件序列化和反序列化本身也要花时间。遇到这种情况我建议先把org.gradle.configuration-cachetrue注释掉回归常规模式优先保证构建的稳定性不要为了技术指标牺牲交付效率。还有一点配置缓存和不少老版本插件不兼容。我遇到过自定义插件在配置缓存模式下执行时报错排查了很久才发现是插件内部通过反射访问了 Gradle 内部对象在缓存还原时这些对象已经不存在了。如果遇到类似问题升级插件版本或者修改插件实现绝对不要硬开配置缓存。4.4 八股文式的“灵魂拷问”Gradle 构建性能到底考什么最后聊点面试相关的话题。这些热词里出现了大量的java面试题、java八股文、java基础面试题确实Gradle 构建优化的知识点也经常出现在面试中比如“如何优化 Gradle 构建速度”“Gradle 的构建流程是什么”等。本质上面试官想考察的不只是你会不会背参数而是你有没有真正理解构建的底层逻辑。我把这一节当作一个自测清单Gradle 的构建生命周期分哪几个阶段初始化、配置、执行。配置阶段与执行阶段的区别是什么配置阶段生成 Task 图执行阶段按依赖关系执行 Task。增量构建的原理是什么Gradle 通过 Task 的输入输出快照判断是否需要重新执行。守护进程的作用是什么复用 JVM、缓存编译结果、避免重复初始化。配置缓存与构建缓存的区别一个缓存配置阶段一个缓存 Task 执行结果。真正把这些问题想明白了再回来看前面的优化手段你会发现其实都是围绕着“减少重复计算、增加并行、缓存结果”这三件事在展开。这也是我写这篇文章时贯穿始终的底层逻辑。5. 实测效果与工具链总结5.1 我的实测数据一台 16GB 内存 MacBook Pro 上的表现我不喜欢只讲理论晒一组我最近优化一个中型项目的实测数据。工程规模大约 38 个模块、依赖数量在 120 个左右机器是 2021 款 MacBook Pro 16GB 内存。优化前冷启动清空 build 目录构建约 6 分 20 秒增量构建改一行 Java 代码约 45 秒配置阶段耗时约 18 秒优化后开启配置缓存、并行构建、调整 JVM 参数、仓库走镜像冷启动构建约 3 分 10 秒增量构建约 12 秒配置阶段耗时约 3 秒数据说明最大的收益来自配置缓存和并行构建的组合冷启动时间降了一半增量构建降了 70% 以上。当然冷启动构建的一半时间仍然花在依赖编译和资源处理上这部分如果没有远程构建缓存靠单机始终是有限度的。如果你在 CI 上配置了 Gradle Remote Cache冷启动的时间还能进一步下降。5.2 工具选型解析Gradle、AGP、JDK 的协同配置综合来看构建优化的工具链是 Gradle AGP JDK 三位一体。单独调任何一环效果都有限。我的建议是Gradle 版本不要盲目追新但也不要停在太老的版本。Gradle 8.x 的配置缓存和并行执行已经非常成熟建议优先考虑。如果看到gradle 9.1这类新版本先在非核心工程试用确认所有插件兼容后再升级。AGP 版本和 Gradle 版本严格匹配。每次升级 AGP 都要检查 Gradle 版本和 JDK 版本AGP 8.x 通常搭配 Gradle 8.x、JDK 17。JDK 版本JDK 17 是目前 Android 开发的主流选择兼顾性能和兼容性。如果你的工程是纯 Java 的JDK 21 在部分场景下更快但要注意第三方插件是否支持。我见过太多团队在这个问题上翻车升级了 Gradle 但忘记升级 AGP结果爆出各种莫名其妙的问题或者看到新版 JDK 就想上结果 Gradle 版本太旧不兼容。所以版本协同这件事一定要当作工程规范来管理。5.3 一些值得留意的边界场景构建优化并不是万能的有几个边界场景要提醒你注意。第一如果你的工程就是单模块的 App没有多模块拆分那并行编译和配置缓存的收益会大打折扣。这种情况下更值得做的是把代码按业务模块拆出来或者至少保证依赖干净、不冗余。第二如果你的机上跑了很多大型软件内存已经捉襟见肘那么盲目调大 Gradle 堆内存反而会让整机变慢。我建议 Gradle 守护进程的-Xmx不要超过物理内存的 1/4否则会跟 Android Studio、模拟器抢内存。模拟器本身是内存大户如果同时开模拟器和构建很容易出现系统级的 swap。第三文件系统监听VFS watch在 Windows 上可能不如 macOS 和 Linux 稳定。我在 Windows 上遇到过开启org.gradle.vfs.watchtrue后文件系统事件监听异常导致构建缓存失效的问题。如果遇到类似情况关闭这个特性再对比一下耗时。6. 最后一公里底层物理性能压榨的几个野路子前面讲的都是常规手段下面这部分是我自己摸索出来的“野路子”不一定适合所有团队但在特定场景下真实有效。第一个是关掉不必要的安全扫描。有些团队在 Windows 机器上装了杀毒软件实时监控 Gradle 缓存目录和 build 目录的每一个文件变化。这会让构建的 I/O 开销成倍增加。技术上合理的做法是把 Gradle user home 和项目 build 目录加入白名单或者过滤掉这些目录的实时扫描这能在不改变构建逻辑的前提下显著提升磁盘 I/O 速度。第二个是手动管理 Gradle 守护进程。如果你经常改gradle.properties或者 JVM 参数Gradle 会认为守护进程的配置已过期自动停掉旧进程并启动新进程。这时候就不要再开一堆 Android Studio 窗口共用一个守护进程了否则频繁的配置变更会导致守护进程反复重启构建体验极差。我的习惯是改完配置后执行一次./gradlew --stop把所有守护进程停掉再重新构建保证接下来用到的守护进程是基于最新配置的。第三个是绑定 CPU 核心。在 Linux 环境下你可以用taskset命令把 Gradle 构建进程绑定到特定的高性能核心上。比如一台大小核架构的机器你可以把构建进程绑定到性能核上避免它被调度到能效核上执行。这个操作在 Android 构建上并不常见但如果你用的是服务器级别的机器或者构建机有明确的 CPU 隔离策略会很有效。第四个是使用 tmpfs 或 ramdisk 来存放临时文件。如果你的构建机器内存多到用不完可以把build/tmp、build/intermediates等目录挂载到内存文件系统上从而大幅减少磁盘写入带来的延迟。不过这个操作很激进一旦断电或重启这些目录就没了只适合在 CI 上配合构建缓存使用。这些野路子虽然不如常规配置那么通用但我觉得把它们写出来是有价值的。毕竟“底层物理性能压榨”除了常规的思路就是要在别人不去看的角落里扣时间。在我个人实战中最有成就感的不是那些高大上的配置而是花了一个下午通过关掉一个测试模块的冗余依赖把全量构建时间从 5 分钟降到 3 分半。构建优化更像是一种细水长流的工作它不靠一次性的革命性改动而是靠不断做减法、做缓存、做并行把每一次等待都压到最低。