react-native-dom とは
experimental と書いてあるが普通に動く。デモを見ると React Native で提供されている仮想 DOM は大体動くといった感じ。
2018 年の React Europe で発表された資料。
https://rndom-slides.vincentriemer.app/
https://www.youtube.com/watch?v=aOWIJ4Mgb2k
これの何がすごいかというとブリッジの仕組みにのっとって構築されているところだ。 Native First と言っている。
ブリッジの仕組み
iOS のブリッジの仕組みは次でまとめているので参照のこと。
https://speakerdeck.com/januswel/discussion-about-the-bridge
https://qiita.com/janus_wel/items/93de843cc2243370fce4
Android は軽くググったら↓が本質的なことを書いていた。
要は React Native の基本設計として React 界と Native 界を結ぶブリッジというものがあり、そのブリッジは次の責務を持っている。
- JavaScript 実行スレッドの開始
- レンダリングスレッドの開始
- 各ネイティブモジュール用スレッドの開始
- JavaScript からネイティブ機能を呼び出す際、キューへのタスク追加
- ネイティブから JavaScript を呼び出す際、キューへのタスク追加
JavaScript スレッドとその他スレッドはそれぞれ機能呼び出しを媒介しているキューが存在していて、キューに積まれたタスクを各スレッドが消化していって JS 層とネイティブ層の連携がなされている、という理解をすればいい。
react-native-dom の設計
上述のブリッジの責務を、次のように実現している
- Web Worker をスレッドとして使っている
- レンダリングスレッドを Yoga の DOM 実装ベースで作っている
つまり React Native の設計思想に照らして DOM というネイティブプラットフォーム向けの実装をした、というパッケージになる。ちなみに yoga-dom は WebAssembly で提供されているようだ。
これがもたらすもの
じゃあ実際にどんなうれしいことがあるのかというと多分次になる。
- Learn Once, Write Anywhere
- コンポーネントベース開発の加速
- 実行速度
Learn Once, Write Anywhere
React.js が掲げている思想で、一度 React.js の流儀を学んだらどのプラットフォームでも書けるというもの。現状でも react-dom と React Native で実現できてはいるが、 react-dom を使う場合は Webpack や Parcel など React Native packager 以外の技術に習熟する必要があった。
これは次のように利点として掲げられている。
Built with the same bundler used for existing React Native platforms: Build both the "native" main and JS threads with the Metro Bundler along with all the developer experience features it provides.
フレームワークとして easy 寄りの選択ではあるが、「感覚を持ち回せる」というのは開発効率に直結する。
また、 React Native はクロスプラットフォーム開発の基盤として Write Once, Run Anywhere の文脈で語られることが多かったが、流石に Web アプリも含めて 1 source で対応しようとする人間はいないだろう。文脈が違いすぎるので UI 設計レベルで別物になるはずだ。
ただ、次の利点であるコンポーネントの流用が加速することで開発効率の上昇も見込める。
コンポーネントベース開発の加速
atomic design でいうところの atoms や molecules まではプラットフォーム共通のコンポーネントを作り込んで流用ということがしやすくなる。つまり Web アプリとネイティブアプリで同じ見た目を持つボタンを共有しやすくなるので CI に準拠しやすくなるなどの利点がある。
organisms や templates など、画面コンポーネントを含む大きなコンポーネントは各プラットフォームで作り込むべきだが、境界さえしっかりと認識していればコンポーネントベースの恩恵を余すところなく享受できるようになるのは強みだ。
実行速度
クライアントサイド Web アプリで特に苦労することなくマルチスレッドが使える。これだけで夢が広がる。
Multithreaded by default: Following the exact same architecture as React Native on mobile, all of your react components/app logic are run in web worker, leaving the main thread to entirely focus on rendering.
たとえば機械学習などの重い計算処理を別スレッドにディスパッチするなど、いくらでも用途がある。
選択肢としてアリなんじゃないか
まだファイルサイズが大きいから production ready ではないよ、と書かれていること、速度のチューニングをこれからすることを考えると、確かにまだ使っていくのは難しいかもしれない。 React Europe での講演資料の中に次をやっていきたいと書いてあった。
- Async/Multithreaded Layout
- More WebAssembly
- First-Class PWA Support
- WebGL Renderer
ただし、アプローチとしてまっとうであることは理解できる。
どう転ぶかわからないのは今まで CSS で担保されてきた表現力を Yoga や独自レンダリングによってどこまで引き出すことが可能なのか、という点。 CSS をフルに使っていきたい、という場面以外では production ready にさえなれば選択肢としてアリなんじゃないか、と思う。