React Nativeはメリット・デメリットがハッキリしている

少し前にReact Nativeの案件に携わったので感じたことを書いていきたい。
結論から言うとタイトル通り「React Nativeはメリット・デメリットがハッキリしている」というのを感じた。

自分について

自分はここ何年かはiOSのネイティブ開発を専門にしているので、どうしてもネイティブエンジニアとしてのバイヤスはかかることを承知して欲しい。また案件自体も直接React部分を構築したというよりも、ネイティブ部分との連携をしていたのがメインだ。ただ、React・TypeScriptの開発経験があるのでソースコードはよく読んだりしていた。

メリット

iOSAndroid対応のアプリを高速で作れる

具体的なアプリの機能については言及できないが、2.5人ぐらい人数で4ヶ月でアプリの大半の機能の構築が出来ていた。作業者の技能にも左右されるが、iOSAndroidのネイティブ開発者がそれぞれ別にいたとしてもこの期間で仕上げるのは可能だろうか言われると難しそうである。とくにアプリのViewのレイアウトに関してはHot ReloadがあるReact Native側の方が高速に開発できる。

もう一つネイティブ側の問題としてiOSAndroidで担当者がいるため、単純にコミュニケーションコストがかかるからである。そのためマルチプラットフォームの環境であればかなりそのコストを削減できるから

Expoが良さそう

ExpoとはReact Native上のフレームワークであり、SaaSとしてのプラットフォームでもある。メリットとしてはJavaScriptのみで開発出来て、面倒なビルド・配布・申請をExpo上でよしなにやってくれるらしい。
実はiOSの鬼門の一つはアプリのビルドだと思う。それはXcodeの学習や証明書など複合的に絡んでいるので、ネイティブエンジニアでも苦手な人がいる。その面倒なことをExpoがラップしてくれているので確かにこれは楽そうだなと感じた。

Xcodeを極力使わない

普段使っているテキストエディタを使えるのは地味にメリットな気がしている。Xcodeは容量でかい・重い・機能が多すぎるのでWeb側出身のエンジニアからしたら不評だと思う。自分も正直あまり使いたくないので基本はAppCodeを使って、要所要所でXcodeを使っている。結局Xcodeはアプリを作るためのアプリであるので、ソースコードの編集はより専門のIDEテキストエディタの方が機能としては優れている。

デメリット

Expoから外れると大変

これが結局最大のデメリットであると思う。メリットにも書いたExpoはいわゆるJavaScriptというWebに閉じた技術で完結するため非常に優れているが、逆に言うとExpoのサポート外の機能を使用すると大変になる。Expoをejectすると言われており例えばネイティブの機能をそのまま利用したい場合はejectする必要がある。その他にもマーケティング用のSDKを使用したいがそのSDKがネイティブしかサポートしていないためejectする必要があるなど。

こう書くとネイティブの機能を一切使わない様にすれば良いと思われるが、実行するのは難易度が高い。ビジネス側の事情もあるし、そもそもネイティブ機能を使わないと何でアプリに作ったんだっけとなる。初回リリースは大丈夫かもしれないが、サービスを継続すると必ずその判断は迫られと思う。

さらにメリットにあったアプリのビルド・配布・申請を自分たちで解決する必要になる。実際に難しいビルドのエラーが発生した場合Web中心に開発してきたメンバーで自力で解決するのは大変である。

Webとアプリの違い

直接React Nativeの問題ではないが、React Nativeを導入するWebメインの中心メンバーで引き起こされがちである。
例えば、誤解しがち一つにiPhoneiPadの開発は全然別である。Webでは現在レスポンシブデザインが中心にあるため、そのままの考えをアプリにもあてはめてレイアウト調整ぐらいの認識を持ってしまうことだ。 Appleもその誤解が生じているのを認識していてわざわざiPadOSというのを出して分離させている。そもそも、iPhoneiPadは画面サイズも違うのでそれにあったページデザインも必要で、ユーザーもiPhoneiPadでは求める機能が違う。

他にもアプリ化する目的の一つにPush通知もあるが個人的な経験から言うと初期リリースでは外した方が良い。ただ、理由を書くとそれ一つでかなりの文量になってしまうが、一言で言うならPush通知に夢を持ちすぎである。

ネイティブ連携が意外と大変

これは直接自分が担当して感じたのだが、React Nativeからネイティブの機能を呼び出そうとするとObjective-Cで連携箇所を書く必要がある。Objective-Cしかマクロに対応していないからという理由だったみたいだがとにかくObjective-Cを書く必要がある。Objective-Cが悪い言語とは別に思わないが現在のiOSの開発における主流ではないのは確かだ。Objective-CからSwiftのコードを呼びだすことも可能であるが、そうなると開発者はJavaScript(TypeScript)・Objective-C・Swiftの3つを覚える必要が出てくるのでかなり大変であるのであまりこの方法は取りたくない。そのため今回自分はObjective-Cだけでコードを完結させた。

また、TypeScriptからネイティブのコードを呼び出そうとすると型情報が失われるのでコンパイル時点でエラーを発見できない。そのためネイティブの機能に関しては実際に動かすまでは分からない。

React Nativeの採用はアリかナシか?

デメリットを結構書いてしまったが別に自分自身はReact Nativeの導入に否定的ではない。当たるかどうか分からないアプリをExpoのフレームワークに乗った上でサクッとリリースして検証するのはアリ。

ただし検証フェーズを終えたなら改めてReact Nativeで続行するかネイティブに切り替えるのかは判断した方が良い。恐らく継続的に開発するアプリでExpoでずっと要件を満たし続けるのは難しい。 結局、アプリの目的・機能・将来性のバランスを見ながら採用をジャッジするのが正しいと感じる。

そしてReact Nativeを導入するのであればネイティブエンジニアをコンサル要員で確保しとくのが良い。ビルド周りのエラーなどは頑張って自分で解決しようとするとかなり時間がかかるのもあるので。