【翻译】React Native Android 构建优化完全指南

4 阅读5分钟

React Native Android 构建优化完全指南


LinuxmacOS 上做 React Native 时,你可能已经发现:Android 的 release 构建耗时长得不合理。构建时打开系统监视器,往往会看到同一个问题:大量构建工具只用得到一颗 CPU 核心,其余算力基本闲置。

本文按步骤讲解每项优化、为何有效,以及如何验证收益。

说明:文中的优化在 MacBook Air M1、8GB 内存 上测试过;实际效果会因机器配置而异

为什么构建这么慢?

React Native 的构建栈包含几块:

  • Gradle:构建 Android 原生代码
  • Metro:打包 JavaScript
  • C++ 编译器:处理 TurboModules 与 Fabric(新架构)

默认情况下,三者都偏保守:Gradle 顺序跑任务、Metro 只用很少的 worker、C++ 每次构建都整份重编——哪怕什么都没改。好消息是:这些都有简单的改法。

未做任何优化时的初始耗时

BUILD SUCCESSFUL in 21m 14s
730 actionable tasks: 554 executed, 166 from cache, 10 up-to-date
Configuration cache entry stored.

See the profiling report at: file:///.../android/build/reports/profile/profile-2026-03-13-07-45-14.html
A fine-grained performance profile is available: use the --scan option.

===========================================
                RESULTS
===========================================
⏱️  Total Benchmarking Time: 22m 2s
📊 A detailed Gradle profiling report is available at:
   android/build/reports/profile/
   (Open the latest .html file in a browser to see where the time was spent)
===========================================

1. 让 Gradle 并行执行

Gradle 是 Android 的构建系统。开箱即用时会一个接一个跑任务,并限制内存以免拖垮系统;在多核机器上,这非常浪费。

做法

optimize-gradle.sh:脚本会根据本机规格自动改写 gradle.properties

#!/bin/bash

# Path to the gradle.properties file
GRADLE_PROPERTIES="android/gradle.properties"

if [ ! -f "$GRADLE_PROPERTIES" ]; then
    echo "Error: gradle.properties not found at $GRADLE_PROPERTIES"
    exit 1
fi

# Get system specifications
TOTAL_MEM_BYTES=$(sysctl -n hw.memsize)
HALF_MEM_MB=$(( TOTAL_MEM_BYTES / 2 / 1024 / 1024 ))
EIGHTH_MEM_MB=$(( TOTAL_MEM_BYTES / 8 / 1024 / 1024 ))
CPU_CORES=$(sysctl -n hw.ncpu)
WORKERS_MAX=$(( CPU_CORES * 3 / 4 ))
if [ $WORKERS_MAX -lt 1 ]; then WORKERS_MAX=1; fi

# Desired property values
JVM_ARGS="-Xmx${HALF_MEM_MB}m -XX:MaxMetaspaceSize=${EIGHTH_MEM_MB}m"
PARALLEL="true"

echo "Optimizing Android Gradle Properties for faster builds..."
echo " - CPU Cores count: $CPU_CORES (Using $WORKERS_MAX for 75%)"
echo " - Memory (Half RAM): ${HALF_MEM_MB}MB"
echo " - Metaspace (1/8 RAM): ${EIGHTH_MEM_MB}MB"

# Remove existing properties so we don't have duplicates
sed -i '' '/^org.gradle.jvmargs/d' "$GRADLE_PROPERTIES"
sed -i '' '/^org.gradle.parallel/d' "$GRADLE_PROPERTIES"
sed -i '' '/^org.gradle.workers.max/d' "$GRADLE_PROPERTIES"

# Append optimized properties at the end of the file
echo "org.gradle.jvmargs=$JVM_ARGS" >> "$GRADLE_PROPERTIES"
echo "org.gradle.parallel=$PARALLEL" >> "$GRADLE_PROPERTIES"
echo "org.gradle.workers.max=$WORKERS_MAX" >> "$GRADLE_PROPERTIES"

echo "Success: gradle.properties optimized!"

使用方式:

chmod +x scripts/optimize-gradle.sh
./scripts/optimize-gradle.sh

也可手动把下列配置写入 android/gradle.properties

# Enable parallel task execution
org.gradle.parallel=true

# Use 75% of your CPU cores
org.gradle.workers.max=6

# Allocate more memory: 4GB heap + 1GB metaspace
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m
配置项作用
org.gradle.parallel=true让彼此独立的构建任务并行执行
org.gradle.workers.maxGradle 可用的最大并行线程数
org.gradle.jvmargsJVM 堆与 Metaspace 分配

优化 Gradle 后的收益

BUILD SUCCESSFUL in 10m 54s
730 actionable tasks: 452 executed, 268 from cache, 10 up-to-date
Configuration cache entry stored.

