197

ブラウザー (IE および Firefox) は、ページが更新されるたびに、リンクされた JavaScript ファイルを解析しますか?

ファイルをキャッシュできるので、毎回ダウンロードしようとはしないと思いますが、各ページは本質的に分離しているため、古いコードを破棄して再解析することを期待しています。

これは完全に理解できますが、非効率的ですが、最新のブラウザはサイト内の解析ステップを回避するほど賢いかどうか疑問に思っています. サイトが ExtJS や jQuery などの JavaScript ライブラリを使用している場合を考えています。

4

6 に答える 6

345

これらは私が掘り起こすことができた詳細です。JavaScript は通常、解釈されて VM 上で実行されると考えられていますが、これは、ソースを直接マシン コードにコンパイルする傾向がある最新のインタープリターには当てはまりません (IE を除く)。


クローム:V8エンジン

V8 にはコンパイル キャッシュがあります。これは、最大 5 つのガベージ コレクションのソースのハッシュを使用して、コンパイルされた JavaScript を格納します。これは、ソース コードの 2 つの同一部分が、それらがどのようにインクルードされたかに関係なく、メモリ内のキャッシュ エントリを共有することを意味します。このキャッシュは、ページがリロードされてもクリアされません。

ソース


更新 - 2015 年 3 月 19 日

Chrome チームは、JavaScript のストリーミングとキャッシングの新しい技術に関する詳細を発表しました。

  1. スクリプト ストリーミング

スクリプト ストリーミングは、JavaScript ファイルの解析を最適化します。[...]

バージョン 41 以降、Chrome はダウンロードが開始されるとすぐに別のスレッドで非同期スクリプトと遅延スクリプトを解析します。これは、ダウンロードが完了してからわずか数ミリ秒で解析が完了し、ページの読み込みが 10% 速くなることを意味します。

  1. コードキャッシング

通常、V8 エンジンは訪問のたびにページの JavaScript をコンパイルし、プロセッサが理解できる命令に変換します。コンパイルされたコードは、コンパイル時のマシンの状態とコンテキストに大きく依存するため、ユーザーがページから移動すると、このコンパイルされたコードは破棄されます。

Chrome 42 では、コンパイルされたコードのローカル コピーを保存する高度な手法が導入されているため、ユーザーがページに戻ったときにダウンロード、解析、コンパイルの手順をすべてスキップできます。これにより、すべてのページ読み込みで、Chrome はコンパイル時間を約 40% 回避し、モバイル デバイスの貴重なバッテリーを節約できます。


Opera : カラカンエンジン

実際には、これは、ソース コードが最近コンパイルされた他のプログラムのソース コードと同一であるスクリプト プログラムをコンパイルしようとするときはいつでも、コンパイラからの以前の出力を再利用し、コンパイル手順を完全にスキップすることを意味します。このキャッシュは、ニュース サービスのさまざまなニュース記事など、同じサイトからページを次々とロードする典型的なブラウジング シナリオでは非常に効果的です。これは、各ページが同じスクリプト ライブラリをロードすることが多く、場合によっては非常に大きなスクリプト ライブラリをロードするためです。

したがって、JavaScript はページのリロード後にキャッシュされるため、同じスクリプトに対する 2 つのリクエストが再コンパイルされることはありません。

ソース


Firefox : SpiderMonkey エンジン

SpiderMonkey はNanojit、JIT コンパイラをネイティブ バックエンドとして使用します。マシンコードをコンパイルするプロセスは、ここで見ることができます。つまり、スクリプトがロードされると再コンパイルされるように見えます。ただし、の内部を詳しく見てみるNanojitと、コンパイルを追跡するために使用される上位レベルの monitorjstracerが、コンパイル中に 3 つの段階を経て遷移し、次のようなメリットがあることがわかりNanojitます。

トレース モニタの初期状態は監視です。これは、spidermonkey がバイトコードを解釈していることを意味します。Spidermonkey が逆方向ジャンプ バイトコードを解釈するたびに、モニターは、ジャンプ先のプログラム カウンター (PC) 値がジャンプされた回数を記録します。この数は、PC のヒット数と呼ばれます。特定の PC のヒット カウントがしきい値に達すると、ターゲットはホットと見なされます。

モニターは、ターゲット PC がホットであると判断すると、フラグメントのハッシュテーブルを調べて、そのターゲット PC のネイティブ コードを保持するフラグメントがあるかどうかを確認します。そのようなフラグメントが見つかった場合、実行モードに移行します。それ以外の場合は、記録モードに移行します。

これはhot、コードのフラグメントの場合、ネイティブ コードがキャッシュされることを意味します。つまり、再コンパイルする必要はありません。これらのハッシュ化されたネイティブ セクションがページの更新間で保持されるかどうかは明らかではありません。しかし、私は彼らがそうだと思います。誰かがこれを裏付ける証拠を見つけることができれば、素晴らしい.

