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