フレームワークの比較
このページをご覧になっているということは、おそらく他のフレームワークでアプリケーションを構築した経験があり、Mithril.js が抱えている課題をより効果的に解決できるかどうかを知りたいと思っているのでしょう。
なぜ [お気に入りのフレームワーク名] ではないのか?
実際には、現代的なフレームワークのほとんどは高速で、複雑なアプリケーションの構築に適しており、適切に使用すればメンテナンスも可能です。Udemy は Angular を、AirBnB は React を、Gitlab は Vue を、Guild Wars 2 は Mithril.js を使用しています(ゲーム内でも!)。これらはすべて、本番環境で十分に利用できるフレームワークです。
経験則として、すでに別のフレームワーク/ライブラリ/スタックに深く投資しているチームであれば、コストのかかる書き換えを正当化できるほどの理由がない限り、既存のものを使い続けるのが賢明です。
ただし、新規プロジェクトであれば、Mithril.js を試してみることをお勧めします。わずか 10KB 未満(gzip 圧縮時)のコードから、どれほどの価値を引き出せるかを確認するだけでも価値があります。Mithril.js は、Vimeo、Nike、Fitbit などの多くの有名企業で使用されており、Lichess や Flarum などの大規模なオープンソースプラットフォームも支えています。
なぜ Mithril.js を使うのか?
一言で言えば、Mithril.js は実用的だからです。10 分ガイド が良い例です。コンポーネント、XHR、ルーティングの基本を習得するのにかかる時間はそれくらいで、これは実用的なアプリケーションを構築するために必要な知識の量とほぼ同じです。
Mithril.js は、意味のある作業を効率的に行うことを重視しています。ファイルのアップロードが必要ですか?ドキュメントで方法を解説しています。認証は?ドキュメント化されています。終了アニメーションは?用意されています。追加のライブラリや特別な仕掛けは必要ありません。
比較
React
React は、Facebook によってメンテナンスされているビューライブラリです。
React と Mithril.js は多くの共通点があります。React の経験があれば、Mithril でアプリケーションを構築するために必要な知識のほとんどはすでに持っていると言えるでしょう。
- どちらも仮想 DOM、ライフサイクルメソッド、キーベースの差分検出を使用します。
- どちらもコンポーネントを使ってビューを整理します。
- どちらも JavaScript をビュー内のフロー制御メカニズムとして使用します。
React と Mithril.js の最も大きな違いは、そのスコープにあります。React はビューライブラリであるため、一般的な React ベースのアプリケーションは、ルーティング、XHR、状態管理のためにサードパーティのライブラリに依存します。ライブラリ指向のアプローチにより、開発者は自分のニーズに合わせてスタックを細かくカスタマイズできます。ただし、React ベースのアーキテクチャはプロジェクトごとに大きく異なる可能性があり、プロジェクトのサイズが 1MB を超える可能性も高くなります。
Mithril.js には、ルーティングや XHR など、一般的な必須機能のための組み込みモジュールがあり、ガイド で標準的な使用方法を紹介しています。このアプローチは、一貫性とオンボーディングの容易さを重視するチームに適しています。
パフォーマンス
React と Mithril.js はどちらもレンダリングパフォーマンスを重視していますが、アプローチが異なります。過去には、React には 2 つの DOM レンダリング実装がありました(DOM API を使用するものと、innerHTML
を使用するもの)。将来導入予定の Fiber アーキテクチャでは、作業単位のスケジューリングと優先順位付けが導入されます。React には、本番環境へのデプロイメントのためにさまざまなチェックとエラーメッセージを無効にする洗練されたビルドシステムと、ブラウザ固有の最適化も備わっています。さらに、React の shouldComponentUpdate
フックと、イミュータブルデータ構造ライブラリの高速なオブジェクト等価性チェックを利用して、仮想 DOM の再調整時間を短縮する、パフォーマンス指向のライブラリも存在します。一般的に、React のパフォーマンスへのアプローチは、比較的複雑なソリューションを設計することです。
Mithril.js は、より少ない方が良いという考え方を採用しています。より小さく、積極的に最適化されたコードベースを持っています。これは、小さなコードベースの方が監査と最適化が容易であり、最終的に実行されるコードが少なくなるためです。
ライブラリのロード時間、つまり各フレームワークの JavaScript コードを解析して実行するのにかかる時間を比較するために、フレームワークコードのみで構成されるスクリプトの最初の行に console.time()
呼び出しを追加し、最後に console.timeEnd()
呼び出しを追加します。便宜上、以下に、バンドルされたスクリプトに手動でロギングコードを追加し、スペック控えめな 2010 年製の PC デスクトップ上の Chrome で実行した、20 回試行中の最良値を示します。
React | Mithril.js |
---|---|
55.8 ms | 4.5 ms |
ライブラリのロード時間は、長時間開いたままにならないアプリケーション(モバイルアプリなど)で重要であり、キャッシュやその他の最適化手法では改善できません。
これはマイクロベンチマークであるため、ハードウェアが数値に大きく影響する可能性があります。これらのテストを自分で再現することをお勧めします。Webpack などのバンドラーフレームワークは、静的モジュール解決をエミュレートするために、タイマー呼び出しの前に依存関係を移動できるため、コンパイルされた CDN ファイルからコードをコピーするか、バンドラーライブラリから出力ファイルを開き、高解像度タイマー呼び出し console.time
と console.timeEnd
をバンドルされたスクリプトに手動で追加する必要があります。new Date
と performance.now
の使用は避けてください。これらのメカニズムは統計的に正確ではありません。
便宜上、Web 上の CDN を使用するように適合されたベンチマークのバージョンを以下に示します。React のベンチマークはこちら、Mithril.js のベンチマークはこちら です。React と同等のスコープであるレンダリングモジュールのみをベンチマークするのではなく、Mithril.js 全体をベンチマークしていることに注意してください。また、この CDN 駆動のセットアップでは、ディスクキャッシュからリソースをフェッチするためにいくつかのオーバーヘッドが発生することにも注意してください(リソースあたり約 2ms)。これらの理由により、ここの数値は完全に正確ではありませんが、Mithril.js の初期化速度が React よりも著しく優れていることを確認するには十分です。
以下は、より意味のあるベンチマークです。10,000 個の div(および 10,000 個のテキストノード)を作成するためのスクリプト時間を測定します。繰り返しますが、React と Mithril.js のベンチマークコードを以下に示します。それらの最良の結果を以下に示します。
React | Mithril.js |
---|---|
99.7 ms | 42.8 ms |
これらの数値は、Mithril.js が大幅に高速に初期化されるだけでなく、React が使用可能になる前に、20,000 個以上の仮想 DOM ノードを処理できることを示しています。
更新パフォーマンス
更新パフォーマンスは、Single Page Application では頻繁に更新が発生するため、初期レンダリングよりも重要になる場合があります。
更新パフォーマンスをベンチマークするのに役立つツールは、Ember チームによって開発された DbMonster と呼ばれるツールです。テーブルをできるだけ速く更新し、1 秒あたりのフレーム数(FPS)と JavaScript 時間(最小、最大、平均)を測定します。FPS 値はブラウザの再描画時間と setTimeout
のクランプ遅延も含まれるため、正確な評価が難しい場合があります。したがって、最も意味のある数値は平均レンダリング時間です。React の実装 と Mithril.js の実装 を比較できます。サンプル結果を以下に示します。
React | Mithril.js |
---|---|
12.1 ms | 6.4 ms |
開発パフォーマンス
もう 1 つ留意すべき点は、React は開発モードで追加のチェックと役立つエラーメッセージを追加するため、上記のベンチマークで使用されている本番バージョンよりも開発の方が遅いことです。説明のために、上記の 10,000 ノードベンチマークを React の開発バージョンで使用したものを以下に示します。
ドロップイン置換
React との API 互換性を謳う プロジェクト、[プロジェクト]、プロジェクトがいくつか存在します(一部は互換レイヤーライブラリを使用)。ただし、それらは完全には互換性がありません(たとえば、PropType のサポートは通常スタブアウトされ、合成イベントはサポートされない場合があり、一部の API は異なるセマンティクスを持ちます)。これらのライブラリには通常、公式の React API の一部ではない独自の機能も含まれていることに注意してください。これは、React Fiber に戻ることを決定した場合に、後々問題になる可能性があります。
ダウンロードサイズが小さいという主張は(React と比較して)事実ですが、これらのライブラリの多くは Mithril.js のレンダラーモジュールよりもわずかに大きいです。Preact は唯一の例外です。
一部のプロジェクトで使用されているベンチマークは、古く、欠陥があり(悪用可能な点がある)、積極的なパフォーマンスの主張には注意が必要です。ベンチマークの作成者の一部である Boris Kaul は、ベンチマークがどのように操作されるかについて詳しく書いています。もう 1 つ留意すべき点は、一部のベンチマークでは高度な最適化機能を積極的に使用しているため、潜在的な パフォーマンス、つまり、いくつかの注意点があれば可能なパフォーマンスを示していますが、コードベース全体を調べて最適化の候補を特定し、最適化の注意点によってもたらされる回帰リスクを評価するために積極的に時間を費やさない限り、現実的にはありそうもありません。
典型的な パフォーマンス特性を示すという精神で、この比較ページに示されているベンチマークは、リンゴとリンゴを比較する、ナイーブで慣用的な方法(つまり、通常コードの 99% を記述する方法)で実装されており、一方または他方のフレームワークを人為的に良く見せるためのトリックや高度な最適化は使用していません。ここの DbMonster の実装がより慣用的に記述できると思われる場合は、PR を投稿することをお勧めします。
複雑さ
React と Mithril.js はどちらも、他のフレームワークと比較して API サーフェスが比較的小さいため、学習曲線を容易にするのに役立ちます。ただし、標準的な Mithril.js は、プレーンな ES5 を使用し、他の依存関係なしに、可読性を損なうことなく記述できますが、標準的な React は、複雑なツール(Babel、JSX プラグインなど)に大きく依存しており、このレベルの複雑さは、構文拡張(Redux の非標準オブジェクトスプレッド構文など)、アーキテクチャ(イミュータブルデータライブラリを使用するもの)、または便利な機能(ホットモジュールリロードなど)の形式で、そのエコシステムの一般的な部分に頻繁に拡張されます。
複雑なツールチェーンは、Mithril.js や他のフレームワークでも可能ですが、Mithril を使用する場合は、KISS と YAGNI の原則に従うことを 強く お勧めします。
学習曲線
React と Mithril.js はどちらも、比較的緩やかな学習曲線を持っています。React の学習曲線は、主にコンポーネントとそのライフサイクルを理解することに関係しています。Mithril.js コンポーネントの学習曲線もほぼ同じです。Mithril.js には、ルーティングと XHR も含まれているため、学ぶべき API は多くなりますが、学習曲線は、React、React Router、および superagent や axios などの XHR ライブラリを学ぶのとほぼ同じです。
標準的な React では、JSX とその注意点に関する実用的な知識が必要であるため、Babel に関連する小さな学習曲線も存在します。
ドキュメント
React のドキュメントは明確でよく書かれており、優れた API リファレンス、入門チュートリアル、およびさまざまな高度な概念をカバーするページが含まれています。残念ながら、React はビューライブラリに限定されているため、そのドキュメントでは、実際のアプリケーションのコンテキストで React を標準的に使用する方法については説明していません。その結果、多くの一般的な状態管理ライブラリが存在し、React を使用するアーキテクチャは、会社ごと(またはプロジェクト間でも)大きく異なる可能性があります。
Mithril.js のドキュメントには、入門 チュートリアル、高度な概念に関するページ、および広範な API リファレンスセクションも含まれており、入力/出力タイプ情報、さまざまな一般的なユースケースの例、および誤用やアンチパターンに対するアドバイスが含まれています。また、クイックリファレンス用のチートシートも含まれています。
Mithril.js のドキュメントでは、Web 標準が大規模な確立されたライブラリと同等になる可能性がある場合に、実際のアプリケーションでの一般的なユースケースに対するシンプルで低レベルなソリューションも紹介しています。
Angular
Angular は、Google によってメンテナンスされている Web アプリケーションフレームワークです。
Angular と Mithril.js はかなり異なりますが、いくつかの共通点があります。
- どちらもコンポーネント化をサポートしています。
- どちらも Web アプリケーションのさまざまな側面(ルーティング、XHR など)のためのツールを提供しています。
Angular と Mithril.js の最も明白な違いは、その複雑さにあります。これは、ビューがどのように実装されるかで最も簡単にわかります。Mithril.js ビューはプレーンな JavaScript であり、フロー制御は、三項演算子や Array.prototype.map
などの JavaScript 組み込みのメカニズムで行われます。一方、Angular は、HTML 属性と補間内で JavaScript のような式を評価できるように、HTML ビューを拡張するためのディレクティブシステムを実装しています。Angular は実際に、それを実現するために JavaScript で記述されたパーサーとコンパイラーを提供しています。さらに複雑なことに、実際には 2 つのコンパイルモードがあります(パフォーマンスのために JavaScript 関数を動的に生成するデフォルトモードと、コンテンツセキュリティポリシーの制限を処理するためのより遅いモード)。
パフォーマンス
Angular は、長年にわたってパフォーマンスの面で多くの進歩を遂げてきました。Angular 1 は、大規模な $scope
構造を常に差分する必要があるため、遅くなる傾向があるダーティチェックと呼ばれるメカニズムを使用していました。Angular 2 は、はるかにパフォーマンスの高いテンプレート変更検出メカニズムを使用しています。ただし、Angular の改善にもかかわらず、Mithril.js の小さなコードベースサイズがもたらす監査の容易さにより、Mithril.js は Angular よりも高速であることがよくあります。
Angular と Mithril.js のロード時間を比較することは、いくつかの理由で困難です。1 つ目は、Angular 1 と 2 が実際には完全に異なるコードベースであり、両方のバージョンが公式にサポートおよびメンテナンスされていることです(そして、現在、実際の Angular コードベースの大部分はまだバージョン 1 を使用しています)。2 つ目の理由は、Angular と Mithril.js の両方がモジュール式であることです。どちらの場合も、特定のアプリケーションで使用されていないフレームワークの重要な部分を削除することができます。
そうは言っても、最小の既知の Angular 2 バンドルは、Brotli アルゴリズムで圧縮された 29kb の hello world です(標準の gzip を使用すると 35kb)。また、Angular のほとんどの便利な機能が削除されています。比較すると、Mithril.js の hello world - すべての機能を含む Mithril.js コア全体 - は、約 10kb gzip 圧縮になります。
また、Angular や Mithril.js などのフレームワークは、自明ではないアプリケーション向けに設計されていることを覚えておいてください。したがって、Angular の API サーフェスをすべて使用することができたアプリケーションは、わずか 29kb ではなく、数百 kb のフレームワークコードをダウンロードする必要があります。
更新パフォーマンス
更新パフォーマンスをベンチマークするのに役立つツールは、Ember チームによって開発された DbMonster と呼ばれるツールです。テーブルをできるだけ速く更新し、1 秒あたりのフレーム数(FPS)と JavaScript 時間(最小、最大、平均)を測定します。FPS 値はブラウザの再描画時間と setTimeout
のクランプ遅延も含まれるため、正確な評価が難しい場合があります。したがって、最も意味のある数値は平均レンダリング時間です。Angular の実装 と Mithril.js の実装 を比較できます。どちらの実装もナイーブです(つまり、最適化はありません)。サンプル結果を以下に示します。
Angular | Mithril.js |
---|---|
11.5 ms | 6.4 ms |
複雑さ
Angular は、豊富なツール(ディレクティブやサービスなど)を提供する点で Mithril.js よりも優れていますが、複雑さも増しています。Angular の API サーフェス と Mithril.js' を比較してください。どちらの API がより自己記述的で、あなたのニーズにより関連性があるかについて、自分で判断できます。
Angular 2 には、理解すべき概念がはるかに多くあります。言語レベルでは、TypeScript が推奨される言語であり、その上に、バインディング、パイプ、「安全なナビゲーター演算子」などの Angular 固有のテンプレート構文もあります。また、モジュール、コンポーネント、サービス、ディレクティブなどのアーキテクチャの概念と、どこで何を使用するのが適切かについても学ぶ必要があります。
学習曲線
同等の機能を比較すると、Angular 2 と Mithril.js は同様の学習曲線を持っています。どちらでも、コンポーネントはアーキテクチャの中心的な側面であり、どちらも妥当なルーティングツールと XHR ツールを持っています。
そうは言っても、Angular には Mithril よりも学ぶべき概念がはるかに多くあります。多くの場合、簡単に実装できる多くのことに対して、Angular 固有の API を提供しています(たとえば、複数形化は本質的に switch ステートメントであり、「必須」検証は単なる等価性チェックなどです)。Angular テンプレートには、Mithril.js で JavaScript がネイティブに行うことをエミュレートするための抽象化のレイヤーもいくつかあります - Angular の ng-if
/ngIf
は ディレクティブ であり、カスタム パーサー と コンパイラー を使用して式文字列を評価し、レキシカルスコープをエミュレートします...など。Mithril.js ははるかに透過的である傾向があるため、推論が容易です。
ドキュメント
Angular 2 のドキュメントには、広範な入門チュートリアルと、アプリケーションを実装する別のチュートリアルが用意されています。また、高度な概念、チートシート、およびスタイルガイドに関するさまざまなガイドもあります。残念ながら、現時点では、API リファレンスには改善の余地があります。いくつかの API はドキュメント化されていないか、API が何に使用される可能性があるかについてのコンテキストを提供していません。
Mithril.js のドキュメントには、入門 チュートリアル、高度な概念に関するページ、および広範な API リファレンスセクションも含まれており、入力/出力タイプ情報、さまざまな一般的なユースケースの例、および誤用やアンチパターンに対するアドバイスが含まれています。また、クイックリファレンス用のチートシートも含まれています。
Mithril.js のドキュメントでは、Web 標準が大規模な確立されたライブラリと同等になる可能性がある場合に、実際のアプリケーションでの一般的なユースケースに対するシンプルで低レベルなソリューションも紹介しています。
Vue
Vue は、Angular に似たビューライブラリです。
Vue と Mithril.js には多くの違いがありますが、いくつかの共通点も共有しています。
- どちらも仮想 DOM とライフサイクルメソッドを使用します。
- どちらもコンポーネントを使ってビューを整理します。
Vue 2 は、Snabbdom のフォークを仮想 DOM システムとして使用します。さらに、Vue はルーティングと状態管理のためのツールも個別のモジュールとして提供します。Vue は Angular と非常によく似ており、同様のディレクティブシステム、HTML ベースのテンプレート、およびロジックフローディレクティブを提供します。Angular と異なるのは、コンポーネントのデータツリー内のネイティブメソッドを上書きするモンキーパッチを用いたリアクティブシステムを実装していることです(一方、Angular 1 はダーティチェックとダイジェスト/適用サイクルを使用して同様の結果を実現します)。Angular 2 と同様に、Vue は HTML テンプレートを関数にコンパイルしますが、コンパイルされた関数は、Angular のコンパイルされたレンダリング関数ではなく、Mithril.js または React ビューのように見えます。
Vue は、同等の機能を比較すると Angular よりも大幅に小さいですが、Mithril.js ほど小さくはありません(Vue コアは約 23kb gzip 圧縮ですが、Mithril.js の同等のレンダリングモジュールは約 4kb gzip 圧縮です)。どちらも同様のパフォーマンス特性を持っていますが、ベンチマークでは通常、Mithril.js の方がわずかに高速であることが示唆されています。
パフォーマンス
ライブラリのロード時間、つまり各フレームワークの JavaScript コードを解析して実行するのにかかる時間を比較するために、フレームワークコードのみで構成されるスクリプトの最初の行に console.time()
呼び出しを追加し、最後に console.timeEnd()
呼び出しを追加します。便宜上、以下に、バンドルされたスクリプトに手動でロギングコードを追加し、スペック控えめな 2010 年製の PC デスクトップ上の Chrome で実行した、20 回試行中の最良値を示します。
Vue | Mithril.js |
---|---|
21.8 ms | 4.5 ms |
ライブラリのロード時間は、長時間開いたままにならないアプリケーション(モバイルアプリなど)で重要であり、キャッシュやその他の最適化手法では改善できません。
更新パフォーマンス
更新パフォーマンスをベンチマークするのに役立つツールは、Ember チームによって開発された DbMonster と呼ばれるツールです。テーブルをできるだけ速く更新し、1 秒あたりのフレーム数(FPS)と JavaScript 時間(最小、最大、平均)を測定します。FPS 値はブラウザの再描画時間と setTimeout
のクランプ遅延も含まれるため、正確な評価が難しい場合があります。したがって、最も意味のある数値は平均レンダリング時間です。Vue の実装 と Mithril.js の実装 を比較できます。どちらの実装もナイーブです(つまり、最適化はありません)。サンプル結果を以下に示します。
Vue | Mithril.js |
---|---|
9.8 ms | 6.4 ms |
複雑さ
Vue は Angular に大きく影響を受けており、Angular が行う多くのこと(たとえば、ディレクティブ、フィルター、双方向バインディング、v-cloak
)を持っていますが、React に影響を受けたもの(たとえば、コンポーネント)も持っています。Vue 2.0 の時点では、(シングルファイルコンポーネントやさまざまな webpack ベースの言語トランスパイルプラグインに加えて)ハイパースクリプト/JSX 構文を使用してテンプレートを記述することもできます。Vue は、双方向データバインディングとオプションの Redux のような状態管理ライブラリの両方を提供しますが、Angular とは異なり、スタイルガイドは提供していません。一つのことを実現する複数の方法のアプローチは、長期的なプロジェクトでアーキテクチャの断片化を引き起こす可能性があります。
Mithril.js は、概念がはるかに少なく、通常、コンポーネントとデータレイヤーの観点からアプリケーションを整理します。Mithril.js のすべてのコンポーネント作成スタイルは、ネイティブ JavaScript 機能のみを使用して同じ vnode 構造を出力します。言語に依存することの直接的な結果は、ツールが少なく、プロジェクトのセットアップが簡単になることです。
ドキュメント
Vue と Mithril.js はどちらも優れたドキュメントを持っています。どちらも、例を含む優れた API リファレンス、入門チュートリアル、およびさまざまな高度な概念をカバーするページが含まれています。
ただし、Vue の 1 つのことを行うための多くの方法のアプローチにより、一部のことが適切にドキュメント化されていない可能性があります。例えば、ハイパースクリプトに関する説明は不足しています。
Mithril.js のドキュメントは通常、トピックに Mithril の範囲外のことが含まれている場合に、過度に徹底的であるという誤りを犯します。たとえば、トピックにサードパーティライブラリが含まれている場合、Mithril.js のドキュメントでは、サードパーティライブラリのインストールプロセスについて説明します。Mithril.js のドキュメントでは、Web 標準が大規模な確立されたライブラリと同等になる可能性がある場合に、実際のアプリケーションでの一般的なユースケースに対するシンプルで低レベルなソリューションも紹介しています。
Mithril.js のチュートリアルでは、Vue よりもはるかに多くのことをカバーしています。Vue のチュートリアル は、その大規模なコア API をカバーするためにいくつかのページを通過した後、単純なローカル ToDo リストで終了します。Mithril.js の 10 分ガイド は、その API の大部分をカバーし、サーバーからのデータのフェッチやルーティングなど、実際のアプリケーションの重要な側面についても説明します。それが十分でない場合は、より長く、より徹底的なチュートリアル もあります。