2017-07-29 9 views
1

私はwebappを構築し、http2経由で提供しています。しかし、私がGoogle Chrome(バージョン59.0.3071.115(公式ビルド)(64ビット))の開発ツールでネットワークを分析すると、http1.1のように6つのアクティブな接続しかないので多重化が機能しないことは明らかです。残りの接続はキューに入れられます。Google Chromeはhttp2と多重化しません

これはなぜですか?または私の期待は正しくないのですか?

スクリーンショット(あなたはそのプロトコルがHTTP2で見ることができます):

Chrome's network tab showing only 6 active connections with the rest queued in spite of using http2

更新#1:

  • バックエンドがnginxの1.13上で実行されます。
  • 私はすべてのスクリプトを一度に読み込むカスタムモジュールローダーを使用しています(ループ内にasync属性のスクリプトタグを作成しています)。
  • 8行目以降ではブラウザがリソースのダウンロードを開始する要求を受け取ったが、白い部分はこのスクリプトがキューに入れられていることを示し、スロットが使用可能になったときにのみ実際のダウンロードが開始されたことを示しています線2,3および4が完了すると、7および9がロードを開始し、11,12,13および5,6,7の線についても同じことが行われる。
+1

共有できる最小限の例でこの問題を再現できますか? –

+1

@FrederikDeweerdtは返事を感謝します。私は現在の環境を示すことはできませんが、私はこの目的のために別の環境を設定します。 –

答えて

1

これはChromeのバグ、または少なくとも不必要な制限だと思います。

これは簡単にテストされます。

私は(それが異なるリソースのように見えるようにするために、クエリのparamと)同じジャバスクリプトファイルの25枚のコピーをダウンロードする簡単な例をHTMLファイル、作成された:私は、同じことをやった

<!DOCTYPE HTML> 
<html> 
<head> 
     <title>Test for Lots of JS files</title> 
     <meta name="robots" content="noindex"> 
<body> 
</body> 
     <h1>This is a test for Lots of JS files</h1> 

     <script src="/assets/js/test.js?v=01"></script> 
     <script src="/assets/js/test.js?v=02"></script> 
     <script src="/assets/js/test.js?v=03"></script> 
     <script src="/assets/js/test.js?v=04"></script> 
     <script src="/assets/js/test.js?v=05"></script> 
     <script src="/assets/js/test.js?v=06"></script> 
     <script src="/assets/js/test.js?v=07"></script> 
     <script src="/assets/js/test.js?v=08"></script> 
     <script src="/assets/js/test.js?v=09"></script> 
     <script src="/assets/js/test.js?v=10"></script> 
     <script src="/assets/js/test.js?v=11"></script> 
     <script src="/assets/js/test.js?v=12"></script> 
     <script src="/assets/js/test.js?v=13"></script> 
     <script src="/assets/js/test.js?v=14"></script> 
     <script src="/assets/js/test.js?v=15"></script> 
     <script src="/assets/js/test.js?v=16"></script> 
     <script src="/assets/js/test.js?v=17"></script> 
     <script src="/assets/js/test.js?v=18"></script> 
     <script src="/assets/js/test.js?v=19"></script> 
     <script src="/assets/js/test.js?v=20"></script> 
     <script src="/assets/js/test.js?v=21"></script> 
     <script src="/assets/js/test.js?v=22"></script> 
     <script src="/assets/js/test.js?v=23"></script> 
     <script src="/assets/js/test.js?v=24"></script> 
     <script src="/assets/js/test.js?v=25"></script> 

</html> 

を、しかし、 Javascriptを処理中に非同期属性を追加し、場合にChromeはダウンロードをブロックすることを決定した:

 <script src="/assets/js/test.js?v=01" async=""></script> 
     <script src="/assets/js/test.js?v=02" async=""></script> 
     ....etc. 

と同じ再びが、延期属性を持つ:

 <script src="/assets/js/test.js?v=01" defer=""></script> 
     <script src="/assets/js/test.js?v=02" defer=""></script> 
     ....etc. 

/assets/js/test.jsファイルが空です。したがって、ブラウザが追加したものを除き、実行の遅延や依存関係はありません。

私はいくつか興味深い結果を見ました!これはすべてChrome 60.0.3112.78または60.0.3112.101で、Apacheを使用していますが、Nginxで見たのと同じ結果になりました。

我々は次の結果を参照HTTP/2サーバーで

