如何讓你的 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 ,雖然直接引用很方便很快速,但會讓你的應用程式變肥啊!