如何讓你的 React Native 效能提升呢?接下將分享幾個優化的小技巧。
console
在開發 React Native 專案中,很常見的 debug 方式就是使用 console.warn()
、console.log()
、console.error()
,但這些 console
多少影響了 JavaScript 的執行效能。在 Production 環境也不會需要這些 console
。隨著專案越龐大,使用的console
也越來越多,這時候就需要可以自動把這些console
移除的工具 babel-plugin-transform-remove-console。
將 babel-plugin-transform-remove-console 導入你的 React Native 專案,讓你的專案在 Production 環境可以自動移除console
,在 Development 環境中還是有這些console
讓你可以 debug。
yarn add --dev babel-plugin-transform-remove-console
yarn add --dev @babel/preset-env
在 babel.config.js
中設定:
module.exports = api => {
const plugins = [];
if (
process.env.BABEL_ENV === 'production'
) {
plugins.push('transform-remove-console');
}
return {
presets: ['module:metro-react-native-babel-preset'],
plugins,
};
};
在 DAY 21 解析 React Native 新架構(New Architecture) 原理 時就有提到 Hermes 的啟用大幅縮減了應用程式打開的時間,提升了 JavaScript 與原生的溝通效率、也減少了 bundle 的大小。
(相關的證明可以看這篇 Measure Hermes engine performance in React Native with Flashlight,作者用了我在 DAY 24 React Native 效能優化: 使用 Flashlight 衡量應用程式效能 提及的 Flashlight 針對使用 Hermes 引擎與否與 React Native 效能提升的關係做了驗證。)
但不是所有 React Native 版本都是預設啟用 Hermes 引擎。
要測試 React Native 專案是否啟用 Hermes 引擎可以透過 global.HermesInternal
這個全域變數去檢查。
const isHermes = () => !!global.HermesInternal;
console.log('isHermes',isHermes());
在 android/app/build.gradle
中啟用 Hermes:
project.ext.react = [
entryFile: "index.js",
- enableHermes: false
+ enableHermes: true
]
然後清除
cd android && ./gradlew clean
再重新 build
npx react-native run-android
在 ios/Podfile
中啟用 Hermes:
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
- :hermes_enabled => false
+ :hermes_enabled => true
)
然後安裝 pod
cd ios && pod install
再重新 build
npx react-native run-ios
這裡要介紹一個工具 react-native-bundle-visualizer,這個工具就是把 React Native 專案打包成的 Metro bundler 視覺化,顯示整包 bundle 的分佈依賴的佔比。
yarn add --dev react-native-bundle-visualizer
yarn run react-native-bundle-visualizer
從上圖得知,整個專案的依賴除了 React Native 本身,最肥的就是 date-fns 約 1.34 MB 佔了 node_modules 9.5% 的空間。透過 react-native-bundle-visualizer 你可以知道哪些套件佔了多少空間,就可以針對這些佔比較重的套件進行優化。
點進來 date-fns 可以發現引用 locale 的佔比居然高達 989 KB !
回到專案,找到所有有引用 date-fns locale 的地方,發現原來我們的需求只是要把時間格式轉換為台灣時間,但是不小心把 date-fns 所有的當地時間的語系都一起載入了!難怪那麼肥!
- import { zhTW } from 'date-fns/locale'; 7.5k(gzipped:2.5k)
+ import zhTW from 'date-fns/locale/zh-TW'; 7.4k(gzipped:2.5k)
修改完成後,再看一次 react-native-bundle-visualizer。
yarn run react-native-bundle-visualizer
這時終端機就顯示這次的 bundle 相較上次縮小了。
可以發現 date-fns 從最肥的套件,掉到第 4 名了,從 1.34 MB 縮小到 403KB。
而本來的 locale 也從 989 KB減少到 22KB 了。
在整個專案中發現 lodash 只用了一個 debounce 的功能,而 debounce 基本上是可以自己用 JavaScript 實作的,所以也沒有必要直接引用整包 lodash ,雖然直接引用很方便很快速,但會讓你的應用程式變肥啊!