See the profiling report at: file:///.../android/build/reports/profile/profile-2026-03-13-08-15-54.html
A fine-grained performance profile is available: use the --scan option.

===========================================
                RESULTS
===========================================
⏱️  Total Benchmarking Time: 11m 24s
📊 A detailed Gradle profiling report is available at:
   android/build/reports/profile/
   (Open the latest .html file in a browser to see where the time was spent)
===========================================

22 分钟 → 约 11 分钟(接近快一倍)

为何有效: Gradle 可以同时推进多个阶段(编译、打包、lint 等),而不必等上一段完全结束再开始下一段。

译者注:脚本中的 sed -i ''BSD/macOS 写法。在 GNU/Linux 上请改为 sed -i(无空字符串参数),或改用 sed -i.bak 等 GNU sed 支持的形式,否则需安装兼容层或手工编辑 gradle.properties


2. 加速 Metro Bundler

Metro 在 release 构建里会把 JavaScript 打成 bundle。默认往往只用 1 个 worker,与 CPU 核心数无关。

做法

metro.config.js 里为 worker 数量做动态配置:

const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
const os = require("os");

const config = {
  // Use 50% of available CPU cores dynamically
  maxWorkers: Math.max(1, Math.floor(os.cpus().length * 0.5)),
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

优化 Metro 后的收益

BUILD SUCCESSFUL in 5m 31s
730 actionable tasks: 452 executed, 268 from cache, 10 up-to-date
Configuration cache entry stored.

See the profiling report at: file:///.../android/build/reports/profile/profile-2026-03-13-09-50-26.html
A fine-grained performance profile is available: use the --scan option.

===========================================
                RESULTS
===========================================
⏱️  Total Benchmarking Time: 5m 49s
📊 A detailed Gradle profiling report is available at:
   android/build/reports/profile/
   (Open the latest .html file in a browser to see where the time was spent)
===========================================

11 分钟 → 约 5 分钟(接近快四倍)

为何有效: 不再写死 worker 数,而是随机器扩展。例如在 8 核 上 Metro 可用 4 个 worker 而非 1 个,JS 打包理论上可接近 4 倍加速。


3. 用 ccache 缓存 C++ 编译

新架构大量依赖 C++ (TurboModules、Fabric)。这些文件编译成本高,默认却每次全量重编,哪怕你只改了一行 JavaScript。

做法

安装并配置 ccache

brew install ccache
ccache --set-config=max_size=20G

setup-ccache.sh:检查是否已安装 ccache、必要时用 Homebrew 安装,并为本机构建做好配置:

#!/bin/bash

echo "==========================================="
echo "  Checking ccache (Compiler Cache) Status  "
echo "==========================================="

if command -v ccache &> /dev/null; then
    echo "✅ ccache is already installed."
else
    echo "⚠️ ccache is not installed. Installing via Homebrew..."
    if command -v brew &> /dev/null; then
        brew install ccache
        if [ $? -eq 0 ]; then
            echo "✅ ccache successfully installed."
        else
            echo "❌ Failed to install ccache. Please install it manually: brew install ccache"
            exit 1
        fi
    else
        echo "❌ Homebrew is not installed. Cannot automatically install ccache."
        echo "Please install Homebrew (https://brew.sh) or install ccache manually."
        exit 1
    fi
fi

# Configure ccache for React Native Android builds
ccache --set-config=max_size=20G
echo "✅ ccache max size configured to 20G."

# Show current stats
echo ""
echo "Current ccache stats:"
ccache -s

echo "==========================================="
echo "  ccache is ready for React Native Builds  "
echo "==========================================="

原理简述: ccache 插在编译器与构建系统之间,按源文件与编译选项的哈希缓存产物;后续构建中相同输入可直接命中缓存,而无需重新编译。

验证缓存是否生效

构建后查看命中率:

ccache -s

关注 cache hit rate。热缓存下,首次完整构建之后常见 70%–90% 命中率,表示对应比例的 C++ 编译被跳过。

> bash scripts/setup-ccache.sh

===========================================
  Checking ccache (Compiler Cache) Status
===========================================
✅ ccache is already installed.
✅ ccache max size configured to 20G.

Current ccache stats:
Cacheable calls:   394 /  422 (93.36%)
  Hits:            178 /  394 (45.18%)
    Direct:        178 /  178 (100.0%)
    Preprocessed:    0 /  178 ( 0.00%)
  Misses:          216 /  394 (54.82%)
Uncacheable calls:  28 /  422 ( 6.64%)
Local storage:
  Cache size (GB): 0.0 / 20.0 ( 0.22%)
  Hits:            178 /  394 (45.18%)
  Misses:          216 /  394 (54.82%)
===========================================
  ccache is ready for React Native Builds
===========================================

> bash scripts/optimize-gradle.sh

Optimizing Android Gradle Properties for faster builds...
 - CPU Cores count: 8 (Using 6 for 75%)
 - Memory (Half RAM): 4096MB
 - Metaspace (1/8 RAM): 1024MB
Success: gradle.properties optimized!

BUILD SUCCESSFUL in 40s
730 actionable tasks: 32 executed, 698 up-to-date
Configuration cache entry stored.

此时整次构建可降到秒级

5 分钟不足 1 分钟

为何有效: 第二次及之后的构建只重编真正变更的文件,其余从缓存加载;在不少场景下可再省 50% 以上时间。

译者注:Linux 上请用发行版包管理器安装 ccache(如 apt install ccache),脚本中的 Homebrew 路径可按需改写。


4. 只构建当前活跃架构

默认会为多种 Android CPU 架构出包,例如 x86arm64armeabi 等,工作量成倍增加。日常开发时,通常只需要与真机或模拟器一致的那一种架构。

做法

package.json 里为开发脚本加上 --active-arch-only

"scripts": {
  "dev": "react-native run-android --mode debug --active-arch-only"
}

为何有效: React Native 会通过 ADB 检测已连接设备的架构,只编译该目标;debug 构建常可再快 2–3 倍

也可用自动化脚本 benchmark-build.sh 做耗时对比:

#!/bin/bash

# Configuration
BUILD_TYPE=${1:-"release"} # Default to release if no argument is provided
START_TIME=$(date +%s)

echo "==========================================="
echo "  React Native Android Build Benchmarking  "
echo "==========================================="
echo "Build Type: assemble$BUILD_TYPE"
echo ""

# Step 1: Clean Metro Bundler Cache
echo "🧹 [1/5] Clearing Metro Bundler Cache..."
rm -rf $TMPDIR/metro-*
rm -rf $TMPDIR/haste-map-*
echo " -> Metro cache cleared."

# Step 2: Clean Gradle Cache
echo "🧹 [2/5] Clearing Gradle Daemon & Cache..."
cd android || exit
./gradlew --stop > /dev/null 2>&1
rm -rf .gradle
rm -rf app/build
./gradlew clean > /dev/null 2>&1
cd ..
echo " -> Gradle cache cleared."

# Step 3: Clean Watchman Cache (if installed)
if command -v watchman &> /dev/null; then
    echo "🧹 [3/5] Watchman found. Clearing Watchman cache..."
    watchman watch-del-all > /dev/null 2>&1
    echo " -> Watchman cache cleared."
else
    echo "⏩ [3/5] Watchman not installed. Skipping..."
fi

echo ""
echo "🚀 [4/5] Proceeding with Build..."
echo "Starting Gradle Build with --profile..."

# Step 5: Execute build with profiling enabled
cd android || exit
# Using --profile to generate an HTML report of the build process
./gradlew assemble$BUILD_TYPE --profile

# Calculate total time
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
MINUTES=$((DURATION / 60))
SECONDS=$((DURATION % 60))

echo ""
echo "==========================================="
echo "                RESULTS                    "
echo "==========================================="
echo "⏱️  Total Benchmarking Time: ${MINUTES}m ${SECONDS}s"
echo "📊 A detailed Gradle profiling report is available at:"
echo "   android/build/reports/profile/"
echo "   (Open the latest .html file in a browser to see where the time was spent)"
echo "==========================================="
cd ..

使用方式:

chmod +x scripts/benchmark-build.sh
./scripts/benchmark-build.sh        # 默认 release
./scripts/benchmark-build.sh debug  # 对 debug 做基准

快速上手:一次跑完优化流程

在项目中落地全部优化的推荐顺序:

# 1. Create scripts directory and copy the scripts from this guide
mkdir -p scripts

# 2. Setup ccache (run once)
chmod +x scripts/setup-ccache.sh
./scripts/setup-ccache.sh

# 3. Optimize Gradle (run once or after fresh clone)
chmod +x scripts/optimize-gradle.sh
./scripts/optimize-gradle.sh

# 4. Update metro.config.js for Metro optimization
# Add dynamic worker allocation (see Section 2)

# 5. Add active architecture flag to package.json
# Add "--active-arch-only" to your dev script (see Section 4)

# 6. Build with benchmarking
chmod +x scripts/benchmark-build.sh
./scripts/benchmark-build.sh

首次完整构建之后,借助 ccache 命中,后续构建通常会明显更快。


总结

优化项预期收益
Gradle 并行 + 内存Android 构建约快 30%–50%
Metro maxWorkersJS 打包约 2–4 倍
ccache首次构建之后常再快 50%+
仅当前架构debug 构建约 2–3 倍

四项叠加,在现代多核机器上,release 从 20+ 分钟 压到 约 2–5 分钟 是合理预期;Apple Silicon 上往往还能更快。先跑一轮优化后的构建并持续看 profiling 报告,长期会省很多时间。


原文站点