Web開發須知的瀏覽器內幕 緩衝與儲存篇(2)

來源:互聯網
上載者:User

標籤:

本文禁止轉載,由UC瀏覽器內部出品。

3. HTTP Cache綜述

HTTP Cache是完全按照IETF規範實現的,最新的RFC規範地址是
https://tools.ietf.org/html/rfc7234。它的作用就是儲存可快取的響應以備重新使用,在下次請求時可減少回應時間和網路頻寬。只有GET和HEAD method會緩衝。

瀏覽器的最佳化

瀏覽器是過濾了部分沒有意義進行緩衝的回應標頭才儲存到磁碟,例如Connection(keep-alive)、www-authenticate等。這能減少耗時較多的磁碟IO時間。另外Cookie也不會儲存在HTTP Cache,而是存到專門的Cookie Storage。

新的規範允許先使用後驗證(stale-while-revalidate)https://tools.ietf.org/html/rfc5861

在隱藏模式下,不存在磁碟讀寫的HTTP Cache。
http://www.chromium.org/user-experience/incognito。
但是某些瀏覽器廠商可能做最佳化,在臨時檔案夾中讀寫,退出或重啟即刪。

容量

容量是以整體計算的,不區分Domain。

Android WebView是20MB。iOS WebView也可能是20MB(根據https://github.com/gnustep/base/blob/master/Source/NSURLCache.m,不確定GNUstep是否也是Apple的源碼)。

PC上的Chromium是以80MB為基準結合磁碟可用空間來考慮的,最大是320MB。演算法是:

// js虛擬碼if (可用空間 < 100MB)  容量 = 80%的可用空間  // < 80MBelse if (可用空間 < 800MB)  容量 = 80MBelse if (可用空間 < 2000MB)  // 約2GB  容量 = 10%的可用空間  // < 200MBelse if (可用空間 < 20000MB)  // 約20GB  容量 = 200MBelse  // >= 20000MB  容量 = Math.min(1%的可用空間, 320MB)  // 200MB <= 容量 <= 320MB

其它基於Chromium開發的瀏覽器可能會修改這個演算法,特別是行動瀏覽器會擴大那個常量值,以更高容量來提高資源複用數(嗯,不是複用率)。

淘汰

淘汰演算法是一般是LRU,但在一些情境會結合檔案大小、時間因素等做進一步最佳化。Cache的管理模組會記錄總的緩衝大小,每次建立新的緩衝時會判斷是否緩衝是否超出容量限制,滿了就會按LRU淘汰一定比例的緩衝。

瀏覽器需要對緩衝的檔案進行索引,如果這個索引損壞,瀏覽器會刪除所有的緩衝。使用者也可以通過設定介面來刪除。此外,第三方程式也會做清理。

Revalidation

使用者點擊重新整理按鈕,會強制走revalidate流程,其它的情況都按照規範來執行。

RFC規範不只是為伺服器和瀏覽器設計的,還考慮了網路中的各種節點,比如Proxy 伺服器、CDN伺服器、智能路由等。

Chromium肯定是嚴格遵守RFC規範的,但第三方瀏覽器通常會破壞這些規範來獲得一定的效能提升。比如更寬鬆的緩衝條件。

Chromium代碼參考:http_response_headers.cc : RequiresValidation

後端最佳化

後端需要在響應中添加Cache-Control來利用瀏覽器緩衝。

  • Expires不要超過一年。
  • 穩定的檔案應該加上max-age。max-age不要大於2^31,以免大於int32而變成負數。
  • Some HTTP/1.0 caches might not implement Cache-Control.對HTTP 1.0可以使用Pragma

沒有任何與到期相關的指令的話,是由client端決定是否緩衝的。Chromium有緩衝,但再次請求的時候並不會走Revalidate流程,還是會得到200 OK。

因為HTTP Cache以URL為key,所以不想用以前的緩衝,則可以更換URL,例如加不同的query、改檔案名稱(如加上MD5或版本號碼)等。URL是忽略錨點的。

要做效能最佳化的同學,可以在協議文檔裡淘金。鑒於網上也有不少文章,這裡不做整理了。

4. Cookie Storage綜述

因為Cookie是在多個要求標頭中複用資料的,所以需要從回應標頭中抽取出來另外儲存。而且Cookie有自己的生命週期管理文法,就有獨立的模組來管理。Cookie資料同時儲存在記憶體和磁碟。

容量

容量是規範裡就有建議最小值的。最新規範是RFC6265,它引用兩個比較舊的規範RFC2965和RFC2109。

其中最老的規範RFC2109的6.3.1節中就有說明:

拒絕服務的攻擊   瀏覽器應該按照host或網域名稱設定Cookie的數量和資料大小上限。Denial of Service Attacks   User agents may choose to set an upper bound on the number of cookies   to be stored from a given host or domain name or on the size of the   cookie information.  Otherwise a malicious server could attempt to   flood a user agent with many cookies, or large cookies, on successive   responses, which would force out cookies the user agent had received   from other servers.  However, the minima specified above should still   be supported.

Chromium的實現是:
- 每個Cookie的最大長度為4096 bytes。大於這個長度的Cookie將不被處理,即不會儲存。
- 每個域的最大數量是180個
- 總體的個數是3300個

這裡有各個瀏覽器的Cookie限制列表:http://browsercookielimits.squawky.net/。

記憶體緩衝

從容量可知,所有Cookie佔用的最大記憶體為3300*4K ≈ 13M。這點記憶體在手機上也是支撐得了的,所以Chromium會把硬碟上的全部Cookie資料都讀到記憶體,每次發送請求都是在記憶體中尋找,所以速度很快。在收到響應,需要建立或更新Cookie時,Chromium才會去寫硬碟。而這個寫操作是在非網路線程中完成的,避免慢速的檔案IO佔用網路線程的時間。

記憶體中的組織是以eTLD+1為key放在multimap裡。

Chromium用SQLite存放cookie。在PC上是對value加密的。在iOS不加密,因為它的沙箱機制足夠完善了,除非越獄。

Chromium把增刪改表示為操作,向資料庫髮指令,而不是全部寫一次。它是在後台線程flush。每30秒或滿512次操作就直接Flush。

參考
http://www.quantum-step.com/download/sources/mystep/Foundation/Sources/NSHTTPCookieStorage.m
Apple是用了系統的NSHTTPCookieStorage。是全寫的。

(註:本節的描述經過簡化,非真實完整的實現)

淘汰

每次建立或更新Cookie就會進行記憶體回收的判斷。有下列的規則:
1. 先淘汰到期的。即超出Max-Age指定時間。
2. 如果超出容量,則會按LRU規則(這裡的used是指accessed)淘汰掉300個Cookie。
3. 如果最近30天內有訪問過,即使超出容量也不會淘汰掉。

下面是Chromium源碼中的部分注釋供參考。

// Any cookies accessed more recently than kSafeFromGlobalPurgeDays will not// be evicted by global garbage collection, even if we have more than// kMaxCookies.  This does not affect domain garbage collection.const int CookieMonster::kSafeFromGlobalPurgeDays = 30;const size_t CookieMonster::kPurgeCookies = 300;const size_t CookieMonster::kDomainCookiesQuotaLow = 30;const size_t CookieMonster::kDomainCookiesQuotaMedium = 50;const size_t CookieMonster::kDomainCookiesQuotaHigh =    kDomainMaxCookies - kDomainPurgeCookies - kDomainCookiesQuotaLow -    kDomainCookiesQuotaMedium;
開發建議
  • 瀏覽器可能會被使用者佈建成禁用Cookie。當確實需要Cookie而發現擷取不了時,請做好一定的提示,提升使用者體驗。
  • 設好max-age,不要讓冗餘的cookie加入到要求標頭裡,可加速連網過程。
  • 因為都在記憶體,Cookie操作的時耗較少,但太大的cookie會在連網階段造成較高的延時。還是乖乖地加上Expire吧。

Web開發須知的瀏覽器內幕 緩衝與儲存篇(2)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.