JavaScript實(shí)現(xiàn)網(wǎng)絡(luò)測速的方法詳解
一、背景知識
在我們的日常生活中離不開網(wǎng)絡(luò),而網(wǎng)絡(luò)的快慢直接決定了用戶的產(chǎn)品使用體驗。最近我們的 WMS 系統(tǒng)在倉庫使用過程中出現(xiàn)了網(wǎng)絡(luò)卡頓導(dǎo)致的異常情況,因此需要提供一個網(wǎng)絡(luò)檢測功能,當(dāng)倉庫再遇到類似問題時可以先通過測量網(wǎng)速來排查是否網(wǎng)絡(luò)出現(xiàn)了異常。
名詞解釋:
1.ping:給目標(biāo) IP 地址發(fā)送一個 ICMP 報文,再要求對方返回一個大小相同的數(shù)據(jù)包來確定兩臺網(wǎng)絡(luò)機(jī)器是否能正常通信以及有多少時延。我們 ping 一下 github 試試:
這里的 time 指標(biāo)就是時延數(shù)值。ping 可以作為網(wǎng)絡(luò)情況的首要參考指標(biāo);
2.jitter:抖動,用來描述網(wǎng)絡(luò)的波動情況。比如每秒測量一次 ping 值,5s 后取五次測量結(jié)果的最大最小值求差,可以看出網(wǎng)絡(luò)的波動情況,差值越小代表網(wǎng)絡(luò)越穩(wěn)定;
3.bandwidth:帶寬,用來描述理論上單位時間內(nèi)網(wǎng)絡(luò)傳輸數(shù)據(jù)的最高速率,它只是一個理論上的最大值。通常我們所說的 1 兆帶寬就是 1Mb/s = 1000Kb/s = (1000/8)KB/s = 125KB/s。帶寬越大自然越好,但是受用戶計算機(jī)性能、網(wǎng)絡(luò)設(shè)備質(zhì)量、資源使用情況、網(wǎng)絡(luò)高峰期、網(wǎng)站服務(wù)能力、線路衰耗,信號衰減等多因素的影響,它并不能直接反映當(dāng)前的網(wǎng)絡(luò)環(huán)境;
4.throughput:吞吐量,用來描述單位時間內(nèi)網(wǎng)絡(luò)傳輸數(shù)據(jù)的實(shí)際速率。受多方面影響,吞吐量一般都小于真正的帶寬值;
5.上傳速度與下載速度:上傳速度就是從本地上傳一個文件的速度,相反,下載速度就是從網(wǎng)絡(luò)上下載一個文件的速度,使用迅雷等下載軟件的時候看到的那個數(shù)值就是下載速度,通常下載速度會大于上傳速度。由于下載場景較多,我們更關(guān)心下載速度數(shù)值。
在網(wǎng)絡(luò)檢測中,沒有單獨(dú)哪一個指標(biāo)可以說明問題,應(yīng)盡可能多的結(jié)合各種指標(biāo)來全面評估網(wǎng)絡(luò)情況。接下來介紹幾種測速方法。
二、Network Information API
瀏覽器為我們提供了網(wǎng)絡(luò)相關(guān)的 API ,NetworkInformation 提供了設(shè)備與網(wǎng)絡(luò)進(jìn)行通信的信息和鏈接類型變更時的有關(guān)事件,它是通過 Navigator
的 connection
屬性進(jìn)行訪問的。connection
對象有一個 downlink
屬性,返回以 Mb/s 為單位的有效帶寬,MDN 上官方解釋說該值是基于最近監(jiān)測的保持活躍連接的應(yīng)用層吞吐量,因此吞吐量的查詢并不是實(shí)時的,如果距離上一個 http 請求間隔較長,這個數(shù)值并不準(zhǔn)確。因此 downlink
值只具備有限的參考意義,且該功能還在實(shí)驗中,不同瀏覽器兼容性也較差,因此不推薦使用這種方式來檢測網(wǎng)絡(luò)情況。
補(bǔ)充一下,connection
對象還有一個 type
屬性和 onChange
方法,type
屬性返回的是當(dāng)前設(shè)備聯(lián)網(wǎng)的類型,枚舉值有如下幾種:
- bluetooth
- cellular
- ethernet
- none
- wifi
- wimax
- other
- unknown
當(dāng)聯(lián)網(wǎng)類型 type
發(fā)生改變時,會觸發(fā) change 事件,通過 onChange
回調(diào)函數(shù)能做一些事情:比如我們在播放視頻時,從 wifi 環(huán)境切換為使用流量時,可以暫停視頻并提示用戶選擇是否用流量繼續(xù)播放。
三、測量 ping 和 jitter 值
由于 JS 無法真正原生地測量 ping 值,因此需要提供一種替代方案來模擬。為了盡可能準(zhǔn)確地得到 ping 值,可以通過請求一個盡量小的資源來模擬發(fā)送 ICMP 報文,記錄發(fā)起請求到收到返回值的時間差。請求的內(nèi)容可以是網(wǎng)站的 favicon.ico ,一個空文件,甚至是一個空接口(注意需要配置跨域)。但是這些方案都依賴于圖片資源、文件以及接口的穩(wěn)定性,如果服務(wù)掛掉的話,得到的 ping 值是有問題的。接下來通過多次測量 ping 值就可以計算代表網(wǎng)絡(luò)波動情況的 jitter 值了。代碼如下:
const Dashboard = React.memo(() => { const [ping, setPing] = useState<number>(0); const [count, setCount] = useState<number>(0); const [pingList, setPingList] = useState<number[]>([]); const [jitter, setJitter] = useState<number>(0); useEffect(() => { const timer = setInterval(() => { const img = new Image(); const startTime = new Date().getTime(); // 此處選擇加載 github 的 favicon,大小為2.2kB img.src = `https://github.com/favicon.ico?d=${startTime}`; img.onload = () => { const endTime = new Date().getTime(); const delta = endTime - startTime; if ((count + 1) % 5 === 0) { const maxPing = Math.max(delta, ...pingList); const minPing = Math.min(delta, ...pingList); setJitter(maxPing - minPing); setPingList([]); } else { setPingList(lastList => [...lastList, delta]); } setCount(count + 1); setPing(delta); }; img.onerror = err => { console.log('error', err); }; }, 3000); return () => clearInterval(timer); }, [count, pingList]); return ( <PageContainer className={styles.dashboard}> <div className="text-center"> <h1>歡迎使用 倉儲管理系統(tǒng)</h1> <h1>PING: {ping}ms</h1> <h1>抖動: {jitter}ms</h1> </div> </PageContainer> ); });
以上代碼是采用測量加載 github favicon 的時間來模擬 ping 值的,圖片大小為 2.2kB,可以獲得更準(zhǔn)確的 ping 值。注意在 img.src 的 url 最后拼接上一個時間戳,保證每次都會重新發(fā)起請求,而不是使用第一次加載的圖片緩存。動圖效果如下,3 秒測量一次 ping 值,拿到最近 5 次 ping 值后計算一次抖動值:
四、測量下載速度
下載速度測量與上述 ping 值測量原理相同,只不過需要將下載的對象換成一個更大的資源,通過計算單位時間內(nèi)下載資源的大小來測量下載速度。像下載軟件迅雷,我們常看到的那個數(shù)字就是下載速度。另外迅雷還有一個很好的功能可以選擇全速下載模式和不影響正常上網(wǎng)的模式,因為下載時可能會擠占帶寬影響用戶正常瀏覽網(wǎng)頁。其中的原理就是迅雷在下載的時候在不停做 ping,如果發(fā)現(xiàn) ping 的延遲增加,就限制下載速度,如果 ping 還高,就繼續(xù)降到 ping 回歸期望值。
五、總結(jié)
如果用戶感到訪問的網(wǎng)站反應(yīng)過慢,有可能是各種原因?qū)е碌?,大致可以遵循以下流程進(jìn)行簡單排查:
1.打開百度等常用網(wǎng)站,查看是否仍然存在網(wǎng)速慢的情況。如果其他網(wǎng)站訪問正常,可以確定是當(dāng)前站點(diǎn)的問題,需要繼續(xù)排查:
可能是 DNS 解析問題,可以在終端輸入 nslookup + 當(dāng)前網(wǎng)站域名來檢查:
如果 DNS 解析正常,那么有可能是網(wǎng)站訪問量過高等原因,具體情況還需排查;
2.如果其他網(wǎng)站速度也比較慢,可以檢查是否在下載文件,如果在下載文件也是會占用帶寬的,可以選擇下載軟件的限制帶寬功能來確保正常上網(wǎng)網(wǎng)速;
3.如果確實(shí)網(wǎng)絡(luò)有問題,那就需要運(yùn)營商維修人員來排查了,有可能是各種原因:用戶計算機(jī)性能、網(wǎng)絡(luò)設(shè)備質(zhì)量、網(wǎng)絡(luò)高峰期、線路衰耗、信號衰減等等。
注意事項:
1.不要在頁面加載的初始階段就去測速,否則會影響 LCP 時間,建議等組件 mounted 后再測速;
2.根據(jù)業(yè)務(wù)場景合理設(shè)計測速方案,比如根據(jù)測速時機(jī)的不同分為兩種方案:
- 實(shí)時檢測:設(shè)置時間間隔來實(shí)時檢測網(wǎng)絡(luò)狀況,優(yōu)點(diǎn)是當(dāng)網(wǎng)絡(luò)出現(xiàn)異常時可以提前告警,缺點(diǎn)是會浪費(fèi)網(wǎng)絡(luò)請求;
- 人為觸發(fā)檢測:用戶察覺網(wǎng)絡(luò)出現(xiàn)異常時,再手動觸發(fā)檢測優(yōu)點(diǎn)是節(jié)省網(wǎng)絡(luò)資源,缺點(diǎn)是缺乏預(yù)警性;
3.若使用加載圖片的方式測量,圖片 url 應(yīng)拼接時間戳,防止請求時直接使用緩存。
到此這篇關(guān)于JavaScript實(shí)現(xiàn)網(wǎng)絡(luò)測速的方法詳解的文章就介紹到這了,更多相關(guān)JavaScript網(wǎng)絡(luò)測速內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
dedecms頁面如何獲取會員狀態(tài)的實(shí)例代碼
下面小編就為大家?guī)硪黄猟edecms頁面如何獲取會員狀態(tài)的實(shí)例代碼。一起跟隨小編過來看看吧,希望對大家有所幫助。2016-03-03JavaScript ECMA-262-3 深入解析(一):執(zhí)行上下文實(shí)例分析
這篇文章主要介紹了JavaScript ECMA-262-3 執(zhí)行上下文,結(jié)合實(shí)例形式詳細(xì)分析JavaScript ECMA執(zhí)行上下文相關(guān)概念、原理與操作注意事項,需要的朋友可以參考下2020-04-04JavaScript蒙板(model)功能的簡單實(shí)現(xiàn)代碼
本文給大家介紹JavaScript蒙板(model)功能的簡單實(shí)現(xiàn)代碼,創(chuàng)建一個蒙板, 設(shè)置蒙板的堆疊順序保證能將其它元素蓋住,感興趣的朋友可以參考下實(shí)現(xiàn)代碼2016-08-08JavaScript實(shí)現(xiàn)區(qū)塊鏈
很多朋友都聽說過比特幣和以太幣這樣的加密貨幣,但是只有極少數(shù)人懂得隱藏在它們背后的技術(shù),接下來通過本文給大家介紹用JavaScript來創(chuàng)建一個簡單的區(qū)塊鏈來演示它們的內(nèi)部究竟是如何工作的,感興趣的朋友一起看看吧2018-03-03使用JavaScript實(shí)現(xiàn)文本收起展開(省略)功能
省略號,作為一種常見的文本處理方式,在很多情況下都十分常見,特別是當(dāng)我們需要在省略號后面添加額外文字時,本文為大家介紹了使用JavaScript實(shí)現(xiàn)文本收起展開功能的相關(guān)方法,希望對大家有所幫助2024-04-04微信小程序?qū)W習(xí)筆記之函數(shù)定義、頁面渲染圖文詳解
這篇文章主要介紹了微信小程序?qū)W習(xí)筆記之函數(shù)定義、頁面渲染,結(jié)合實(shí)例形式較為詳細(xì)的分析了微信小程序中函數(shù)的定義、生命周期、模板調(diào)用、樣式控制等操作技巧,并配合圖文形式進(jìn)行了詳細(xì)說明,需要的朋友可以參考下2019-03-03通過隱藏iframe實(shí)現(xiàn)無刷新上傳文件操作
本文給大家介紹iframe無刷新上傳文件,通過一個隱藏的iframe來處理上傳操作我采用的是ReactJS,amazeui,nodejs1.html target指向iframe的name,就是把上傳后的操作交給iframe來處理2016-03-03