1. kkeethのエンジニア雑談チャンネル
  2. No.201 朝活「続・Speeding up..
2023-03-26 27:24

No.201 朝活「続・Speeding up the JavaScript ecosystem - eslint」をダラダラ読む回

はい.第201回は引き続き


Speeding up the JavaScript ecosystem - eslint

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-3/


を読みました💁

いやぁ,一貫して学びだらけの記事でした…こんなエンジニアになりたいものだ←

良記事ですのでぜひ皆さんも読んでみてくださいー!


ではでは(=゚ω゚)ノ



See Privacy Policy at https://art19.com/privacy and California Privacy Notice at https://art19.com/privacy#do-not-sell-my-info.

00:03
はい、3月20日月曜日ですね。 遅刻は朝9時10分になりました。
本日も東京だと結構寒くてですね。 ちょっと心もがいしようと思ってたのに、急にまた
あの冬服を出してきました。はい、おはようございます。 ゆめみのきーすかとくわはらです。
ではでは本日も朝活を始めていきたいと思います。 昨日に続きましてですね、今日もタイトルを読みます
Speeding up the JavaScript ecosystem-eslintの記事を 読んでいこうと思っています。
昨日ですね、eslintを使っているプロジェクトで、 なんかどう、臨床のパフォーマンスが悪いなというところで、
その辺に、なんでそんなに遅いのというのをちょっといろいろ 考察したり解説をしているという方もいらっしゃって、
そのブログを読んでたんですけれど、 なんかeslintってやっぱりドキュメンテーション周りの
そのコメントのところを読むのが読み込みだって解析に結構時間を 送っているとかだったりとか、
あとは初期化のところですね、の処理で結構時間を 買ったりとかですけど、その中でなんかやっぱフォーブを
使ってたんですけど、フォーブやっぱ遅いよねってなっているので、 フォーブじゃなくて普通に
従来のフォーブですね。 let i イコールゼロで、 i はレング図より小さくて i プラスプラスみたいな
っていうところですね。手続き的に書いていくのが 一番いいんじゃないのっていう話ですね。
なんか内部的にはですね、ゲットパスってメソッドを使ってて、 そのゲットパスメソッドの中の
create four of イテレーションヘルパーっていうメソッドが ビルド後に結構出力されるらしいんですけど、その出力された
結果のメソッドが結構重いと。でそれに必要なくないというところで、 フォーブを使ってやってみたんですけど、そうする方が全然
早いというところですね。 実になんか400ミリ秒まで抑え込めばあれだと。
だけどフォーブじゃなくて従来のそのレッド i イコールゼロの手続きに変えた方が
さらに200ミリ秒早くなったということで、こっちの方が良くないかっていうところですね。
まあそれについて一応本体の方にもちゃんとプロリクを出したということですね。 すごいですねと思いました。あとは
なんか文字列のところでスプリットしてなんかわちゃわちゃっていうのを、そのゲットパスの内部処理的なことを
やってるんですけど、スプリットせずに渡された引数のところからのパフォーマンス改善のところを
やられてましたね。中で使っているESクエリだったりとかそのゲットパスっていうメソッド自体が
なんでそんな遅いのっていうところの解析がされているので、皆さんもぜひこの記事読んでみてください。
すごく面白いというかかなりテクニカルで突っ込んだ内容ですので、見ていただけると幸いです。
あとESLintのパフォーマンス改善がちょっと前に行われたんですけど、それはこういうところに
あったなんていうことでよくわかると思いますので。 今後自分たちもフロントエンドを開発するときにこの辺をちゃんと見ていかなきゃ
いけないというか、この辺まで突っ込んでみていけると自分たちの設計力も上がるんだろうなというところでした。
はい、というわけで今日はその続きですね。一旦そのプルリクを出したよっていうところまでを読んだので、
今日はその続きから読んでいきたいとおもいます。 続きですけどベイリングアウトアーリーというところですね。
入っていきたいとおもいます。はい、戻りますね。これは確かに少しレールから外れたような気がする例になります。
正しくマッチングしないときにデバッグしなければならないような人間にはなりたくありません。
03:01
これがカスタムドメイン特定言語に対する私の主な不満になります。
通常ツールのサポートは全くありません。代わりにJavaScriptの世界にいれば適切なデバッグ化を使っていつでもどのステップでも値を検査することができます。
先ほどのモジュレースセレクターの例は少し極端にはなりますけど、セレクターの大半はこのような形をしています。
このような形というのはCSSのセレクターですね。バイナリーエクスプレッションとかバリアブルディレクション、デクラレーションみたいな感じの
セレクターをしています。大半はこんな感じの一文字一言で書いてあるところですけど、たまーにさっきみたいな
超大なセレクターも出てくるということですね。大半はこれだけになります。
セレクターのほとんどは現在のASTノードが特定のタイプであるかどうかを知りたいだけです。それ以上のことは特にありません。
そのためセレクターエンジン全体は必要ないんです。もしそのための高速パスを導入してセレクターエンジンを完全に
バイパスしてみたらどうでしょうかと。セレクターエンジンのバイパスをしてみたらどうなるんですか確かに。
というのでこの秘書の方は実際にやってみました。クラスノードイベントジェネレーターみたいなメソッドを作っておいて、その中で
バーっといろいろやってるわけですね。はい、if、isタイプっていうところでnewsetでまあそのいろんなセレクターのところを
ダーッと配列で持っておいていった。applyセレクターでそのノードとセレクターですね。
今対象のノードと見てみたいセレクターってところをメソッドで渡してあげて、それをマッチするかどっかっていうのはその中でやってるやつですね。
eslintの、多分これ独自メソッドですね確か。esqueryのメソッドの中にmatchesっていうのがあるのでそれを使ってみてやるとどうでしょう。
というのでまあいわゆるバイパスをしてみたらどうなるんでしょうかっていうのを見てみたんですけど、
セレクターエンジンってのはすでにショートカットサーキットしているので、文字列化されたセレクターが普通の
JavaScript関数としてセレクターとどう違うのかというのに興味がわきました。
直感的に単純なJavaScriptの条件として書かれたセレクターの方がエンジンに最適化するのが簡単だなというふうに思いましたよと。
ここは単純に思っただけなんですけどで、実際じゃあどれぐらいパフォーマンス変わったのかというところが次に続くっぽいですね。
続きましてセレクターの最高ですね。rethinking selectorsって書いてますね。
セレクターエンジンっていうのはブラウザーのCSSのように言語の壁を越えてトラバーサルコマンドっていうのを渡す必要がある場合に非常に便利になりますと。
はぁ、ちょっとすでにもう分かってないぞ俺。不勉強呪いますが。すいません。
セレクターエンジンっていうのは常にセレクターを解析して何をすべきかというのを分解し、解析されたものを実行するためのロジックをその場で構築する必要があるからになりますと。
セレクターエンジンは常にセレクターを解析して何をすべきか分解して、
解析されたものを実行するためのロジックをその場で構築する必要があります。
あ、そうなんや。ロジック自体もその場で構築してるんですね。
しかし、ESLint内部では言語の壁を越えることはありません。私たちはJavaScriptの世界に留まっているのです。
ですから、クエリ命令をセレクターに変換し、それを再び実行できるように解析することによってパフォーマンス的に何かを得られるわけではありません。
そりゃそうだよね。
むしろ、セレクターの解析と実行にリンティング時間全体の約25%を費やしています。
06:03
あ、そんなことやってるんですね。
はぁはぁ。で、新しいアップデッチがやっぱり必要だったよということでした。
で、私はちょっとひらめきました。
セレクターとは概念的な記述であり、その記述が持つ基準に基づいて要素を検索するようなものです。
それはツリーのルックアップであったりとか、配列のようなフラットなデータ構造であったりします。
考えてみれば、標準的なArray.prototype.filterメソッドの呼び出しのコールバック関数もセレクターになります。
あー、コールバック関数もセレクターか。
まあでも構造としてはそうですよね。
配列のようなフラットなデータ構造であったりするのは、それはその通りだと思ってますし、単純なセレクターの記述ですよね、概念的には。
で、アイテム、過去Arrayですね。
配列のコレクションから値を選択して、気になる値だけをピックアップしていることになります。
で、ES Queryですね。やっているメソッド、ES Queryというメソッドですけど、そこでやっていることはこれと全く同じことをやっています。
たくさんのオブジェクト、ASTノードの中からある条件に合致するものを選んでいるわけです。
これがセレクターになります。
では、セレクターの解析ロジックを避けて、代わりに普通のJavaScriptの関数を使ってみたらどうでしょうかということですね。
ES QueryとかESLintの中でやっているごちゃごちゃっていうASTノードでやるのではなくて、単純にJavaScriptの中だけでやってしまうとどうなんでしょうかというところで、
この筆者の方はES Queryセレクターみたいなところを変数で1回作っておいて、その中に文字列、リテラル展開をしていて、その中にセレクターを1個パーッと書いてしまっているわけですね。
はいはい。いくつかのセレクターを書いておいて、それをファンクションにかけていくんですね。
JSセレクターっていう関数を作っておいて、その中にノードを渡してあげるわけですね。
で、そのノードに書けてあげる感じです。今言ったそのES Queryセレクターっていう変数に入れたものと、そのノードのタイプっていうところをずっと凸合し合わせていって、それどうなのっていうのを見てみないと。
はい。ものすごく手続き的ではありますし、直感的ですね。見ればわかるみたいなメソッドになってますけど、まぁわかりやすいですね。
綺麗かどうかっていうのは別として、単純にここからタイプをバーっととにかく引っ張っていって、凸合していくとどうなるかっていうことをやってるわけですね。
いやーこれはまあどシンプルでありますけどすごくわかりやすいですし、要はセレクターって何やってるかっていうと、要はオブジェクトの中から対象のものをピックアップしているというだけにすぎないということですね。
で、その条件とかもこちらで渡してあげてやったらいいと。なのでそれは別にASTのノードの中でやるわけではなくて、単純にJSだけでやってしまえば早いんじゃないのっていうのをこの方はやられていると。
はい。愚直にやったってところですね。で、戻してみました。では実際この作った関数っていうのを試してみましょうと。
僕の音読だとわかりづらいので皆さんの方で直接ソースコードを見ていただくといいと思います。
で、この2つのアプローチの時間数を測定するためにいくつかのベンチマークをかけました。少ししてデータが画面に飛び込んできましたよというところで、
WATTはES Queryで、ES QueryとES Query Optimizedですね。あとはPlain JavaScript Functionというところですね。
で、やってみました。で、foo.substringですね。何かオブジェクト.文字列.substringなので、文字列の中からいくつかの文字数を取ってくるんですけど、
09:08
今回は1,2っていうのは1,2になっているので、あれですね。インデックス1のところから2文字を取ってこいよっていうことをやってますと。
で、単位としてはopsuseqでやってるってことですね。で、やってみましたと。そうするとそのそれぞれの結果ですね。
ES QueryとES Query OptimizedとPlain JavaScript Functionでの実行結果を見てみますと、
JavaScriptの純粋な関数が文字列ベースのものを簡単に凌駕しているようです。圧倒的に優れてますねってことでした。
ES Queryを高速化するためにこれだけ時間をかけても、JavaScriptのバリアントには到底及びません。
セレクターが位置せずエンジンが早めに救済するようなケースでは、プレーンな関数よりも30倍も遅かったのですと。
この小さな実験によってセレクターエンジンにかなり時間を費やしているという私の仮説が裏付けられましたと。
実にその時間ですけど、ops.var.secですけども、ES Queryだと大体42万ぐらいですね。
で、これms、違うsecですよね。で、ops.だから1秒あたりに何回Opsなので実行できるかというのが42万だったんですけど、
ES Query Optimizedの方だと303万まで上がりますと。すごいパフォーマンス課税しますね。
この時点で10倍とは言わないですけど8倍ぐらい上がってるんですけど、そこからさらにプレーンなJavaScriptにしてみますと、
6696万まで行くと。実に30倍近くいってるということですね。
パフォーマンスが改善したということですね。いや、これはすごいですね。
ここについても実はプルリク出したのが気になりますけど、続き読んでいきましょうか。
続いて、サードパーティーのプラグインやプリセットが与える影響についてのところを見ていきたいと思います。
ES Lintのセットアップからプロファイルを見てみますと、より多くの最適化の余地がありますが、
私は正しい最適化に時間を費やしているのかという疑問を思うようになりましたと。
単純に今までの結果でいくと、いろいろパフォーマンス改善しているのは分かったし、
何が原因だったのか、何が遅くなっているのかというところは、
証明はとりあえず裏付けはできましたけど、果たしてこれが正しい最適化なのかというところにちょっと疑問を持ちましたと。
これまでES Lint自身のリンティングセットアップで見てきたような問題というのは、
他のリンティングセットアップでも発生したのでしょうか。
ES Lintの強みの一つというのは、サードパーティーのリントルールを柔軟にサポートすることになりますと。
確かにそうですよね。これが除かれると、それはそれで本来ES Lintを使う理由がちょっと薄れていっちゃうので、
それは本末先頭ということですよね。
振り返ってみると、私が携わったプロジェクトの多くにはいくつかのカスタムリントルールというのがありまして、
さらに2から5個のES Lintプラグインだったりとかプリセットがインストールされていました。
しかしもっと重要なのは、パーサーを完全に入れ替えたことです。
NPMのダウンロード統計を見ますと、ES Lintの組み込みパーサーを置き換える傾向があるということがわかります。
パッケージで見ますと、ES LintとNPMのダウンロードですね。
ウィークリーのダウンロードと見ると、大体31,718ダウンロードが行われているようですね。
これドットで表示されているから3万とかじゃなくて、もっともっとでかいですね。
12:01
3,171万ですね。いや、全然でかかったですね。
すごい。ES Lintって毎週3,000万とかダウンロードされるんですか。へー。
続いて、TypeScript ES Lintパーサーですね。
AddTypeScript-ES Lintスラッシュパーサーですけどね、正式には。
こちらの方のウィークリーのダウンロードを見ますと、2,319万ドット行ってますね。はぁ。
続いて、AddBabelスラッシュES Lint-パーサーですね。
Babelの方のパーサーを見ると、こちら650,000ですね。
どれもこれもでも結局すごいダウンロード数を週間で稼いでますね。
いやー、さすがES Lintって感じですけど。
はい、まあちょっとそのパーサーを見ていきましたが、
この数字を真剣に言うのであれば、ES Lintの全ユーザーのうち、
ビルトインパーサーを使用しているのは実は8%でございますということですね。はい。
また、TypeScriptがES Lintの全ユーザーの73%を占め、
いかに指揮多数な存在になっているかっていうのを示しています。
で、BabelパーサーのユーザーがTypeScriptにも使っているかどうかというデータはちょっとありませんと。
私の推測ではそのようなユーザーは一部で、
TypeScriptユーザーの総数は実際にはもっと多いんじゃないかなというふうに思ったりしていますと。
まあそうでしょうね。普通にES Lint使ってますけど、
だいたい皆さんもTypeScriptで書くのが前提なので、
TypeScript ES Lintパーサーを使う人のほとんどなんじゃないかなと思ってます。
BabelのES Lintパーサーを使う人って結構少ないんじゃないかというところですね。
実際にあのNPMの数字だけ見ても19%になってますしっていうところですね。
ただまあ体感としてはもっと多いんじゃないかというのはこの秘書の方のご意見ですと。
では続いていきましょう。またプロファイルの画像に戻りますね。
前回と同様プロファイルには様々な領域がありまして、どこに時間がかかっているかというのがわかります。
TypeScriptのフォーマットからES Lintが理解するフォーマットへの変換に結構時間かかっているよってことがまあプロファイリングからもわかります。
そして古い友人であるES LintインポートプラグインとES Lintプラグインノートっていうのを見つけ、
モジュール解決ロジックの束っていうのをキックオフしているようですね。
しかしここで興味深いのは、セレクターエンジンのオーバーヘッドが表示されないことになります。
ApplySelector関数が呼び出される例はありますけど、全体から見ればほとんど時間を使ってないと。
ApplySelectorはほとんど時間を使ってないんですね。
もちろんTypeScriptの単純にパーシングとモジュールリソリューションルールとかですね。
あとはTSのASDコンバージョンとコンフィグファイルローディングってところで結構時間を送っているよってことですね。
サードパーティーのプラグインで常にポップアップして実行にかなりの時間を要するのは
ES LintプラグインインポートとES Lintプラグインノートの2つがあるようです。
これらのプラグインがアクティブになると、プロファイリングデータにそれぞれが如実に現れてきます。
この2つのプラグインっていうのは多くのモジュールを解決しようとするため、
ファイルシステムトラフィックが大きくなってしまいますが、その結果をキャッシュすることがありません。
この点についてはシリーズの第2回で詳しく説明しましたので、これ以上詳しく説明することはありません。
ちょっと先の話でやりますけど、この記事読み終わったら、シリーズ3回に分かれてるんですけど、
15:02
シリーズ3から読み始めてしまったので逆流してしまいますけど、次回以降はシリーズ2を読んでいこうと思います。
そこで語られてますよということでした。
続いて、全てのASDノードを変換しましょうというセクションに入ります。
まずは冒頭で行われるタイプスクリフトの変換から始めます。
私たちのツールは私たちが提供したコードを解析して、
アブストラクトシンタックスツール、いわゆるASTですね、と呼ばれるデータ構造に変換をします。
ASTは私たちの全てのツールが動作するためのビルディングブロックだと考えることができます。
ASTは次のような情報を提供します。
例えばここで変数を宣言して、名前とこの値を持っていますとか、ここでif分を宣言してこの条件でこのブロックをガードしてますよなどなどっていうところが、
ASTのところで書かれています。
一応この記事内のソースコードではJSに変換されたASTというのが示されています。
単純にオブジェクトになってますけど、こんな感じになりますよというのが示されています。
ちょっと音読するとわかりづらいので、やっぱり皆さんの方で見ていただくといいと思います。
私たちのツールがどのようにコードを解析するかは、ASTエクスプローラーのページで確認することもできます。
このページを訪れて様々なコードスニーペットで遊んでみることを強くお勧めします。
私たちのツールのASTフォーマットがどれほど似ているか、あるいはしばしば異なっているかとよく理解することができます。
これ確かに面白いですよね。
実際僕もたまにしかやってこないですけど、久しぶりにちょっとこれ使ってみようと思います。
ASTエクスプローラーのページですね。
なんか、Javascriptだけを今までずっと書いてきたんですけど、その中身的なところとか変換するとき、
公文記を作るんですけど、抽象公文記を。
こんな感じなんだねっていうのを見てみると割と面白いですよ。
いろんなものが見えてきたりするし、中身を実際に覗いている感じがするので、
この辺の視点とか観点を持ってコードを書くのはなかなか面白いなと思ってますので、参考に見てみてください。
はい、戻ります。
しかしですね、ESLintの場合、これにはちょっと問題があるようです。
私たちは選んだパーサーに関係なくルールが機能するようにしたいんですよと。
ノーコンソールルールっていうのを有効にするとき、全てのパーサーで動作するようにしたいのであって、
各ルールをパーサーごとに書き換える必要というのはもちろんありません。
本質的に必要なのは、私たち全員が合意できる共有ASTフォーマットになります。
そしてこれこそがESLintが行うことになります。
ESLintは全てのASTノードがES3の仕様に合致することを期待しています。
ES3の仕様というのは、各ASTノードがどのように見えるべきかを規定したものになりますと。
この仕様はかなり古くからあるもので、多くのJavaScriptツールにはこの仕様から始まっていますと。
バベルもそれをベースにしていますが、その後いくつかの逸脱が文章化されていますということです。
しかしそこにタイプスクリプトを使うときの問題の確信というのも実は含まれていますと。
タイプスクリプトのASTフォーマットは型そのものを表すノードも考慮する必要があるため、非常に異なっていますと。
またタイプスクリプト自身が使いやすいように内部で異なる表現をしている構成要素というのもあります。
つまりタイプスクリプトのASTノードの一つ一つをESLintが理解できる形式に変換する必要もありますと。
18:00
ここがいわゆるオーバーヘッドですね。
この変換にはやっぱり時間がかかります。
このプロファイルでは全体の時間の22%を実は示していますと。
TSのASTノードの理解をするための変換に22%使っている、5分の1を使っているんですね。
結構使いますね。
さらにファイル数とかコンポーネント数が増えれば増えるほどそれは比例して大きくなっていくので、これはちょっとバカにならないですね。
時間がかかる理由はトラバーサルだけではなくて、変換のために新しいオブジェクトを割り当てているからですよと。
基本的にメモリ上には異なるAST形式のコピーが2つあると。
めっちゃメモリ食いますね。そんなことをやってるんだ。
当初の実装のままやってるからっていうのがあって、それ結構名残ってしまってるんでしょうね。
もしかしてバベルのパーサーの方が早いのかなというのがちょっと気になったので見てみました。
TypeScript ESLintパーサーをバベル ESLintパーサーと入れ替えてみたらどうなるでしょうかと見てみました。
グラフを見てみますと、TypeScript ESLintパーサーはパースタイム2.1秒かかってますけど、
バベル ESLintパーサープラスバベルプリセットTypeScriptの2つのセットにしてみますと、
まさかのパースタイム0.6秒というので、全然早いですね。
TypeScript ESLintパーサーが実は遅いということがここで分かるんですね。
てことは、そうすることでかなりの時間を節約できるというのが分かりました。
興味深いことに、この変更によって設定のロード時間も実はかなり短縮されましたと。
コンフィグロード時間の改善はおそらくバベルのパーサーがより少ないファイルに分散されたことに起因するものでしょうと言っています。
ああ、なるほどね。バベルってそんなことやったんですね。
コンフィグファイルは結構分割したんですね。
はい、てことで300ちょっとしかミリ秒は変わってないですけど、まあそれでもバカにならないですね。
コンフィグだけを読むのにそんなにかかるのかっていうから差が出ますからね。
beforeはだって合計すると結局850ミリ秒コンフィグを読み込むだけに時間がかかってますからね。
そう考えると結構バカにならないですよね。
戻ります。
バベルパーサーっていうのはこの記事を書いている時点、確かに今年の2月だった気がしますね。
はい、明らかに高速になりますけど型を意識したリントをサポートしないってことに注意をしてください。
単純に速いだけは速いけど、タイプスクリプトみたいな型の方はサポートしないってことは注意ですね。
これはタイプスクリプトensリントパーサーだけの機能になります。
これはfor in loopで繰り返しを処理する変数っていうのが実は配列ではなくてオブジェクトであるかどうかを検出できる
no for in arrayルールのようなルールの可能性を開くものになります。
というわけでタイプスクリプトensリントパーサーを使い続けた方が実態としては良いかもしれません。
もしensリントがタイプスクリプトの構文を理解でき、かつリントが少し速くなることを期待しているのであればバベルのパーサーに変更するのも良い選択肢ですと。
であれば、TS使うかどうかは結構パフォーマンスが結構あるですね。
密接に関わってくるですけど、まあやっぱりみんなタイプスクリプトを使うでしょうからまあまあバベルの方に戻ることはないんだろうなと思いますね。
だからそのensリントの今後の進化に期待をしましょうというところでした。
最後、ボーナスラウンドになりますと、理想的なリンダーはどのようなものなのかというところが最後に語られるそうですね。
21:03
この頃ensリントの将来についてパフォーマンスを最優先とする議論に遭遇しました。
特にセッションという概念を導入することで現在のようにファイル単位ではなくて、
完全なプログラムのリンチを可能にすることについて素晴らしいアイディアが提示されていますと。
ensリントユーザーの少なくとも73%がタイプスクリプトコードのリントにensリントを使っていることを考えると、
ASTの変換をより少なくするような緊密な統合というパフォーマンスに関して大きな意味を持つでしょうと。
またラブストっていうのがあるんですね。
っていうのの移植についての話もあって、現在のラブスト、ラブスト?ラストじゃなくて本文を見てみますと、
ラブストっていうワードがですね、
いや、ないぞ。
ディープウェルが変わったことを言っている。
ラブストみたいなことはないけど、多分ラストだと思うんですけど。
There is also some character about the last...
やっぱラストだな。はい、ラストって言ってますね。
なんでラブストってなったんだ?
またラストの移植についての話もあって、
現在のラストベースのJavaScript用リンターがどの程度早いのかというのに興味をそそられましたと。
いまいろんなツールとかCLIとかもそうですけど、ラストの置き換えが結構進んでますよね。
これがensリントにもやっぱり話が続いてきて、そっちが完全に入ってくるのであれば結構いい話だと思いますね。
結構僕もそれで早くなるんだと興味をそそられますね。
で戻ります。タイプスクリプトの文法の大部分を解析することができて、
ある程度量産体制が整っていると思われるのはやっぱりRSリントだけであると言ってます。
はい、やっぱRSリントってのがあるんですね。
RSリントの他に純粋なJavaScriptのシンプルなリンターはどんなものがあるかというのをちょっと考えてみました。
セレクターエンジンを持たず一定のAST変換を必要とせず、
コードをパースして様々なルールをチェックするのに必要なものだけであるような、
はいはい、純粋にソースコードだけの方に注目をしたようなパーサーがあるのかなみたいなところですね。
はい、そこで私はバベルのパーサーを非常にシンプルなAPIでラップし、
ASTツールを歩くためのカスタムトラバーサルロジックとちょっと追加してみましたと。
バベル独自のトラバーサル関数というのは繰り返しのために大量のアロケーションというのが発生し、
ジェネレーターをベースに構築されているため、ジェネレーターを使わない場合に比べて若干遅くなるため、
ちょっと選ばなかったということですね。
また数年前にESビルドのパーサーをJavaScriptに移植したことにも由来します。
何年もかけて自分で書いたいくつかのカスタムJavaScript、もしくはTypeScriptパーサーでも試してみました。
とはいえ、ビートのリポジトリですね、144ファイルですけど、
の上でこれをすべて実行した結果の数値は以下のとおりですと。
見てみますと、ESLintの方でいくとだいたい時間は5.85秒かかっていました。
カスタムリンターのJavaScriptですね。やると0.52秒。
最後ですね、RSLintですね。ラストベースのRSLintですると0.45秒になりました。
やっぱり全然早いですね。
標準のESLintよりもカスタムリンターの方がそれは早いよねってことでした。
この数字からも今回の実験では、JavaScriptだけでラストの性能にかなり近づけるってことも逆に言うと確信していますということですね。
24:03
最後に結論を語って終わりにしたいと思います。
コンクルージョンですね。
はい、結論。全体としてですね、ESLintプロジェクトというのは非常に明るい未来が実は待っています。
逆に言うと改善の余地はいくらでもあるということですね。
OSSプロジェクトの中では最も成功しているプロジェクトの一つであり、十分な資金を得る秘訣とも得られました。
ESLintをより早くするためのいくつかの事柄を検討しましたけど、ここではカバーしきれませんでした。
もっともっとたくさんの領域を検討する必要もありまして、余地もありますよと。
ESLintの未来みたいな記事が別のリンクに貼られていますね。
フューチャーオブインセリントディスカッションというリンクの記事があります。
こちらのディスカッションではESLintをより良く、より早くするための素晴らしいアイディアがたくさん詰まっています。
厄介なのは一度に全ての問題を解決しようとしないことになります。
私の経験ではそれはしばしば失敗する運命になります。
一から書き直すのもほぼほぼ同じことになります。
その代わり、現在のコードベースは完全に良い出発点であり、もっと素晴らしいものに作り変える準備ができているとも言えます。
外部の人間から見ると、いくつかの重要な決断を迫られることがあります。
例えば、文字列ベースのセレクターをサポートし続けることは、この時点で意味があるのかというのは疑問です。
もしそうなのであれば、ESLintチームには、ESクエリのメンテナンスを引き受け、必要な愛を与える能力があるのでしょうか。
また、NPMのダウンロード数を見ると、ESLintユーザーの73%がTypeScriptユーザーであることから、TypeScriptのネイティブサポートについてはどうでしょうか。
そうなるにせよ、私は彼らのチームと彼らのビジョンを実行する能力に強い自信を持っています。
ESLint未来に期待をしています。
というので、この記事は締められておりました。
はい、いかがだったでしょうか。
かなりテクニカルかつ技術的にも突っ込んだ記事で、
あ、で、めちゃくちゃ勉強になりましたね。
あと、技術記事でこういう風に書くんだなっていう一つの素晴らしいベンチマークじゃないけど、良い例だと思っているので、
はい、また皆様改めて読んでみてください。
そして、あれですね、これを読んで興味ある人はESLintの中身ですね、ソースコードを見てみてください。
僕もちょっと軽く読んだことがあるんですけど、かなり設計の勉強になります。
ESLint自体はTypeScriptで実は書かれていないんですよね。
これはもうやっぱり歴史が長くあって、JavaScriptだけで書かれているんですけど、
JSDocがすごく細かく書いてあったりとか、設計に関してかなり参考になるので、
はい、コードリーディングでお勧めするライブラリとして、僕はESLintをあげてもいいなと思っているので、
実際にソースコード自体も読んでみてください。
はい、というところで、今日の朝方は終了したいと思います。
次回は冒頭じゃないですね、途中で言った通りですけど、
この記事自体がタイトーにありまして、
Speed up the JavaScript Ecosystemという記事なんですけど、
これ、パート3なんですよね。
シリーズ3つに渡られていて、そのうちの3つ目からちょっと読んでしまったので、
ちょっと逆流にしますけど、明日はパート2、モジュールリソリューションですね。
モジュール解決のところの記事を読んでいこうかなと思っていますので、
興味ある人はまた見てください。
同じように、結構突っ込んだ、すごくテクニカルな記事だと思われるので、
こんな感じでゆるーく読んでいこうと思います。
では、今日はですね、
27:00
デゲパンさんとプテラノさんですね。
ご参加いただきありがとうございました。
明日もゆるーく読んでいきますので、興味があれば参加してみてください。
じゃあ、また今日から月曜日ですね。1週間頑張っていけたらと思いますし、
もう3月も終わるんですね。
ということで、4月から新入社員が入っている方もいると思いますので、
しっかり3月、締めに向かって頑張っていけたらなと思います。
では、終了したいと思います。お疲れ様でした。
27:24

コメント

スクロール