:すべてのスクリプトは、並列にロードされた(しかし、おそらく順序で実行される)プレインscriptタグで

を。まったく6接続制限は、HTTP/1.1の下でようがありません: Javascript with no async or defer

非同期scriptタグとスクリプトが6のグループに並列にロードされている - あなたが述べたとおりに:それらの Javascript with async

クリックすると、彼らを示しHTTP/2経由でダウンロードしました。

延期scriptタグを使用すると、スクリプトはasyncタグを使用した結果と同じになります(一度に6件のダウンロードを抑制)。

これは意味をなさない - Chromeはダウンロードをブロックしないように非同期または遅延を使用する場合のみ、Javascriptのダウンロードを制限します。

ビューポートの画像でも同じことが起こるわけではないので、多重化はChromeで動作するため、非同期モードまたは遅延モードのJavascriptでは不必要に制限されているように見えます。 HTTP/2でスクリプトをまとめてバンドルすることを検討している場合は、もはや必要のないことを多くの人がアドバイスするので、これは本当の制限です。

同じことではなく、はFirefoxでもEdgeでも発生しません。 Opera(Chromiumベースのブラウザ)で発生しますが。

これは悪いニュースです。良いニュースは、彼らがそれを修正したかもしれないということです。私がChrome Canary(62.0.3190.0)を試しても、この動作を繰り返すことはできません。しかし、WebページテストをCanary(ユーザーエージェントの文字列に62.0.3190.1を与えるので実際には同じ)にすると、となりますので、100%ではありません。

持っているので、彼らの言うことが表示されます。このためChromeチームにバグを提起:すべてのすべてでhttps://bugs.chromium.org/p/chromium/issues/detail?id=757191

を、サーバーとクライアントの両方でHTTP/2は、両側として、現時点では流動的で少し思えるんこの比較的新しいプロトコルの中から最適な使い方を得るために、実装を微調整し調整する必要があります。それでも、ChromeはGoogleがSDPY実装(HTTP/2が主に基づいている)でこれを開始して以来、Chromeがヒットしたのは驚くべきことです...

* *アップデート**

Chromeチームが復帰し、これがChromeでのHTTP/2の現在の実装の制限であることを確認しました。 HTTP/2のように多くのアセットが同時に呼び出されたときにパフォーマンスの問題が発生していたため、重要な項目(非同期/遅延やビューポートに表示されない項目を含む)をHTTP/1.1の上限6に制限しませんでした。

HTTP/2の優先順位付けは、送信後に優先順位付けの概念を持っていますが、HTTP/2の優先順位付けがここでは役に立たないように、優先順位を付けて送信する前にパフォーマンスの問題が見られました。

今後これを改善したいと考えています。

私は新しいHTTP/2環境に慣れ、ブラウザとサーバーを最適化する必要があるため、実装上の問題だと思いました。

+1

Chromeチームからのフィードバックが追加されました。 –

1

HTTP/2を使用してChromeがマルチプレックスを制限することを決定する理由は複数あります。

たとえば、画像が多数表示されているページをブラウザビューポートに表示するかどうかによって、その動作が大きく異なる場合があります。

ダウンロードしたドキュメントはスクリプトであり、スクリプトはブロックされているか、または相互に依存しているか、ブラウザがリソースをダウンロードする方法を変更することがあります。

https://http2.golang.org/gophertiles?latency=0のようなHTTP/2のオンラインの例を見ると、Chromeは画像のダウンロードを本当にうまく行います(ただし、ビューポートに表示されている場合のみ)。

したがって、あなたのケースでは、スクリプトを使用することができます。多分彼らはお互いに依存関係があり、そのためChromeは一度に6以上のものを多重化できないのです。

これは、HTTP/1.1を前提としたJavaScriptローダーの限界であり、現在はHTTP/2で廃止されていますが、私は驚くことはありません。

Chromeデベロッパーツールの[掲載結果]タブを使用して、ページの掲載結果を把握することができます。

Page Speedなどのツールを見て、ページを最適化する方法を知りたい場合もあります。

要約すると、ChromeがHTTP/2をどのように実装するかは問題ではなく、アプリケーション/スクリプト内でHTTP/2用に最適化されていないものではないと思います。

+0

返事をありがとう、しかし私はあなたのコメントは私の場合に適用されるとは思わない。元の投稿の更新#1を参照してください。また、Page Speedは意味のある結果を出しませんでした(100/100)。 –

関連する問題