摘要:文件路徑,上線后,絲絲潤滑無痛無癢,完美第四個版本,可以做更多注意哦,重點來咯盡早加載是減少首屏時間的關鍵引申閱讀,直接把到里是個不錯的方案。
第一個版本,簡單粗暴有點痛所謂 File Prefetching 就是在一個頁面加載成功后,默默去預加載后續可能會被訪問到的頁面的資源。
前端資源預加載其實沒啥新鮮的,我們倒騰這個事情的過程卻是很有有意思也很有啟發性。
1、建一個獨立的頁面,里面索引了各種需要預加載的css、js,代碼類似下面這樣。
...其他需要預加載的css ...其他需要預加載的js
2、 在每個頁面加入一個iframe(一般通過base模板統一加),這樣每個頁面打開的時候都會加載上面這個頁面。假設上面的頁面的url是 https://xxx.com/common/prefetching.html 那么我們每個頁面底部都有這么一行代碼:
如何驗證要驗證某個file prefetching的方案是否真的有效,無非就是以下幾步:
(假設A頁面使用了showcase_d0fbaaef124a8691398704216ccd469a.css,而B頁面不會)
讓chrome終端打開的時候cache功能依舊有效
清空所有本地cache
打開B頁面,在控制臺Networking里看prefetching.html以及附屬的資源文件是否被下載了
打開A頁面,注意:是在地址欄里輸入A的網址然后回車,不要打開A頁面后習慣性地按Command/Ctrl+R來刷新,不出意外,我們會看到如下圖這樣的結果:
這說明,這2個css文件是從cache里讀的。如果Command/Ctrl+R來刷新頁面,我們會看到這樣的結果:
兩者的差別是,Command/Ctrl+R的時候,瀏覽器會從cache里找該靜態文件,如果找到了,會根據上次請求這個文件時得到的cache-control信息判斷該靜態文件是否已經過期了,如果沒有,會以 if-modified-since、Etag 等信息作為 request headers 向服務器請求這個文件,服務器如果認為文件沒有變過,會返回Http code為304,瀏覽器于是直接讀cache。具體不展開啦,可以看 [《HTTP caching
》](https://developers.google.com/web/fundam... 和 《Understanding HTTP/304 Responses》。
讓chrome終端打開的時候cache功能依舊有效:Chrome終端的配置里把Disable cache (while DevTools is open)的勾選去掉
清空所有cache:地址欄里輸入 chrome://settings/clearBrowserData 打開后勾上 Cached images and files 點 Clear browsing data
查看瀏覽器當前cache的資源列表:chrome://cache/
目前看來,上面這個 File Prefeching 的方案是有效的。不過這種是最簡陋的試驗版,存在幾個問題:
prefetching.html 里的js會被執行,然后不可避免地會有一堆js錯誤 —— 看著難受~
通過iframe 加載 prefetching.html 會影響到當前頁面相關資源的加載速度
每次打開頁面都會加載一次 prefetching.html,雖然里面的靜態文件都已經在第一次打開的時候被cache住了不會重復下載,但無謂多一個請求終究是沒必要。
于是,我們上線使用的版本是這樣的:
1、有一段每個頁面都會被執行到的js:
// 打開一個iframe,下載之后頁面可能需要的js/css setTimeout(function() { var lastOpenTime = 0; var nowTime = (new Date()).getTime(); try { lastOpenTime = window.localStorage.getItem("staticIframeOpenTime"); } catch (e) {} if (lastOpenTime > 0 && (nowTime - lastOpenTime < 24 * 3600 * 1000)) { // 24小時打開一次iframe return; } var iframe = $("
2、prefetching.html 里的資源想辦法讓他下載但不執行,基本上都是把這些css/js文件當做其他類型的文件來加載,最后參照了《Preload CSS/JavaScript without execution》這篇文章,prefetching.html 中加載js文件的代碼大概是這樣的:
通過對預加載的js文件只下載不執行、延時加載prefetching.html、借助localstorage的記錄一天只加載一次prefetching.html,基本上解決了版本一的3個問題。
效果和問題移動頁面全站上線后,平均loaded時間減少了0.15s,首屏時間沒有數據,不過收益應該是可觀的
不過,這個版本上線后,我們發現頁面在prefetching的時候會假死,最后定位到是因為object加載js導致的(具體為什么會這樣還沒細究),考慮到我們主要的頁面都是在手機端訪問的,基本上都是webkit內核(Image的方式在firefox中不兼容也不甚關系),所以我們決定改用Image來加載所有JS。
第三個版本,完美這個版本除了解決第二個版本的假死問題,還加入了dns-prefetch,關于這部分的背景和思路可以參考我另外一篇文章:《預加載系列一:DNS Prefetching 的正確使用姿勢》。
... ...
上線后,絲絲潤滑無痛無癢,完美
第四個版本,可以做更多注意哦,重點來咯!
盡早加載css是減少首屏時間的關鍵(引申閱讀),直接把css inline到html里是個不錯的方案。但是,這種方案的缺點是無法充分利用瀏覽器緩存。所以,我們嘗試在現有的File Prefetching 的基礎上,再進一步,讓首次訪問足夠快(用css line),后續訪問又能利用起瀏覽器緩存。
我們對一部分重點頁面的css文件改用類似加載js的方式去加載,并在加載成功的回調里加一條cookie記錄標示該css文件已經被下載。這樣在后端輸出html的時候,可以根據cookie的信息知道這幾個css文件是不是已經在瀏覽器里cache住了。如果是則正常輸出一個標簽。如果不是,說明用戶是第一次訪問這個頁面,則直接把css文件的內容inline到html里以求最快出首屏。當然,也會出現從cookie上看客戶端已經cache了某個css文件,但實際上沒有的情況,由于這種情況下html里輸出的還是一個link標簽,并不會影響正常的流程。
相關代碼大概是這樣的,需要的朋友可以參考下:
var loadCss = function(key, url) { var image = new Image(); var date = new Date(); date.setTime(+date + 1 * 86400000); // 因為下載的不是圖片,實際觸發的是onerror事件 image.onload = image.onerror = function () { document.cookie = key + "=" + url.slice(url.indexOf("build_css")) + ";path=/;domain=.youzan.com;expires=" + date.toGMTString(); }; image.src = url; } preloadCss = { key1: "文件路徑", key2: "文件路徑2" ... } for (var key in preloadCss) { loadCss(key, preloadCss[key]); }總結
在做 File Prefetching 的過程當中,每一個版本的優化都是不同的人在做的:
A起了個頭 ->
B改進到能上線的標準 ->
發現有問題,C改進了它 ->
D又在這個基礎上做出了最后一個版本。
這種感覺非常好:)
TODO其實還有一類資源可以加到這個prefetching.html里,那就是常用的圖片,不過我們還沒這么做。
現在我們有贊全部移動web頁只使用一個prefetching.html,并還沒有針對不同的條件進行針對性的的prefetching。
本文首發于我的
SegmentFault專欄:https://segmentfault.com/a/1190000004189...
個人技術博客:http://delai.me/code/file-frefetching/
轉載請注明出處
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/61759.html
摘要:前端日報精選和實現直接當前頁預覽手淘互動動效的探索白話原型和原型鏈源碼解析瀏覽器前端優化中文第期深入理解中的動畫演示,提高你的網頁開發技能知乎專欄實戰一概覽工作機制第部分迷津欲有問把賣了眾成翻譯代理程序實現復制集搭建及抓包 2017-08-24 前端日報 精選 iframe和HTML5 blob實現JS,CSS,HTML直接當前頁預覽手淘互動動效的探索白話原型和原型鏈React 源碼解...
摘要:錯過一周的優質內容,不要再錯過周一的快速回顧寒潮來得出乎意料,手腳,一遍聽著史詩巨著張士超你到底把我家鑰匙放哪里了,一邊將優質內容進行整理一周咨詢當技術成為一種武器翻譯組一周簡訊跟著輪子哥造輪子基本概念二排版前端名一前端遠程調試德來預加載 錯過一周的優質內容,不要再錯過周一的快速回顧 寒潮來得出乎意料,dong手dong腳,一遍聽著史詩巨著《張士超你到底把我家鑰匙放哪里了》,一邊將優質...
摘要:錯過一周的優質內容,不要再錯過周一的快速回顧寒潮來得出乎意料,手腳,一遍聽著史詩巨著張士超你到底把我家鑰匙放哪里了,一邊將優質內容進行整理一周咨詢當技術成為一種武器翻譯組一周簡訊跟著輪子哥造輪子基本概念二排版前端名一前端遠程調試德來預加載 錯過一周的優質內容,不要再錯過周一的快速回顧 寒潮來得出乎意料,dong手dong腳,一遍聽著史詩巨著《張士超你到底把我家鑰匙放哪里了》,一邊將優質...
閱讀 741·2021-11-11 16:54
閱讀 3062·2021-09-26 09:55
閱讀 2012·2021-09-07 10:20
閱讀 1205·2019-08-30 10:58
閱讀 1052·2019-08-28 18:04
閱讀 705·2019-08-26 13:57
閱讀 3591·2019-08-26 13:45
閱讀 1156·2019-08-26 11:42