小程序圖片緩存策略(不改代碼更換OSS圖片)

昨天,後端給我提了一個問題:他更換了CDN上的圖片,但是他打開小程序來看,還是舊圖片,他嘗試過刪除小程序,重新進,還是舊圖片。

我第一反應是:“你有沒有清CDN緩存?“

他說:”我在阿里雲CDN控制檯刷新緩存了,都兩三天了,還是舊圖片。”(後來我看過刷緩存記錄,一天前剛刷的,他誇張了。。。)

我說:“那不應該呀,CDN刷新緩存,5分鐘就生效了。”

當即拿出我的手機,進小程序看了一下,是新的圖片。

他趕緊拿出他的手機給我看,果然,不管試多少次,都是舊圖片。

我說:”你這個圖片是文件名沒改,請求地址沒變,被客戶端緩存了。但是這個沒關係,你這個圖片基本上不會換,這次換圖,在我手機上已經驗證了是沒問題的,並且圖片所在的模塊是新增的,目前還沒發佈,用戶沒有訪問記錄,他們手機上沒有舊圖的緩存,發佈後,用戶手機上都會看到新圖片,你手機上的舊圖只是測試的時候訪問過,就被緩存了。“

但是,他不同意,說:“萬一後面又要換圖了,那怎麼辦?”

雖然他說的萬一概率很小,但是不怕一萬就怕萬一。我只好跟他說:”那行,我處理下“

很簡單嘛,改文件名就好了。但是他這些圖片名稱都是按商品類目名稱批量生成的,而且如果改文件名,他要改代碼,我也要改代碼。

那就不改文件名,在圖片地址後面加查詢字符串嘛,哪張圖片變了,就把它地址後面的查詢字符串改一下,比如?v=1?v=2,這樣他就不用改代碼了,但是前端還是要改代碼,每次圖片變了,我得改小程序裏引用這張圖片地址後面的查詢字符串,這還要重新發布。

這個方法太笨了,直接在圖片地址後面生成時間戳不就好了,如:${url}?ts=${new Date().getTime()}。但是這樣圖片每次都會重新請求,性能會產生問題。

那爲什麼圖片會被緩存那麼久了?怎樣才能讓緩存失效了?

打開控制檯看下請求,如下:

 

從控制檯裏可以看到,圖片響應是from disk cache,說明圖片資源被緩存到磁盤了,disk cache是強緩存,它是持久存儲。但是disk cache是會嚴格根據HTTP頭信息中的緩存控制字段來判定哪些資源可以緩存,緩存多久的。我們可以在HTTP響應頭裏設置Cache-ControlExpires來告訴小程序,這個圖片應不應該被緩存,如果緩存,應該緩存多久。

可以看到,上圖中,我的圖片響應頭裏是沒有Cache-ControlExpires的,所以當你沒有在響應頭裏設置緩存策略時,小程序會強緩存你的圖片,而且會緩存很久很久;

在我的需求裏,我這個圖片不會經常變動,就算變了,一天後生效也是OK的,所以我給這個圖片的響應頭加上Cache-Control: max-age=86400就可以了,max-age以秒爲單位,8640024小時

這樣設置以後,用戶第一次訪問圖片會被小程序緩存,24小時內用戶再次訪問此圖片,小程序不會發出網絡請求,而是直接從磁盤緩存裏讀取。24小時以後,緩存過期,用戶再次訪問此圖片時,小程序會發出請求從服務器獲取最新圖片。

我的圖片是放在阿里雲上的,應該如何設置響應頭呢?

雖然圖片是從CDN請求,但是我們CDN源站設置的是阿里雲對象存儲OSS的Bucket域名,對象存儲OSS可以設置資源的HTTP響應頭。

登錄阿里雲,進入對象存儲OSS,找到資源所在Bucket-文件管理,進入資源所在目錄,資源列表右邊“更多”裏有“設置HTTP頭“,除了可以設置單個資源的HTTP頭,還可以選擇當頁所有資源,批量設置HTTP頭。點擊“設置HTTP頭“,在“Cache-Control"字段填上值保存就可以了,如下圖:

 除了剛纔說的強緩存,還有一種協商緩存策略,再看我之前貼的那個圖片響應的圖,響應頭裏雖然沒有Cache-ControlExpires,但是有ETagLast-Modified,上面說當disk cache過期後,小程序會重新向服務端發起請求,此時客戶端會在請求頭帶上上一次圖片響應的ETagLast-Modified,分別放在If-None-MatchIf-Modified-Since裏,服務器接受到這兩個字段後,會和當前資源比較,如果ETag變了,或者資源修改時間大於上次修改時間,將返回新資源,否則返回304告訴客戶端,資源沒有變化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章