Optimize Assets
OTA update size directly affects download success rates on poor networks and the time users spend waiting for an update to apply. This page covers both built-in DeployPulse optimizations and app-side best practices for keeping bundle sizes small.
Built-in: Differential Packages
DeployPulse automatically generates a differential package for every release after the first. Only files that changed since the previous release are included in the download — the unchanged parts of the bundle are reused from the device's cached copy.
The diff badge in the dashboard's release history confirms that a differential package was generated. No configuration is needed.
The first release to a deployment is always a full bundle. Every release after that will be a diff, provided the previous release is still available.
Use Hermes
Hermes is the default JavaScript engine in React Native 0.70 and later. If your project was created with RN 0.70+, Hermes is already enabled - no changes needed.
For projects on older React Native versions, enable Hermes in your native config:
android/app/build.gradle
project.ext.react = [
enableHermes: true
]
ios/Podfile
use_react_native!(
:hermes_enabled => true
)
No special dpctl flags are needed when using Hermes. dpctl release-react produces a standard JavaScript bundle that Hermes compiles to bytecode on the device at first run and caches from then on.
Exclude Source Maps
Source maps can double the bundle size if accidentally included in the OTA release zip. Always output them to a path outside --outputDir:
dpctl release-react MyApp-iOS ios \
--outputDir ./release \
--sourcemapOutput ./sourcemaps/main.jsbundle.map \
--dev false
If you use Sentry, upload the map file separately after releasing. See the Sentry Integration guide.
Image Optimization
Images frequently account for 60–80% of bundle size. A few changes can have a large impact:
react-native-imagemin-asset-plugin— Metro plugin that automatically compresses PNG, JPG, and WebP assets at build time with no quality loss.- SVGO — lossless SVG optimization for
react-native-svgassets. Run as a build step:svgo --folder ./src/assets/icons. - Remove
@1xassets — modern Android and iOS devices no longer use@1ximages. Removing them reportedly reduces bundle size by ~12%. - Avoid
data:imageURIs — inline base64 images inflate the JS bundle and prevent differential updates from being effective. Always reference assets by path.
Reduce JS Bundle Size
react-native-bundle-visualizer— runs Metro and opens an interactive treemap to identify which dependencies are largest.- Knip — static analysis tool that detects unused exports and files. Removing dead code shrinks the bundle and improves diff efficiency between releases.
- Avoid large JSON files in the bundle — localization files and feature flag payloads are common offenders. Lazy-load them at runtime or fetch from a remote endpoint instead of bundling.
Font Optimization
Fontmin generates subset fonts that contain only the Unicode characters your app actually uses. Subsetting a custom font from 400KB to 40KB is common for apps that use a limited character set.
Release Flags
Always build releases with:
dpctl release-react MyApp-iOS ios \
--deployment Production \
--dev false \
--minify true
--dev false— disables the React Native DevTools bridge, assertions, and verbose logging. Required for production.--minify true— applies additional Terser minification on top of Metro's default output.
Further Reading
- Sentry Integration — upload sourcemaps for symbolicated crash traces
- Code Signing — sign releases for verified delivery
- Troubleshooting — diagnose slow or failing updates
