- 最近、Node.jsツールをRust、Zig、Goなどのより高速な言語で書き直そうとする傾向には懸念があり、その客観的な懸念点を整理する
[性能]
- JavaScriptツールを高速化する余地は、まだ十分に掘り尽くされていないと考えている
- ESLint、Tailwindなどには、簡単に改善できる部分が多く存在する
- ブラウザにおいてJavaScriptは、ほとんどのワークロードに対して「十分に速い」
- ではCLIツールでは、なぜJavaScriptを捨てようとしているのだろうか?
大規模な書き直し
- 長い間、JavaScriptツールのエコシステムは「動くこと」に重点を置いてきた
- 今ではAPIの大半が安定し、誰もが「同じものを、より速く」求める状況になっている
- 性能を考慮して新たに書かれ、APIもすでに定まっているため開発時間を節約できることから、新しいツールのほうが速くなり得る
- AからBへ書き直すと速度向上が起こるため、BのほうがAより速いと主張しやすい
- しかし、書き直しそのものが速さの理由である可能性もある(2回目のほうが知見が増え、性能にもより注意を払うため)
バイトコードとJIT
- ブラウザでは当然のように、バイトコードキャッシュとJIT(Just-In-Timeコンパイラ)の恩恵を受けている
- JavaScriptが正しくキャッシュされれば、ブラウザはソースコードをバイトコードにパースしてコンパイルする必要がない
- 頻繁に実行される関数は、機械語へさらに最適化される(JIT)
- Node.jsスクリプトでは、バイトコードキャッシュの恩恵をまったく受けられない
- しかし今ではNodeでもコンパイルキャッシュを使えるようになった(
NODE_COMPILE_CACHE環境変数を設定)
- JITは関数を何度も実行して「ホット」にならないと効果が出ないため、一回限りのスクリプトでは恩恵を受けにくい
- Pinaforeでは、JavaScriptベースのblurhashライブラリをRust(Wasm)版に置き換えようとしたが、5回目の反復に達すると性能差が消えた
- PorfforのようなツールでNodeスクリプトをAOTコンパイルすることも検討できる
- Wasmを使うと、純粋なネイティブツールと比べて性能低下がある
[貢献のしやすさとデバッグの容易さ]
- 「すべてをネイティブで書き直す」運動に対する主な懐疑点はここにある
- JavaScriptは、緩やかな型付け、学びやすさ、ブラウザ対応などによって大衆的な言語になっている
- 長い間、JavaScriptエコシステムではライブラリ作者も利用者もJavaScriptを使ってきた
- これは貢献のハードルを下げる助けになる
- しかしJavaScriptライブラリの作者が別の言語を使うと、この利点は崩れてしまう
- また、JavaScript依存関係はローカルで簡単に修正できる(
node_modulesを直接編集)
- 一方、ネイティブ言語で書かれている場合は、ソースコードを直接チェックアウトしてコンパイルしなければならない
- JavaScriptライブラリをデバッグするときは、使い慣れたブラウザ開発者ツールやNode.jsデバッガを使える
- Wasmでもデバッグが不可能というわけではないが、別の技術セットが必要になる
[結論]
- JavaScriptエコシステム向けに新世代のツールが登場しているのは良いことだ
- 既存ツールの多くは非常に遅く、競争の恩恵を受ける余地があるように見える
- しかし、JavaScript自体が本質的に遅いとか、改善の余地がないとは考えていない
- Chromium開発者ツールの最近の改善を見ると、まだ道のりは長いと感じる
- RustやZigの開発者だけの専有領域になる世界には懸念がある
- 平均的なJavaScript開発者がビルドツールのバグに直面したとき、無力感を覚える可能性がある
- 若いWeb開発者に学習性無力感を教え込むことになりかねない
- これは未知の道であり、意図しない結果を招く可能性がある
- 一方で、より低リスクでほぼ同じ結果を得られる別の道もある
- しかし現在の流れには、減速する気配が見られない
GN⁺の意見
- RustやZigなどへの書き直しが常に最善とは限らない。compile cacheなど、JavaScript側にもまだ改善の余地がありそう
- 初心者開発者にセグフォルトのような複雑な問題へ向き合わせることが本当に良いのかは疑問で、むしろ無力感だけを教えることになるかもしれない
- 長年JavaScriptで築いてきたエコシステムの利点(ライブラリ間で自由に修正できること、慣れ親しんだデバッグ環境など)を犠牲にしてまで速度を上げるのが本当に良い方向なのか、考える必要がある
- 既存のJavaScriptライブラリでも改善の取り組みは続けられるべきだろう。JavaScriptの可能性はまだ掘り尽くされていない
- たとえ大勢は覆せないとしても、この方向性についてはコミュニティ全体での真剣な議論と検討がさらに必要に思える
15件のコメント
個人商店と大型店では、運営方式が少し違うこともありますよね。変えること自体に批判的な姿勢を取るよりも、このような現象の意味を考えてみるほうが健全な考え方だと思います。
好みや流行に乗って変えるようにも見えるかもしれませんが、企業は普通そんなふうに意思決定をしないじゃないですか
PythonやJavaScript自体が遅いのか? と言われると、そうとも言い切れないですが
よく使われるPythonやJavaScript製のツールが遅いのか? については、Yesだと思います。
低消費電力の機器を何台か使っているのですが、本当に腹が立つほど遅いツールが多いです..
Pythonコミュニティの側でも、ほぼまったく同じ手の話が繰り返されています。
JavaScriptはJavaScriptで書かれているわけではありませんが、ほとんどのJavaScript開発者はその点を気にしていません。"初心者開発者"や"若いWeb開発者"にとって、JavaScriptがJavaScriptで書かれていないことは問題ではないのに、JavaScript開発ツールがJavaScriptで書かれていないのは問題だというのは、あまり筋の通った話ではありません。むしろ、そういうことを気にする開発者は、どちらのグループにもごく少数しか存在しないでしょう。
十分な最適化を施せばほぼ同じ速度を出せるという点を否定しないとしても、本当にそれだけの価値があるのでしょうか?
単に、かつては開発ツールをC++ではなくJavaScriptで書くほうが経済的だった時代から、JavaScriptで書くよりRustで書くほうが経済的な時代への転換が訪れただけです。
流れを押し戻す方法は、より多くのコストをかけて「JavaScriptで最適化しよう」運動を展開することではなく、より少ない開発コストでも効率的なJavaScriptツールを開発できるようにすることです。(似たようなことを言っているように見えるかもしれませんが、どこに努力を注ぐかが違います)
同感です。経済性は、ツール開発者ではなくツール利用者を中心に再定義すべきだと思います。
これまでの経済性は、ツール利用者よりもツール開発者を重視した指標だったのではないかと思います。ツール利用者が経験しなければならない非効率さや性能上の問題は、優先順位の中で比較的後回しにされてきた印象です。個人的には uv や vite を便利に使っていますし、可能であれば pip や create-react-app のようなツールは避けたいですね。
CLIツールはランタイムなしで動作できるべきだと思うので、なかなか同意しづらいですね。
WASMの単独実行ファイルを作れるのではと言われても、本文でも述べられているように性能低下があるでしょうし。
JavaでCLIを書くのが一般的ではないのと同じで、JavaScriptも同様だと思います。
筆者は、SPA と JavaScript ツール開発の両方で JavaScript が使われているため、それ以外に必要な周辺スキルも同じだと勘違いしているように見えます。JavaScript ツールには、システムプログラミングやコンパイラ分野のスキルが必要だと思います。
言語が同じでも、実行環境はブラウザと NodeJS で異なり、そのギャップを越えられる人だけが JavaScript ツールに貢献できるはずです。実行環境が違うのだから、別のエコシステムと見なすべきではないでしょうか。
これも同じく、SPA 開発と JavaScript ツール開発の境界を越えられる人の数を過大評価している点だと思います。フロントエンド開発者にシステムプログラミングに準ずる知識を求めるのは無理があります。ツールの利用者は、表面的なエラーメッセージや現象しか理解できないのではないでしょうか。言語さえ分かれば解決する問題ではないと思います。
ツールとライブラリを混同して話しているようですね。ライブラリについてはある程度共感できますが、ツールについてはどうでしょうか..
他の言語の開発者たちもツールはネイティブで書かれているのに慣れているはずですが。
個人的には、ツールでもライブラリでもJavaScriptで書かれていれば、JavaScriptに慣れた開発者がそれらをデバッグし、必要であれば貢献できます。ところがRustに書き直されてしまうと、オープンソースへの貢献はRust開発者にしかできなくなってしまいます。JavaScript開発者の母数はRustと比べて圧倒的に大きいため、オープンソースのエコシステムでは、ツールであれライブラリであれJavaScriptで書かれているほうが有利な場合がある、ということです。
JavaScript はブラウザと NodeJS によって実行環境が断片化されており、そのため言語ユーザー数の単純比較は論拠として限界があると考えています。バックエンドの Spring 開発者と JDK 開発者、React/Angular/Vue 開発者と JavaScript ツール開発者では関心事と立場が異なり、消費者と生産者の関係です
JavaScript ツールの性能と使い勝手の改善を目指すのであれば、手段である実装言語を変えることも選択肢になり得ると個人的には思います
私は、開発ツールの消費者と生産者を明確に分けるのは難しいと思います。会社の規模が大きくなるにつれて、ツールチェーンに対して独自のカスタマイズや追加プラグインを、自分たちが望むルールに合わせてカスタマイズしたり実装したりすることが多く、この場合は同じ言語を使うこと自体が大きな利点になると思います。
また、ツールの利用者がツール自体の改善や実装に関心を持ち、自然に貢献するようになるケースも多いです。
ツールチェーンのカスタマイズに関心を持ったり、その作業を担ったりする人は、消費者の役割を超えて、プロシューマーないし生産者の役割を果たしていると思います。プラグインの場合は、生産者と消費者の間にあるプラグイン規約の中で動いていると考えています。その状況において、同じ言語を使うことが、別個の設定ファイル形式や拡張ポイントを提供することよりも、技術的にもコミュニケーションコストの面でも役立つという点には、私も同意します。
ただし、JavaScriptツールの性能問題、あるいは NodeJS の JIT 遅延の問題が、消費者の意思決定の範囲内にあるとは思いません。そうしたアーキテクチャや動作仕様を作った主体は、ツールの生産者とランタイム開発者たちだからです
JavaScript の裾野が広いからといって、コンパイラ/トランスパイラのコードベースに貢献できる開発者が増えるとは限らないのではないかと思います。ライブラリやフレームワークと、基盤ツールはまったく別の領域だと考えています。
しかし、書き直しそのものが高速化の理由かもしれない -> 振り返ってみると、これは本当にその通りですね……
非常に選択的であるからこそ、この方の言葉には共感します。
ただ、別の次元では、JS以外にも多様な解決策が存在することは技術的進歩の観点から非常に重要な要素なので、その反対の状況についても尊重されるべきだと思います!
Hacker Newsの意見
JavaScriptは本質的に遅いという意見がある。多くのエンジニアが高速化に取り組んできたが、それでも静的型付け言語より遅い。大規模なプログラムでは、型が明確な言語のほうが適している
JavaScriptは学びやすいわけではなく、複雑なプロトタイプと型システムを持っている。TypeScriptがそれを補っているが、それでも複雑である
言語を変えるだけでも性能は大きく向上しうる。既存システムをJSとPHPからGoに置き換えたとき、8〜10倍の性能向上を経験した
並列処理の重要性が見過ごされている。Rustは並列コードを書くのに適しているが、JSは並列コードを書くのに適していない
JavaScriptは現在ではJavaに近い速度を持ち、C++より2〜4倍遅い。性能を高めるには、居心地のよい領域から踏み出す必要がある
Rust、Zig、Goのプログラムは、ソースコードを確認してコンパイルするのが容易である。新しい言語を学ぶことは、問題解決のしかたにも影響を与える
JavaScriptツールの性能を高める余地は、まだすべて使い果たされたわけではないと考えている。ただし、より良い基盤の上に構築するほうが効率的である
RspackはRustで書かれたWebpack互換の再実装であり、性能が5〜10倍向上している。Webpackを容易に置き換えられる
JavaScriptの依存関係はローカルで修正しやすいが、Rustはバグが少ないため修正の必要も少ない。Rustは習得が難しいものの、それによって他の言語でもより良いプログラマになれる