本文是篇真正的隨筆 是我在寫一份前端最佳化ppt時 想到哪寫到哪 產生的一份 羅裡吧嗦的 東東...有點懶的整理 ...所以就發布到這個旮旯吧.
Ajax 最佳化
一 . 給被請求資源設定有效長遠的 Expires 的同時設定一個相對短 且合理的 max-age值
比如 對某一檔案 伺服器的回應標頭 中應該包含
Expires: Tue, 01 Jun 2030 15:43:46 GMT
Cache-Control:max-age=60
以及Last Modified頭或 ETag頭 的其中一個.
對於ie瀏覽器來說頭兩項 缺一不可 的原因在於
假如 對於某檔案 即沒有 Expires 又沒有 max-age的話 那麼 快取檔案就無 到期時間…一旦某快取檔案無到期時間 而 我們又去使用 xhr 對象對伺服器請求 該檔案. 則會導致 ie直接使用本機快取檔案給我們 而不會發起一個http 串連請求給伺服器.
我們需要
給動態檔案使用獨立的eTag演算法或lastModified 演算法 以便確定內容的及時更新 .原因在於ie瀏覽器 對於動態檔案 如 aspx php等 一樣會固執的緩衝他們 並在 xhr對象請求時 不發起http請求 此處應根據不同情況差異 選擇性 確保ie 快取檔案的Expires 時間 和max-age或乾脆禁止 ie快取檔案.
永遠不要期待ie像firefox chrome safari 等瀏覽器那樣 對於aspx php等動態檔案類型. 在預設http頭中沒有Expires 和max-age 以及Last Modified 或ETag時.自作主張的快取檔案並在xhr請求時不發起http請求.
補充:對於動態檔案 如aspx iis預設不會發送 Last Modified 或ETag頭 即 iis認為 對於動態檔案 應該總是輸出新的內容給用戶端. 所以 用戶端對於 動態檔案 也總是不會有 if Modified Since 和If None Match頭 這就導致 瀏覽器 的xhr對象 對動態檔案做請求 不可能出現304狀態代碼 也就是說 一旦發起http請求 並成功返回資料那麼只有 200 的可能 這很合理 但是ie的問題在於如上面所說 於其他瀏覽器的區別之處就 在於 預設 無epxires的情況下的處理差別. 好在 設定 Expires和 max-age 可以完善的解決這些問題 而不會產生瀏覽器差異.
只使用Expires而不使用max-age 雖然沒問題 但是 這裡需要一個預期 即 我們首先要 預期 用戶端 與伺服器端 時間相差不是很離譜 但因為這個是無法保證的 所以 我們需要 用max-age來保證到期時間的準確性.
但如果只有max-age ie瀏覽器 的xhr 對象發起的請求 仍然會有bug 他會導致 瀏覽器 直接放棄 本地cache而每次都發起請求 到伺服器 .這顯然也不是我們想要的結果
所以同時 設定max-age和 Expires 可以確保ie及 其他瀏覽器 都遵守以下原則
1
在快取檔案到期之前的xhr請求 直接去 本機快取讀 而不發起http串連請求
2
一旦快取檔案到期 才會發起請求 如果伺服器回應標頭中 有Last Modified 或 Etag頭 則 請求同時會帶有 對應的 If-Modified-Since頭或 If-None-Match 頭 以便讓伺服器判斷 是否需要返回新的 檔案內容 或者 只返回 304 頭 通知瀏覽器 本機快取可以信任 它於伺服器上的 檔案相同.
二 對於不期待先後順序的xhr請求 應放棄所謂xhr 資源管理.
即 通過一系列瀏覽器探測 以及http協議版本的 預期 以及當前 資源載入 所佔用http串連數 等等狀況 最終控制 執行個體化出的xhr對象個數 以及他們的用途…
這種行為看起來 可以避免 同時聲明過多的xhr對象 而又不滿足對應串連數 使可能過多的 xhr對象在瀏覽器隊列中 空耗這 記憶體.
但恰恰相反 我們應在每次需要xhr時 立刻建立一個 並使其發送 需要的 請求 即可 我們要做的 只是在 success 回呼函數處 即刻銷毀xhr即可
這樣做才可以 100% 有把握的 保證xhr的最大並發數而不需要我們自己去 分析 判斷 猜測.
令一個需要注意的問題是 關於 主動給xhr 添加http要求標頭內容
我的建議是
添加 Accept 頭 比如 */* 因為一旦不設定此頭 則個個瀏覽器的預設 Accept頭 都不一樣 比如firefox 就可能是一個很長的頭 浪費頻寬 . 所以同意使用 Accept 並制定為我們需要的類型 可以減少http請求中的資料量.
一個有趣的問題 在於 如果 我們沒有主動向xhr添加一個 If-Modified-Since 頭的話則無論伺服器返回碼 是不是304 xhr.status 都將是200 除非 我們明確的添加了一個包含If-Modified-Since的要求標頭 這時xhr.status== 200 才是可信任的否則 . 一旦 是從緩衝中讀取的 內容 則狀態總是200 而不是我們期望的 304 . 手動添加 If-Modified-Since 頭 為一個 過早或過晚的日期(相對該檔案在伺服器上的 Last Modified 日期) 都將導致 伺服器端校正快取檔案可靠性失效.從而伺服器端 總是發送一個 200 狀態代碼 並將最新檔案資料異同 發送過來. 所以人為添加 If-Modified-Since頭 需要謹慎 且保證其正確性. 如果我們並不需要確定 到底是從緩衝讀出資料還是 伺服器端發送的資料 則 不建議人為添加 If-Modified-Since頭.
另外 xhr請求時 永遠不要嘗試 人工發送 一個 If-None-Match 頭 給伺服器 我們一般將會得到一個 400狀態代碼即 bad Request 即使 我們的內容是一個看起來 合法的 有效ETag值.