質問
開発プロセス中に、バックエンドAPIリクエストが非常に遅いことがわかったため、バックエンドに文句を言いました。
「APIが非常に遅いのはなぜですか?インターフェースを要求するのに10秒以上かかります。」
さらに、このような状況は時々発生します。フロントエンド開発の学生は、時々発生すると言いましたが、必須ではありません。
しかし、手術後、バックエンドの学生はインターフェースに問題がないことを発見し、郵便配達ツールとテスト環境を介してそれを試し、インターフェース要求の速度に問題がないことを発見しました。
「それはフロントエンドの問題のように感じます」?
次のように問題を整理しましょう。
- バックエンドAPIリクエストは特に遅く、散発的です。
- テスト環境では再現はありません。
- 郵便配達員のツールリクエストは再現されませんでした。
問題解決プロセス
時間はどこですか?
最初の質問、使用されるAPIに費やされる時間はどれくらいですか?
Chromeデバッガーを開きます。ネットワーク内の各インターフェイスの時間がかかることがわかります。
時間のかかるインターフェースのWaterfulにカーソルを合わせると、特定の時間のかかるインターフェースを確認できます。
時間のかかるのは、主にStalled
ブラウザがこのリクエストを発行する命令を取得してからリクエストを発行できるようになるまでの待ち時間であり、一般的にはプロキシネゴシエーションとのリリースを待つ時間であることがわかります。 DNSクエリ、TCP接続の確立などを除く再利用可能なTCP接続。
したがって、APIはブラウザから送信される命令を待機しています。上のスクリーンショットを例にとると、APIは23.84Sを待機しており、要求と応答の時間は非常に高速です(最大で数百ミリ秒、バックエンドが言ったインターフェースは遅くない)。
では、ブラウザが実行するのを待っているAPIは正確には何ですか?
リクエストをブロックしているのは何ですか?
配置した後、サーバー送信イベント(以下、SSEと呼びます)がプロジェクトで使用されていることがわかりました。WebSocketと同様に、サーバーからブラウザーに情報をプッシュします。ただし、違いはHTTPプロトコルを使用することです。
当不通过 HTTP / 2 使用时,SSE
会受到最大连接数的限制,限制为 6 次。此限制是针对每个浏览器 + 域的,因此这意味着您可以跨所有选项卡打开 6 个 SSE 连接到 www.example1.com,并打开 6 个 SSE 连接到 www.example2.com。这一点可以通过以下这个 demo 复现。
复制问题的步骤:
- 访问ssebin.btubbs.com/multi/
- 单击添加计数器6或更多次
- 尝试打开另一个标签到同一地址
结果是,第 6 次之后,SSE 请求一直无法响应,打开新的标签到同一个地址的时候,浏览器也无法访问。
效果图如下:
该问题在 Chrome 和 Firefox 中被标记为“无法解决”。
至于偶现,是因为前端开发者有时候用 Chrome 会打开了多个选项卡,每个选项卡都是同一个本地开发地址,就会导致达到 SSE
的最大连接数的限制,而它的执行时间会很长,也就会阻塞其他的请求,一致在等待 SSE
执行完。
所以解决的方法是什么?
解决方案
简单粗暴的两个方法
- 不要打开太多个选项卡。这样就不会达到它的限制数。(因为我们一个选项卡只请求一个 SSE)。
- 开发环境下,关闭该功能。
使用 HTTP / 2
使用 HTTP / 2 时,HTTP 同一时间内的最大连接数由服务器和客户端之间协商(默认为 100)
这解释了为什么我们 test 环境没有问题,因为 test 环境用的是 HTTP / 2。而在开发环境中,我们使用的是 HTTP 1.1 就会出现这个问题。
那如何在开发环境中使用 HTTP / 2 呢?
我们现在在开发环境,大部分还是使用 webpack-dev-server 起一个本地服务,快速开发应用程序。在文档中,我们找到 server 选项,允许设置服务器和配置项(默认为 'http')。
只需要加上这一行代码即可。
devServer: {
+ server: 'spdy',
port: PORT,
}
复制代码
看看效果,是成功了的。
原理使用 spdy 使用自签名证书通过 HTTP/2 提供服务。需要注意的一点是:
该配置项在 Node 15.0.0 及以上的版本会被忽略,因为 spdy 在这些版本中不会正常工作。一旦 Express 支持 Node 内建 HTTP/2,dev server 会进行迁移。
总结归纳
原本这个问题认为跟前端无关,没想到最后吃瓜吃到自己头上。提升相关技能的知识储备以及思考问题的方式,可能会方便我们定位到此类问题。
充分利用好浏览器的调试工具,对一个问题可以从多个角度出发进行思考。比如一开始,没想到本地也可以开启 HTTP / 2。后来偶然间想搜下是否有此类方案,结果还真有!
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。