本篇大綱
PWA會是未來趨勢啊
最近在研究PWA。
很久以前遇到朋友在問pwa的東西,那時因為沒聽過,所以也沒太在意。但上個月有後端的朋友問lighthouse的測試,用了lighthouse後,發現上面的評分標準有一項就是pwa,才發現這應該是前端需要知道的技術。
google了一下pwa,驚覺,這一定會是未來趨勢啊!!
這樣相信的原因有幾個:
- google在lighthouse中列為評分標準
- 可以減少頁面讀取的時間,而讀取時間又是seo的影響要素之一
- 當檔案存在cache中,即便無網路的情況下,頁面也可以開啟
- Andriod會主動提示是否加入手機桌面,開啟時還可以隱藏網址欄
- 可以推播訊息
- 不是每一間公司都養得起一位ios app工程師+一位andriod工程師的,因此這種很像是app的作法可以是一種替代方案
除了第1點,基本上2–6點是爬了一些文上看到的。
另外google的PageSpeed Insights最近也開始併入了lighthouse的評分,也許有一天pwa的項目會加進去,到那時,在用pagespeed測頁面速度的工程師、企劃、pm……都會開始注意到pwa(用lighthouse測頁面的早就注意到了吧?)。
所以,與其到未來大家都在用的時候才研究,不如趁知道的時候就趕快研究。
結果,光是看存入cache這段,就看了好久,撞了好多次壁。
這篇是從service-worker到sw-precache到workbox的基本使用,還沒進入workbox cli前的筆記。
如果只是想把檔案存到cache,減少頁面讀取時間,那這篇也夠用了。
推薦3篇優質教學文
在兩眼一抹黑的情況下,踩了許多坑,在這邊推薦三篇受益很多的教學文:
這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝
是一位前端工程師在2017iT邦幫忙鐵人賽的系列文章。除了介紹pwa,也有實作出to do list出來。
介紹了pwa的存cache跟推播功能,並用原生js寫出demo code。
這篇介紹了workbox的主要應用,在一團亂的情況下,是看完這篇才對workbox有了基本的認識。
以下,是本階段研究的筆記,因為主要想拿來實用,所以對很多理論上的東西沒有深入研究,目的是可以拿來在下一個案子中使用並看成效是否有比較好。
如果有寫錯的地方,請不吝指教。
關於「存到快取(cache)」的就我所知
「快取」是蠻常聽到的一個詞,大部份出現在網頁有做修改了以後,企劃或客戶就會打來問說「為什麼我的頁面重整後還是一樣?」,然後工程師看了一下後就會說:「喔,把快取清掉就好了。」
這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝
接著是前端的話,就會改一下引用css或js那行的版本號,後端的話就會寫個清快取的功能給使用者可以手動清,最後當企劃或客戶重新整理頁面時,就會看見更新過的樣子,從此大家就過著幸福快樂的日子。
基本上在一個靠google寫程式的時代,講快取/緩存的技術文章很多,這邊就不做深入研究了。
這邊主要記錄在pwa上,存到快取是什麼意思?
如果我們去一間咖啡店買咖啡,流程大概如下:
- 你填了菜單,到櫃台點一杯咖啡 →
- 櫃台轉身對廚房人員說:要一杯咖啡 →
- 廚房泡了一杯咖啡後,送到櫃台 →
- 櫃台把咖啡拿給你。The End。
其實,我們打開chrome,進到某個網頁,也差不多在做一樣的事情。
假設今天我們要進到google首頁,會是這樣:
- 瀏覽器(你)送需求(菜單)到伺服器(櫃台),要google首頁的檔案(咖啡) →
- 伺服器(櫃台)向資料庫(廚房)要資料(咖啡) →
- 資料庫(廚房)篩出要的資料(咖啡),給伺服器(櫃台) →
- 伺服器(櫃台)把拿到的檔案(咖啡),傳給瀏覽器(你)。The End。
好啦,其實背後還有很多工,但就像廚房要做一杯咖啡也不是泡泡三合一就端出來,一個簡單的事情背後都是很多工的。
詳細可以看這一篇:從使用者輸入網址,到瀏覽器呈現出來,經過了哪些過程?
那,pwa的存cache,是影響了哪一個部份?
一樣從買咖啡那個例子來看,這次多一個新角色:媽媽。
- 你填了菜單,到櫃台點一杯咖啡的時候 →
- 媽媽跳了出來,說咖啡家裡冰箱就有啦,就把你的菜單拿走 →
- 媽媽把家裡的咖啡拿給你。The End。
那個媽媽,就是pwa裡的service-worker(sw.js)這支檔案,而冰箱就是cache。
sw.js是實際執行存cache這段的js檔,全名是service-worker。
pwa建的sw.js,裡面有一步就是攔截所有發向伺服器的請求(媽媽拿走你的菜單),如果發現request的檔案,跟cache裡有的檔案是同一個時,就會直接拿cache裡的檔案當作response。
要注意的是sw.js可以攔截所有request,權限非常非常的大,為了確保傳遞時的安全性,pwa就只能在https底下執行。
實作:註冊sw.js
以下就要開始寫code了,寫如何用sw.js去存cache。
首先,在index.html,要加一段註冊sw.js的script,讓sw.js可以發揮功能。
register的路徑,因為是練習用,所以把sw.js建在/pwatest/這個資料夾裡。
sw.js的檔案註冊在哪,這支sw.js影響的範圍就在哪。
像是這邊是註冊在/pwatest/底下,因此能攔截需求的網址也要在https://xxxx.xxx.tw/pwatest/裡。
畢竟sw.js能攔截所有request,權力大的沒邊啊,如果一開始就下在根目錄,整個站都會受影響,目前還是拿來練習用,就先建在子目錄中。
註冊sw.js用了promise,而promise在IE是不支援,原本想用core.js來做補救,但後來想想……IE根本不支援service-worker啊,要不要polyfill什麼的都無所謂啦~
如何查看是否成功註冊sw.js
成功註冊sw.js的話,在開發人員工具 →Application →Service Workers中可以看到以下:

