カランのブログ

ソフトウェアエンジニア / 台湾人 / 福岡生活

今のモード ライト

Svelte:新しいフロントエンドフレームワークの登場

最初にSvelteを見たとき、「ああ、また新しいフロントエンドフレームワークか」と思ってあまり気にしなかった。しかし、最近では多くのブログ記事やウェブサイトで紹介されていることを見て、私の好奇心が引かれるようになった。

公式ウェブサイトのチュートリアルとドキュメントを見て初めて、これは通常の「フロントエンドフレームワーク」とは異なるアプローチで、文法レベルでコンパイラと組み合わせてシンプルで効率的なコードを書くものだと気づいた。

Svelte

次のフレーズに私の興味を引かれました:

Svelteはコードを小さなフレームワークのないバニラJSにコンパイルします - あなたのアプリは高速に起動し、高速であるままです。

実際に一度書いてみたところ、Reactに慣れている私はいくつかの方法について考える必要がありましたが、全体的に非常に好きで、他の(React、Vueなどの)フレームワークとはまったく異なるコンセプトです。

私は皆さんに、Svelteの作者がYGLFでの講演「Rethinking reactivity」を見て、フロントエンドフレームワークの本質と私たちが何を実現できるかを再考してみることをお勧めします。以下は、この講演についての私のメモと考察です。

リアクティビティとは何か?

関数型リアクティブプログラミングの本質は、値の動的な振る舞いを宣言時に完全に指定することです - Heinrich Apfelmus

私たちがフロントエンドフレームワークを使用する際、通常2つのことを考慮します:

  • 仮想DOM:ページのレンダリングパフォーマンスの確保
  • リアクティビティ:値の変更を追跡する

フロントエンドフレームワークの最も重要な部分は、データフローとデータの変更のトラッキングです。

仮想DOMの使用理由

主な理由は、データの更新がページ全体の再レンダリングに影響すると、パフォーマンスに大きな影響があるためです。そのため、仮想DOMは通常、必要な変更のみを再レンダリングするための効率的なdiffアルゴリズムを実装しています。

しかし、問題があります。安定したdiffアルゴリズムと更新メカニズムを実装するには、非常に多くの作業が必要で、パフォーマンスの制約も考慮する必要があります。ツリーの深さが深くなると、パフォーマンスのボトルネックが発生する可能性があるためです。

リアクティビティ

Reactは、データの変更を追跡するためにsetStateuseStateを使用します。一方、VueはProxyの方式を採用し、開発者が値にアクセスする際にリアクティビティメカニズムをトリガーし、データの変更を追跡します。

Reactでは、useStateまたはthis.setStateを使用して値の変更を検知し、余分な更新を行わないようにするメカニズムがあります。以下のコードを見てみましょう:

const Counter = () => {
  const [counter, setCounter] = useState(0);
	const handleClick = () => {
    setCounter(c => c + 1)
  }
	return <div onClick={handleClick}>{counter}</div>
}

コンポーネントが更新されるたびに、useStatehandleClick関数が再評価されます。React内部ではこれらの状態の変化を保存し、適切な更新を行います。

この問題を解決するために、useMemoや他の最適化手段が導入されました:

  • shouldComponentUpdate
  • React.PureComponent
  • useMemo
  • useCallback

これらのメカニズムの実装には多くの労力がかかり、画面の再レンダリング時に全体を再描画しないようにするためのものです。これにより、バグの少ないコードが作成され、面倒な作業ではなく創造的な作業に時間を費やすことができます。しかし、これらのメカニズムにより、reactやreact-domのバンドルサイズが非常に大きくなります。

実際、作者自身が公式ブログで「Virtual DOMは純粋なオーバーヘッド」という記事を公開し、Virtual DOMによってもたらされる利点と犠牲を説明しています。記事の結論を引用すると:

重要なのは、仮想DOMは「機能」ではなく、「目的」です。それは、状態遷移について考えずにアプリを構築し、一般的に十分なパフォーマンスを持つことを可能にするための手段です。これにより、バグの少ないコードが作成され、退屈な作業ではなく創造的な作業に時間を費やすことができます。

しかし、仮想DOMを使用せずに同様のプログラミングモデルを実現することもできます - それがSvelteの役割です。

また、記事中には興味深いツイートもあります:

仮想DOMのメカニズムは、フレームワークが状態管理について心配しなくても済むようにするために存在しますが、なぜこのメカニズムをプラットフォーム自体が提供しないのでしょうか?これは興味深い視点ですが、実際に実装するためにはどれほどの労力が必要か、またブラウザによる互換性や規格に対する問題が発生する可能性があるため、フレームワーク自体よりも進化の速度が遅いかもしれません。

Svelte

バンドルサイズが大きいわけではありませんが、製品のコードと組み合わせると、このバンドルサイズは驚くほど大きくなります。

以上の考えをまとめると、現代のフロントエンドフレームワークの欠点は次のとおりです:

  • ランタイムのリアクティビティ+仮想DOMのdiffメカニズム
  • 大きなバンドルサイズ

バンドルサイズやパフォーマンスについて気にする必要があるかどうかは人それぞれかもしれませんが、いつかはハードウェアの性能やネットワークの速度が追いつくでしょう。そのときには差があまり明確ではなくなり、コード分割やダイナミックインポートなどの手法を使用して初期のバンドルサイズを効果的に減らすこともできます。

また、強力なトランスパイラであるBabelを使用することで、JavaScriptにBabelのサポートを加えることで、ランタイムで行う必要のある複雑なタスクをできるだけ減らすことができます。また、WebAssemblyやArrayBufferなどのlow-level APIの進歩により、Webの発展は新たな局面を迎えるかもしれません。この時代では、フロントエンドだけでなく、シンプルなコンパイラを作る方法も学ばなければなりません。

次の記事

チャット flv.js

前の記事

スヴェルトノート (1)-特効薬なし

この文章が役に立つと思うなら、下のリンクで応援してくれると大変嬉しいです✨

Buy me a coffee

作者

Kalan 頭像照片,在淡水拍攝,淺藍背景

愷開 | Kalan

Kalan です。台湾出身で、2019年に日本へ転職し、福岡に住んでいます。フロントエンド開発に精通しているだけでなく、IoT、アプリ開発、バックエンド、電子工作などの分野にも挑戦しています。 最近、エレキギターを始めました。ブログを通じて、より多くの人と交流できればと思っています。気軽に絡んでください