這幾天分享一下我看《高性能 JavaScript》的學(xué)習(xí)筆記,希望能對(duì)大家有所幫助。
請(qǐng)求數(shù)據(jù)
一共 5 種從服務(wù)器請(qǐng)求數(shù)據(jù)的方式:
- XMLHttpRequest (XHR)
- 動(dòng)態(tài)腳本注入
- iframe
- Comet
- Multipart XHR
其中 iframe 和 Comet 只有在特殊情況下會(huì)被使用。
XHR
XHR 是最最常用的數(shù)據(jù)請(qǐng)求工具了。它不止有 get 方法,還有 post、put、delete 這些方法。像 Axios 這類數(shù)據(jù)請(qǐng)求庫就是 XHR 的封裝。
動(dòng)態(tài)注入腳本
動(dòng)態(tài)注入腳本其實(shí)就是在 DOM 中添加指定 src 的 <script> 標(biāo)簽。
var scriptElement = document.createElement('script')
scriptElement.src = 'http://whale.ke.com/getList?name="123"&id=888'
document.getElementByTagName('head')[0].appendChild(scriptElement)
Multipart XHR
這種方案其實(shí)也是基于 XHR 的:
- 客戶端使用 XHR 發(fā)起請(qǐng)求
- 服務(wù)器端響應(yīng)多條數(shù)據(jù)的合成。
- 客戶端收到響應(yīng)后拆分?jǐn)?shù)據(jù)、解析數(shù)據(jù)。
- 由于這種合成數(shù)據(jù)一般很大,我們可以使用輪詢現(xiàn)有響應(yīng)數(shù)據(jù)流來逐步獲取數(shù)據(jù)。
發(fā)送數(shù)據(jù)
一共兩種發(fā)送數(shù)據(jù)的方式:
- XHR
- 信標(biāo)
XHR
上面我們提到了 XHR 能夠發(fā)送各類 http 請(qǐng)求,所以給服務(wù)器發(fā)送數(shù)據(jù)必然沒有問題。無論是 GET 還是 POST 都可以做到傳輸數(shù)據(jù)到服務(wù)器端。
但是 URL 是有長度限制的,在處理類似表單這類大量數(shù)據(jù)的提交時(shí),最好還是用 POST 方法。
信標(biāo)
信標(biāo)的創(chuàng)建方法(類似于動(dòng)態(tài)腳本注入):
- 創(chuàng)建 Image 對(duì)象
- 為 Image 對(duì)象 src 定義 URL
var url = "/status_tracker.php"
var params = [
"step=2",
"time=1243879"
]
(new Image()).src = url + "?" + params.join('&')
這樣就可以向服務(wù)器端發(fā)送 URL 拼接出的數(shù)據(jù)了。同樣的,由于 URL 長度限制,無法傳輸大量數(shù)據(jù)。
優(yōu)點(diǎn):它是給服務(wù)器回傳消息最有效的方式。性能消耗很小,且服務(wù)端錯(cuò)誤不會(huì)影響客戶端運(yùn)行。
缺點(diǎn):有 URL 長度限制,返回的信息很少。
那么提交數(shù)據(jù)的方式怎么選呢?
- 如果要提交大量數(shù)據(jù),建議用 XHR
- 如果只是要發(fā)送簡(jiǎn)單數(shù)據(jù)到服務(wù)器端,用信標(biāo)。
數(shù)據(jù)格式
常用的數(shù)據(jù)格式有以下幾種:
- XML —— 笨重而完善的數(shù)據(jù)格式,兼容性很好,性能不佳。
- JSON —— 性能表現(xiàn)最好的數(shù)據(jù)格式
- JSON-P —— 動(dòng)態(tài)注入的 JSON 腳本,解析快、能跨域、但不安全。
- HTML —— 特定場(chǎng)景下的數(shù)據(jù)格式
- 自定義格式 —— 自己約定的數(shù)據(jù)格式,性能好,但是需要約定解析方法。
總的來說,對(duì)于一般情況 JSON 是表現(xiàn)最好的數(shù)據(jù)格式。如果數(shù)據(jù)集很大并且對(duì)解析時(shí)間有要求,可以使用以下兩種方案之一:
- JSON-P:使用動(dòng)態(tài)腳本注入技術(shù)注入,通過執(zhí)行 JavaScript 而非解析字符串的方式來獲取數(shù)據(jù)。它解析速度極快、還可以跨域進(jìn)行,但是不安全。
- 使用字符分隔的自定義格式,利用動(dòng)態(tài)腳本注入或者 XHR 獲取自定義格式數(shù)據(jù)后,通過
split()方法解析自定義字符串。這種方法速度快、數(shù)據(jù)文件小。
Ajax 性能優(yōu)化
- 緩存數(shù)據(jù),最快的請(qǐng)求就是沒有請(qǐng)求。
- 設(shè)置 HTTP 頭部信息
- 本地?cái)?shù)據(jù)存儲(chǔ)
- 注意使用 Ajax 類庫會(huì)有一些局限,如不能訪問 readyState 所以不能實(shí)現(xiàn) MXHR。
小結(jié)
整體看下來,動(dòng)態(tài)腳本注入來加載數(shù)據(jù)也是不錯(cuò)的數(shù)據(jù)獲取方式。而 XHR + JSON 是現(xiàn)階段最流行的數(shù)據(jù)傳輸方式。在性能上也表現(xiàn)不錯(cuò)。
更多 Ajax 的優(yōu)化,還需要好好學(xué)習(xí) HTTP 相關(guān)知識(shí),如設(shè)置頭部信息、設(shè)置緩存、過期時(shí)間、http2 等知識(shí)點(diǎn)。