摘要:服務(wù)端代碼網(wǎng)頁端代碼函數(shù)傳入請(qǐng)求的為了獲取請(qǐng)求數(shù)據(jù),將改為。捕獲三個(gè)請(qǐng)求的時(shí)間,分別為,,。對(duì)于連續(xù)的相同請(qǐng)求,會(huì)阻塞后面的請(qǐng)求,直到前面的完成。這也是為什么打開谷歌開發(fā)者控制臺(tái),請(qǐng)求沒有等待,立即執(zhí)行了。
最近在研究慢請(qǐng)求監(jiān)控的問題,寫了一個(gè)簡(jiǎn)單的測(cè)試代碼:在網(wǎng)頁端(index.html)通過fetch函數(shù)向服務(wù)端獲取數(shù)據(jù),然后打印請(qǐng)求耗時(shí)。
function requestData() { let start = new Date(); fetch("http://localhost:3000/company/basic") .then(res => { return res.json(); }) .then(res => { let span = new Date() - start; console.log("span:", span); }); } requestData();
在服務(wù)端通過setTimeout延時(shí)1500s才返回?cái)?shù)據(jù)(服務(wù)端使用ExpressJS)。
app.get("/company/basic", (req, res) => { setTimeout(function() { res.send({ hello: "Hello Fundebug!" }); }, 1500); });
不出所料,span數(shù)據(jù)都略微大于 1500。
而后,我突發(fā)奇想,假設(shè)我同時(shí)發(fā)送多個(gè)請(qǐng)求會(huì)怎么樣呢?于是有了如下代碼:
[1, 2, 3].forEach(function() { requestData(); });
結(jié)果好像也沒問題,在 Chrome 瀏覽器下面是這個(gè)效果:
接入 Fundebug 慢請(qǐng)求監(jiān)控測(cè)試于是愉快地接入 Fundebug 監(jiān)控:
并設(shè)置如果請(qǐng)求時(shí)長(zhǎng)超過 2 秒就上報(bào):
if ("fundebug" in window) { fundebug.httpTimeout = 2000; }
本以為刷新頁面,應(yīng)該不會(huì)收到報(bào)錯(cuò)。
結(jié)果,萬萬沒想到的是,F(xiàn)undebug 收到 2 個(gè)慢請(qǐng)求報(bào)錯(cuò)。
這不科學(xué)??!
點(diǎn)開錯(cuò)誤詳情,可以看到具體的報(bào)錯(cuò)信息。一個(gè)請(qǐng)求耗時(shí) 3018 毫秒,一個(gè)請(qǐng)求耗時(shí) 4525 毫秒。
也就是說,第一個(gè)請(qǐng)求沒問題,假設(shè)是 1500 毫秒。我們把三個(gè)請(qǐng)求的時(shí)間放一起看看有何規(guī)律:1500,3018,4524。他們近似成等差數(shù)列,相差 1500 毫秒。于是,我懷疑三個(gè)請(qǐng)求是一個(gè)一個(gè)阻塞式的,而不是并發(fā)的。
測(cè)試并發(fā)請(qǐng)求不同 API 的情況為了驗(yàn)證這一點(diǎn),我將測(cè)試改為請(qǐng)求三個(gè)不同的 API 接口。
服務(wù)端代碼:
app.get("/company/basic", resp); app.get("/company/basic1", resp); app.get("/company/basic2", resp); function resp(req, res) { setTimeout(function() { res.send({ hello: "Hello Fundebug!" }); }, 1500); }
網(wǎng)頁端代碼(requestData函數(shù)傳入請(qǐng)求的 URL):
[ "http://localhost:3000/company/basic", "http://localhost:3000/company/basic1", "http://localhost:3000/company/basic2" ].forEach(function(item) { requestData(item); });
為了獲取請(qǐng)求數(shù)據(jù),將httpTimeout改為 1500。
if ("fundebug" in window) { fundebug.httpTimeout = 1500; }
Fundebug 捕獲三個(gè)請(qǐng)求的時(shí)間,分別為 1526,1525,1529。
至此大體驗(yàn)證了剛剛的假設(shè):對(duì)同一個(gè) API 接口的并發(fā)請(qǐng)求會(huì)被阻塞,對(duì)不同的 API 接口并發(fā)請(qǐng)求正常執(zhí)行。
那么為什么會(huì)被阻塞呢?意圖何在?接下來慢慢給各位介紹。
背后的原因在StackOverflow上找到了答案:
Yes, this behavior is due to Chrome locking the cache and waiting to see the result of one request before requesting the same resource again. The answer is to find a way to make the requests unique.
也就是說,Chrome 特意做了這樣的設(shè)計(jì)。對(duì)于連續(xù)的相同請(qǐng)求,Chrome 會(huì)阻塞后面的請(qǐng)求,直到前面的完成。通過判斷前面的請(qǐng)求返回的 Header 里面的緩存設(shè)置來決定下一步的行動(dòng)。
我們可以做個(gè)實(shí)驗(yàn)來驗(yàn)證一下。
緩存實(shí)驗(yàn)
服務(wù)端設(shè)置緩存 2 秒
在服務(wù)端的接口返回代碼中配置緩存時(shí)間
res.setHeader("Cache-Control", "public, max-age=2");
服務(wù)端設(shè)置不緩存
res.setHeader( "Cache-Control", "private, no-cache, no-store, must-revalidate" );
Chrome 開發(fā)者面板設(shè)置Disable Cache
最后的疑問為什么打開和不打開谷歌開發(fā)者控制臺(tái),行為會(huì)不一樣了?
其實(shí)是有原因的,而且這個(gè)干擾項(xiàng)一度成功阻止了我發(fā)現(xiàn)問題的本質(zhì)。當(dāng)我們?cè)陂_發(fā)前端項(xiàng)目的時(shí)候,代碼的改動(dòng)希望能夠?qū)崟r(shí)地反應(yīng)到網(wǎng)頁上,而不是受到瀏覽器緩存的影響,但是我們發(fā)現(xiàn)往往刷新頁面的時(shí)候沒有真的去服務(wù)端獲取數(shù)據(jù),還是老的信息。于是,我們會(huì)去配置一個(gè)選項(xiàng),將Disable Cache設(shè)置為true。也就是說,在開發(fā)環(huán)境下,緩存是被禁用了的,也就不存在等待第一個(gè)請(qǐng)求返回然后判斷其 Header 里面Cache-Control設(shè)置的問題。這也是為什么打開谷歌開發(fā)者控制臺(tái),請(qǐng)求沒有等待,立即執(zhí)行了。
關(guān)于FundebugFundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應(yīng)用實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了10億+錯(cuò)誤事件,付費(fèi)客戶有陽光保險(xiǎn)、核桃編程、荔枝FM、掌門1對(duì)1、微脈、青團(tuán)社等眾多品牌企業(yè)。歡迎大家免費(fèi)試用!
版權(quán)聲明轉(zhuǎn)載時(shí)請(qǐng)注明作者 Fundebug以及本文地址:
https://blog.fundebug.com/2019/07/17/chrome-stall-multiple-same-request/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/105701.html
摘要:前端是應(yīng)用服務(wù)器處理之前的部分,前端主要包括等各種資源,針對(duì)不同的資源有不同的優(yōu)化方式。常見方法合并多個(gè)文件和文件,利用整合圖像,使用在實(shí)際的頁面嵌入圖像數(shù)據(jù),合理設(shè)置緩存等。 web前端是應(yīng)用服務(wù)器處理之前的部分,前端主要包括:HTML,CSS,javascript,image等各種資源,針對(duì)不同的資源有不同的優(yōu)化方式。 內(nèi)容優(yōu)化 (1)減少HTTP請(qǐng)求數(shù):這條策略是最重要最有效...
摘要:高性能代碼的最佳實(shí)踐前言在這篇文章中,我們將討論幾個(gè)有助于提升應(yīng)用程序性能的方法。要獲得有關(guān)應(yīng)用程序需求的最好最可靠的方法是對(duì)應(yīng)用程序執(zhí)行實(shí)際的負(fù)載測(cè)試,并在運(yùn)行時(shí)跟蹤性能指標(biāo)。 showImg(https://segmentfault.com/img/bVbtgk4?w=256&h=254); 高性能Java代碼的最佳實(shí)踐前言 在這篇文章中,我們將討論幾個(gè)有助于提升Java應(yīng)用程序性...
摘要:提高用戶訪問網(wǎng)站的響應(yīng)速度與網(wǎng)站的可用性,解決網(wǎng)絡(luò)帶寬小用戶訪問量大網(wǎng)點(diǎn)分布不均等問題。網(wǎng)站加速什么是加速網(wǎng)站加速相信大家都知道,當(dāng)一個(gè)用戶打開一個(gè)新網(wǎng)站的時(shí)候,如果網(wǎng)站打開的速度很慢的話,用戶是很難繼續(xù)瀏覽的;因此,很多網(wǎng)站運(yùn)營人會(huì)想方設(shè)法的去提升網(wǎng)站的加載速度。例如用CDN加速,能幫助一個(gè)網(wǎng)站能夠快速打開的有效和實(shí)用方法。 我們相信速度是一個(gè)成功網(wǎng)站的必備要素之一,速度不夠快,會(huì)降...
摘要:摘要阿里云主要分為離線分析和在線分析兩種功能。演講嘉賓簡(jiǎn)介勛臣,阿里云內(nèi)核團(tuán)隊(duì)技術(shù)專家,目前阿里云專家系統(tǒng)開發(fā)。通過診斷報(bào)告定位性能下降原因。 摘要:阿里云CloudDBA主要分為離線分析和在線分析兩種功能。幫助用戶節(jié)省成本,定位問題,分析原因并推薦解決方法。CloudDBA可以做到實(shí)時(shí)診斷,離線診斷和SQL優(yōu)化。并且通過MySQL的參數(shù)調(diào)優(yōu),檢測(cè)參數(shù)的不合理或者準(zhǔn)備的延遲的情況。 演...
閱讀 2019·2021-08-21 14:09
閱讀 484·2019-08-30 15:44
閱讀 2111·2019-08-29 16:32
閱讀 1374·2019-08-29 15:36
閱讀 3440·2019-08-29 12:43
閱讀 2783·2019-08-29 11:14
閱讀 434·2019-08-28 18:26
閱讀 2250·2019-08-26 13:57