註冊完sw.js以後,就是要存一個sw.js的檔案,然後寫裡面的code了。
實作:寫一份sw.js檔
在爬文的時候,寫sw.js這段最混亂,也最麻煩。
遇到的情況是:
- 開頭先是看教學文,還用原生的js寫了一支出來(就是 講講PWA 這篇)
- 接著看到別的文章中說google有出生成器sw-precache(就是 iT邦幫忙 這篇)
- 又用了sw-precace以後,發現說明文件最後寫了:
The team behind sw-toolbox and sw-precache have been busy creating Workbox, which is a collection of libraries and tools that make it easy to build offline web apps. It’s a joining of sw-toolbox and sw-precache with more features and a modern codebase.
簡單來說就是,他們正在開發更好棒棒的workbox build,希望大家在寫新專案時可以換成這套。
看到這點頭都暈了,只是想要有個js可以存取cache,是要走過多少條路,而且workbox的說明文件很多頁啊,又全都英文,看完又是一段長路要走。
一開始為了求速成,就直接看他們寫的跟gulp做結合的範例code,複製貼上後執行,就有一份sw.js檔了~而且還真的可以用。
但,我找不到自訂cache檔案名稱的參數,而且他們還有一些像是css、js、image可以分開存成不同cache的功能,也沒有給gulp用的範例。
因此,只好重頭開始看說明文件。
實作:用workbox建立sw.js
看完說明文件的「使用入門」、「總覽」這兩篇後,其實,只要複製裡面的範例碼,就可以做到存cache、攔截request並傳回resoponse了,而且範例碼還真的很好懂,只能說google團隊太強大了。
以下附上兩種寫法,如果是小專案要用,直接copy貼上,並更新要存成cache的檔案路徑就行了。
範例1:單純存成cache
範例2:文件中說,如果頁面想要可以離線讀取時的寫法
當sw.js的內容寫了上面的範例1或2後,就可以在開發人員工具 →Application →Cache Storage中看到存取的檔案,如下圖(以下是範例1的結果):

實測:頁面載入速度有比較快嗎?
來測試一下,用了cache後是不是頁面讀取速度有比較快?
這邊是用chrome70的瀏覽器來測,檔案是放到godaddy上的經濟版 Linux主機。
以下這張是沒有用cache,頁面重新整理了三次,第三次的network的記錄:

以下這張是用了cache,一樣重新整理三次後network的記錄:

使用前跟使用後,頁面讀取時間從1.78秒降到787毫秒,降了接近1秒。
聽起來是蠻像在造神還是在業配的,不過讀取速度有比較快是真的。
補充一個重要的想法:pwa適合的是前後分離的開發方式。
為什麼?
從上面範例2可以看出來,為了要達到離線時也能開啟頁面,cache裡也存了「index.html」這檔案。
由於頁面的html不動,那抓資料的方式就是用ajax去抓,抓完後再丟進頁面裡。這是前後分離的作法。
如果是後端開發,後端直接丟資料進頁面,那用cache的方式就一定會死,使用者即便不斷重新整理頁面,看到的還是舊的,因為cache裡存的會是前一版的html,除非sw.js檔案更新,重新抓一次檔案進cache。
因此如果網站主要是由後端開發,cache這段就只能存必要的css、js、image等,至少可以減少頁面讀取的時間。
這篇的筆記就寫到這邊,之後會再來看workbox cli跟workbox裡眾多參數的意思。
這是一篇學習中的筆記,如果有寫錯的地方還請不吝告知。
PWA學習筆記系列
- PWA學習筆記-1:cache、workbox基本使用
- PWA學習筆記-2:workbox CLI
- PWA學習筆記-3:workbox 參數
- PWA學習筆記-4:manifest.json
- PWA學習筆記-5:用firebase做web push

