在看Spring中HttpServlet的Service方法時,對於GET請求,代碼邏輯以下:html
if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince; try { ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); } catch (IllegalArgumentException iae) { // Invalid date header - proceed as if none was set ifModifiedSince = -1; } if (ifModifiedSince < (lastModified / 1000 * 1000)) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } }
其中涉及的關鍵信息是修改時間,這就涉及到瀏覽器數據緩存問題。如下對個緩存機制進行簡單總結,可用於請求的優化。(本文中的圖都摘自其餘文章)前端
當瀏覽器GET請求的時候,若是有If-Modified-Since,則會與當前服務器上相關資源最後一次修改時間進行對比,若是相同則返回304(資源可訪問,但沒修改),不然加載最新數據,瀏覽器再緩存起來。這樣減小網絡數據傳輸和服務器壓力。gulp
根據修改時間判斷文件是否被修改,若是一個網頁被頻繁更新,但實際內容並無更新,依然會對服務器形成壓力。引入了ETags和If-None-Match,其不一樣於Last-Modified和If-Modified-Since取決於修改時間,能夠依賴其餘屬性,如資源的MD5等。當資源被更新,但實際內容沒有更新,則會比較修改時間和ETags,若是ETags沒變,則不更新數據資源。但查閱源碼戴發現,目前底層實現上實現的是弱Etags,其由文本長度和修改時間組成,資源被更新後,ETags依然會更新。在AbstractResource中,代碼以下:瀏覽器
@Override public final String getETag() { if (weakETag == null) { synchronized (this) { if (weakETag == null) { long contentLength = getContentLength(); long lastModified = getLastModified(); if ((contentLength >= 0) || (lastModified >= 0)) { weakETag = "W/\"" + contentLength + "-" + lastModified + "\""; } } } } return weakETag; }
添加Expires頭能有效的利用瀏覽器的緩存能力來改善頁面的性能,能在後續的頁面中有效避免不少沒必要要的Http請求,WEB服務器使用Expires頭來告訴Web客戶端它可使用一個組件的當前副本,直到指定的時間爲止。例如:Expires:Thu,15 Apr 2010 20:00:00 GMT; 他告訴瀏覽器緩存有效性持續到2010年4月15日爲止,在這個時間以內相同的請求使用緩存,這個時間以外使用http請求。Expires有一個很是大的缺陷,它使用一個固定的時間,要求服務器與客戶端的時鐘保持嚴格的同步,而且這一天到來後,服務器還得從新設定新的時間。緩存
HTTP1.1引入了Cathe-Control,它使用max-age指定組件被緩存多久(時間相對請求的時間),從請求開始在max-age時間內瀏覽器使用緩存,以外的使用請求,這樣就能夠消除Expires的限制。但有個缺點就是,用戶不能第一時間拿到最新修改的文件。請求過程以下:性能優化
另外,gulp 給靜態資源文件添加hash(md5)後綴防止緩存無效,能獲取最新文件(這個須要進一步研究)服務器
參考:網絡
HTTP的請求頭標籤 If-Modified-Since less
If-Modified-Since和If-None-Match前端性能
http://www.360doc.com/content/17/0721/17/41344223_673116604.shtml