編集: Mozilla 開発者の Boris Zbarsky が、Gecko はコンパイル済みスクリプトをまだキャッシュしていないと述べていることが指摘されています。この SO answerから取得。


Safari : JavaScriptCore/SquirelFish エンジン

この実装に対する最良の答えは、すでに他の誰かによって与えられていると思います。

現在、バイトコード (またはネイティブ コード) をキャッシュしていません。これは
私たちが検討したオプションですが、現在、コード生成は
JS 実行時間のわずかな部分 (< 2%) であるため
、現時点では追求していません。

これは、Safari の主任開発者であるMaciej Stachowiakによって書かれました。ですから、それが真実であると考えることができると思います。

他の情報は見つかりませんでしたが、最新のSquirrelFish Extremeエンジンの速度向上について詳しくはこちらをご覧ください。冒険したい場合は、こちらでソース コードを参照してください。


IE : チャクラエンジン

このフィールドには、IE9 の JavaScript エンジン (チャクラ) に関する現在の情報はありません。何か知ってる人いたらコメントください。

これはまったく非公式ですが、IE の古いエンジンの実装について、Eric Lippert ( JScript の MS 開発者) はブログの返信で次のように述べています

JScript Classic は、JScript Classic プログラムを実行する前に、コードを完全に構文チェックし、完全な解析ツリーを生成し、バイトコードを生成するという意味で、コンパイルされた言語のように機能します。次に、バイトコード インタープリターを介してバイトコードを実行します。その意味で、JScript は Java と同じように「コンパイル」されています。違いは、JScript では独自のバイトコードを保持したり調べたりすることができないことです。また、バイトコードは JVM バイトコードよりもはるかに高レベルです。JScript クラシック バイトコード言語は解析ツリーの線形化にすぎませんが、JVM バイトコードは明らかに低レベルのスタック マシンで動作するように意図されています。

これは、バイトコードがまったく保持されないことを示しているため、バイトコードはキャッシュされません。

于 2012-02-13T13:27:47.700 に答える
12

他の回答で述べたように、Operaはそれを行います。(ソース

Firefox (SpiderMonkey エンジン) はバイトコードをキャッシュしません。ソース

WebKit (Safari、Konqueror) はバイトコードをキャッシュしません。ソース

IE[6/7/8] または V8 (Chrome) についてはわかりません。IE は何らかのキャッシュを行う可能性がありますが、V8 は行わない可能性があります。IE はクローズド ソースなのでよくわかりませんが、V8 では「コンパイル済み」コードをキャッシュしても意味がないかもしれません。これらのコードはマシン コードに直接コンパイルされるからです。

于 2012-02-13T10:34:08.043 に答える
3

私の知る限り、解析されたJavaScriptをキャッシュするのはOperaだけです。ここの「キャッシュされたコンパイル済みプログラム」のセクションを参照してください

于 2012-02-12T18:40:13.620 に答える
2

Google Dartが「スナップショット」を介してこの問題に明示的に取り組むことは何の価値もありません。目標は、事前に解析されたバージョンのコードをロードすることにより、初期化とロード時間を高速化することです。

InfoQには良い記事があります@http ://www.infoq.com/articles/google-dart

于 2012-02-20T19:26:32.643 に答える
0

「いつもではない」が正解だと思います。私が理解していることから、ブラウザーとサーバーの両方が、キャッシュされるものを決定する役割を果たします。毎回ファイルをリロードする必要がある場合は、Apache 内から構成できるはずです (たとえば)。もちろん、ユーザーのブラウザーがその設定を無視するように構成されている可能性はあると思いますが、それはおそらくありそうにありません。

したがって、ほとんどの実際のケースでは、JavaScript ファイル自体はキャッシュされますが、ページが読み込まれるたびに動的に再解釈されると思います。

于 2009-07-08T08:59:06.927 に答える
0

ブラウザは間違いなくキャッシュを利用しますが、そうです、ブラウザはページが更新されるたびに JavaScript を解析します。ページがブラウザーによって読み込まれるたびに、1.コンテンツ ツリーと 2.レンダー ツリーの 2 つのツリーが作成されるためです。

このレンダー ツリーは、dom 要素の視覚的なレイアウトに関する情報で構成されます。そのため、ページが読み込まれるたびに、javascript が解析され、javascript による動的な変更により、dom 要素の配置、要素の表示/非表示、要素の追加/削除などにより、ブラウザーはレンダー ツリーを再作成します。しかし、FF や chrome などの最新のブラウザでは、少し異なる方法で処理されます。これらにはインクリメンタル レンダリングの概念があるため、上記のように js による動的な変更がある場合は常に、それらの要素のみがレンダリングされ、再度再描画されます。

于 2012-02-13T10:23:20.880 に答える