次世代クロスプラットフォームフレームワーク「Lynx」 ファーストインプレッション
こんにちは!テラーノベルでiOS/Android/Webとフロントエンド周りを担当している @kazutoyoです!
ByteDanceが、モバイル/Web向けのクロスプラットフォームの新たなフレームワーク、「Lynx」を公開しました。
普段iOS/AndroidのネイティブやReact Native、Next.jsなどで開発している筆者が、Lynxを触ってみた感想を書いてみます。
Lynxのファーストインプレッション
良い部分
- 1つのコードでiOS/Android/Webようにアプリケーションを開発できる
- Web開発者に優しいMobile/Appの開発体験
- HTML/CSSに近いスタイル
- 独自のPrimJSによって、高いパフォーマンスを実現
- Mainスレッドとバックグラウンドスレッドが別れた設計になっており、UIの更新遅れなどが起きづらくなっている
- Grid Layoutなど、React Nativeより高機能な部分もある
- Native Module機能により、Lynxが提供していないネイティブのAPIも独自に追加することが出来る
- Rspeedy(Rspackベースのビルドツール)により、ビルドが高速
これからに期待な部分
- 導入がやや面倒
- Expo(React Native)やFlutterと比べ、ビルドして動かすまでのステップが多い
- エコシステムがまだまだこれから
- 登場したばかりなので仕方がないですが、現状のReact NativeやFlutterと比べてコミュニティが成熟していない
- LynxはプリミティブなAPIしか用意していないため、欲しい機能などは自分で作る必要がある
- エコシステムが成長すると、これらも豊富になるはず
- React NativeのContinuous Native Generationのような仕組みがない
- iOS/Androidのプロジェクトファイルを自分で設定する必要がある
Lynxについて
LynxはWebスキルを持つ開発者がモバイルアプリケーションも開発できるように焦点を当てていて、HTMLとCSSに近いAPIでUIの開発ができるように設計されています。
Lynxは、LynxエンジンがプリミティブなUIを各プラットフォームのAPIに変換を行っています。
https://lynxjs.org/guide/ui/elements-components.html
つまり、FlutterのようなSkiaエンジン上でUIを描画するのではなく、React NativeのようにネイティブのAPIを呼び出して画面を構成するようなイメージです。
Lynxの組み込み要素
Lynxでは現在次の6つのプリミティブな要素が用意されています。
-
<view>
- HTMLの
<div>
のような要素。レイアウトや表示要素として使用する。
- HTMLの
-
<text>
- テキスト用の要素。ネストもできたり、
<image>
を含めたりも出来る。
- テキスト用の要素。ネストもできたり、
-
<image>
- 画像の表示要素。
-
<scroll-view>
- 水平/垂直方向へのスクロールをするためのコンポーネント。コンテンツが表示領域より大きくなる場合に用いる。要素数が多く、繰り返し行われる場合は、よりパフォーマンスの良い
<list>
を使用する。
- 水平/垂直方向へのスクロールをするためのコンポーネント。コンテンツが表示領域より大きくなる場合に用いる。要素数が多く、繰り返し行われる場合は、よりパフォーマンスの良い
-
<list>
- 遅延読み込みによってレンダリングのパフォーマンスが良いスクロール可能なコンテナー。単純なリストだけではなく、グリッドやウォーターフォールなどもサポートする。
-
<page>
- ページ上でのルートの要素。HTMLの
<body>
タグのようなイメージ。
- ページ上でのルートの要素。HTMLの
UIを実装していきます。
Lynxでのスタイリング
Lynxでは、インラインでのスタイル指定と、CSSファイルとclass名指定でのスタイリングに対応しています。
index.tsx
import { root } from "@lynx-js/react";
import "./index.css";
function App() {
return (
<view
style={{
flexDirection: "column",
marginTop: "50%",
transform: "translate(-50%, -50%)",
marginLeft: "50%",
width: "150px",
height: "150px",
}}
class="bg-gradient"
>
</view>
);
}
index.css
.bg-gradient {
background: radial-gradient(
circle at top left,
rgb(255, 53, 26),
rgb(0, 235, 235)
);
}
レイアウト
Lynxでは4つのレイアウトの指定が可能です。
display: flex
Flexboxでのレイアウトです。
flex-grow
や flex-shrink
などの指定を行わない場合、よりシンプルな display: linear
の利用を推奨しています。
display: linear
AndroidのLinearレイアウトのように、子要素を順に並べるシンプルなレイアウトの場合に利用する。
display: grid
React Nativeでは対応されていないGridレイアウトもLynxではサポートされています。
レスポンシブに対応する際に、大きなメリットになりそうです。
display: relative
AndroidのRelativeレイアウトに近い要素で、親要素や他の子要素と相対的な位置でレイアウトすることができます。
例えば、次のようなユーザーのプロフィールカードのレイアウトは、他の要素や親要素の位置を参照して、レイアウトを行うことができます。
https://lynxjs.org/guide/ui/layout/relative-layout.html
アニメーション
Lynxでは一般的なWebのアニメーションのように、 @keyframes
やCSS Transitionなどをサポートしてします。
Lynxを試してみる
こちらのQuick Startを元にLynxを一旦iOS Simulatorで動かしてみましょう!
プロジェクトの作成
create rspeedyでプロジェクトを作成します。
pnpm create rspeedy@latest
LynxExplorerをiOS Simulatorにインストール
Lynx Exploreという、Lynxを動作させるためのサンドボックス環境をiOS Simulatorにインストールします。(ExpoのExpo Goに近いイメージ)
iOSシミュレーターのアーキテクチャによって、それぞれビルド済みのバイナリが配布されているので、それらをダウンロードして、解凍します。
arm64
x86_64
mkdir -p LynxExplorer-x86_64.app/
tar -zxf LynxExplorer-x86_64.app.tar.gz -C LynxExplorer-x86_64.app/
Xcodeを起動し、メニューの「Open Developer Tool」→「Simulator」から、もしくは以下のコマンドでiOSシミュレーターを起動します。
open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/
先ほど解凍した.appファイルをシミュレーターにD&Dしてアプリケーションをインストールします。
LynxExplorerでアプリケーションを実行する
作成したプロジェクトに移動し、 pnpm run dev
で起動します。
http://192.168.100.16:3000/main.lynx.bundle?fullscreen=true
がコンソールログに表示されるので、そのURLをLynxExplorerの「Card URL」上に入力して「Go」ボタンでアプリケーションを読み込みます。
これで開発環境が整いました!
HotReloadもかなり速い印象です。
ShowCaseを見る
LynxExplorerを起動すると「ShowCase」のメニューがあります。
そちらより、Lynxで出来ることがいろいろと確認することができます。
外部のアプリケーションを読み込む
LynxExplorerの「Card URL」に外部のURLを入力して、アプリケーションを実行することができます。
試しに、こちらのチュートリアルのコードを読み込んでみます。
まとめ
最初のまとめにも書きましたが、かなりWebのAPIに近く、Webの開発者にとっては敷居が低いのではないかと思います。
React NativeもReact Strict DOMにより、同じくWebのAPIと同じようにモバイルアプリケーションを作成できるように目指しています。
現状では、React NativeのほうがExpoやライブラリが豊富、コミュニティも大きいため、第一の選択肢になると思います。
しかし、今後のLynxの成長次第では、より良い選択肢になるのではないかと思います。
Discussion