摘要:緩存緩存,也叫網(wǎng)關(guān)緩存反向代理緩存。瀏覽器先向網(wǎng)關(guān)發(fā)起請求,網(wǎng)關(guān)服務(wù)器后面對應(yīng)著一臺或多臺負(fù)載均衡源服務(wù)器,會根據(jù)它們的負(fù)載請求,動態(tài)將請求轉(zhuǎn)發(fā)到合適的源服務(wù)器上。雖然這種架構(gòu)負(fù)載均衡源服務(wù)器之間的緩存沒法共享,但卻擁有更好的處擴(kuò)展性。
一、前言?
工作上遇到一個(gè)這樣的需求,一個(gè)H5頁面在APP端,如果勾選已讀狀態(tài),則下次打開該鏈接,會跳過此頁面。用到了HTML5 的本地存儲 API 中的 localStorage作為解決方案,回顧了下Web緩存的知識,感覺自己了解得不夠多,所以想整理下,加深理解。
二、web緩存的作用Web緩存是指一個(gè)Web資源(如html頁面,圖片,js,數(shù)據(jù)等)存在于Web服務(wù)器和客戶端(瀏覽器)之間的副本。緩存會根據(jù)進(jìn)來的請求保存輸出內(nèi)容的副本;當(dāng)下一個(gè)請求來到的時(shí)候,如果是相同的URL,緩存會根據(jù)緩存機(jī)制決定是直接使用副本響應(yīng)訪問請求,還是向源服務(wù)器再次發(fā)送請求。比較常見的就是瀏覽器會緩存訪問過網(wǎng)站的網(wǎng)頁,當(dāng)再次訪問這個(gè)URL地址的時(shí)候,如果網(wǎng)頁沒有更新,就不會再次下載網(wǎng)頁,而是直接使用本地緩存的網(wǎng)頁。只有當(dāng)網(wǎng)站明確標(biāo)識資源已經(jīng)更新,瀏覽器才會再次下載網(wǎng)頁。
減少網(wǎng)絡(luò)帶寬消耗(當(dāng)Web緩存副本被使用時(shí),只會產(chǎn)生極小的網(wǎng)絡(luò)流量,可以有效的降低運(yùn)營成本。)
降低服務(wù)器壓力(給網(wǎng)絡(luò)資源設(shè)定有效期之后,用戶可以重復(fù)使用本地的緩存,減少對源服務(wù)器的請求,間接降低服務(wù)器的壓力。同時(shí),搜索引擎的爬蟲機(jī)器人也能根據(jù)過期機(jī)制降低爬取的頻率,也能有效降低服務(wù)器的壓力。)
減少網(wǎng)絡(luò)延遲,加開頁面打開速度。
三、web緩存的類型在Web應(yīng)用領(lǐng)域,Web緩存大致可以分為以下幾種類型:
3.1 數(shù)據(jù)庫數(shù)據(jù)緩存3.2 服務(wù)器端緩存Web應(yīng)用,特別是SNS類型的應(yīng)用,往往關(guān)系比較復(fù)雜,數(shù)據(jù)庫表繁多,如果頻繁進(jìn)行數(shù)據(jù)庫查詢,很容易導(dǎo)致數(shù)據(jù)庫不堪重荷。為了提供查詢的性能,會將查詢后的數(shù)據(jù)放到內(nèi)存中進(jìn)行緩存,下次查詢時(shí),直接從內(nèi)存緩存直接返回,提供響應(yīng)效率。比如常用的緩存方案有memcached等。
服務(wù)器端緩存包含代理服務(wù)器緩存和CDN緩存:
3.2.1 代理服務(wù)器緩存3.2.2 CDN緩存代理服務(wù)器是瀏覽器和源服務(wù)器之間的中間服務(wù)器,瀏覽器先向這個(gè)中間服務(wù)器發(fā)起Web請求,經(jīng)過處理后(比如權(quán)限驗(yàn)證,緩存匹配等),再將請求轉(zhuǎn)發(fā)到源服務(wù)器。代理服務(wù)器緩存的運(yùn)作原理跟瀏覽器的運(yùn)作原理差不多,只是規(guī)模更大。可以把它理解為一個(gè)共享緩存,不只為一個(gè)用戶服務(wù),一般為大量用戶提供服務(wù),因此在減少相應(yīng)時(shí)間和帶寬使用方面很有效,同一個(gè)副本會被重用多次。常見代理服務(wù)器緩存解決方案有Squid等,這里不再詳述。
3.3 瀏覽器端緩存CDN(Content delivery networks)緩存,也叫網(wǎng)關(guān)緩存、反向代理緩存。CDN緩存一般是由網(wǎng)站管理員自己部署,為了讓他們的網(wǎng)站更容易擴(kuò)展并獲得更好的性能。瀏覽器先向CDN網(wǎng)關(guān)發(fā)起Web請求,網(wǎng)關(guān)服務(wù)器后面對應(yīng)著一臺或多臺負(fù)載均衡源服務(wù)器,會根據(jù)它們的負(fù)載請求,動態(tài)將請求轉(zhuǎn)發(fā)到合適的源服務(wù)器上。雖然這種架構(gòu)負(fù)載均衡源服務(wù)器之間的緩存沒法共享,但卻擁有更好的處擴(kuò)展性。從瀏覽器角度來看,整個(gè)CDN就是一個(gè)源服務(wù)器。
3.4 Web應(yīng)用層緩存瀏覽器緩存(Browser Caching)是瀏覽器端保存數(shù)據(jù)用于快速讀取或避免重復(fù)資源請求的優(yōu)化機(jī)制,有效的緩存使用可以避免重復(fù)的網(wǎng)絡(luò)請求和瀏覽器快速地讀取本地?cái)?shù)據(jù),整體上加速網(wǎng)頁展示給用戶。
應(yīng)用層緩存指的是從代碼層面上,通過代碼邏輯和緩存策略,實(shí)現(xiàn)對數(shù)據(jù),頁面,圖片等資源的緩存,可以根據(jù)實(shí)際情況選擇將數(shù)據(jù)存在文件系統(tǒng)或者內(nèi)存中,減少數(shù)據(jù)庫查詢或者讀寫瓶頸,提高響應(yīng)效率。
接下來從Web前端的角度著重了解瀏覽器端緩存機(jī)制。
四、web緩存之瀏覽器端緩存淺析根據(jù)標(biāo)準(zhǔn),到目前為止,H5 一共有6種緩存機(jī)制,有些是之前已有,有些是 H5 才新加入的。
1. 瀏覽器緩存機(jī)制 2. Dom Storgage(Web Storage)存儲機(jī)制 3. Web SQL Database 存儲機(jī)制 4. Application Cache(AppCache)機(jī)制 5. Indexed Database (IndexedDB) 6. File System API4.1 瀏覽器緩存機(jī)制 4.1.1 非HTTP協(xié)議定義的緩存機(jī)制
瀏覽器緩存機(jī)制,其實(shí)主要就是HTTP協(xié)議定義的緩存機(jī)制(如: Expires; Cache-control等)。但是也有非HTTP協(xié)議定義的緩存機(jī)制,如使用HTML Meta 標(biāo)簽,Web開發(fā)者可以在HTML頁面的
節(jié)點(diǎn)中加入標(biāo)簽,代碼如下:上述代碼的作用是告訴瀏覽器當(dāng)前頁面不被緩存,每次訪問都需要去服務(wù)器拉取。使用上很簡單,但只有部分瀏覽器可以支持,而且所有緩存代理服務(wù)器都不支持,因?yàn)榇聿唤馕鯤TML內(nèi)容本身。下面主要介紹HTTP協(xié)議定義的緩存機(jī)制。
4.1.2 HTTP協(xié)議定義的緩存機(jī)制通過 HTTP 協(xié)議頭里的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段來控制文件緩存的機(jī)制。這應(yīng)該是 WEB 中最早的緩存機(jī)制了,是在 HTTP 協(xié)議中實(shí)現(xiàn)的,有點(diǎn)不同于 Dom Storage、AppCache 等緩存機(jī)制,但本質(zhì)上是一樣的??梢岳斫鉃?,一個(gè)是協(xié)議層實(shí)現(xiàn)的,一個(gè)是應(yīng)用層實(shí)現(xiàn)的。
4.1.3 HTTP1.0 時(shí)代緩存字段詳解Pragma:設(shè)置頁面是否緩存,為Pragma則緩存,no-cache則不緩存。
Expires:有了Pragma來禁用緩存,自然也需要有個(gè)東西來啟用緩存和定義緩存時(shí)間,對http1.0而言,Expires就是做這件事的首部字段。 Expires的值對應(yīng)一個(gè)GMT(格林尼治時(shí)間),比如Mon, 22 Jul 2002 11:12:01 GMT來告訴瀏覽器資源緩存過期時(shí)間,如果還沒過該時(shí)間點(diǎn)則不發(fā)請求。
如果Pragma頭部和Expires頭部同時(shí)存在,則起作用的會是Pragma,需要注意的是,響應(yīng)報(bào)文中Expires所定義的緩存時(shí)間是相對服務(wù)器上的時(shí)間而言的,其定義的是資源“失效時(shí)刻”,如果客戶端上的時(shí)間跟服務(wù)器上的時(shí)間不一致(特別是用戶修改了自己電腦的系統(tǒng)時(shí)間),那緩存時(shí)間可能就沒啥意義了。
Cache-Control: 針對上述的“Expires時(shí)間是相對服務(wù)器而言,無法保證和客戶端時(shí)間統(tǒng)一”的問題,http1.1新增了 Cache-Control 來定義緩存過期時(shí)間。注意:若報(bào)文中同時(shí)出現(xiàn)了 Expires 和 Cache-Control,則以 Cache-Control 為準(zhǔn)。
(1) 最常見的,比如服務(wù)器回包:Cache-Control:max-age=600 表示文件在本地應(yīng)該緩存,且有效時(shí)長是600秒(從發(fā)出請求算起)。在接下來600秒內(nèi),如果有請求這個(gè)資源,瀏覽器不會發(fā)出 HTTP 請求,而是直接使用本地緩存的文件。
(2) Cache-Control: no-cache;這個(gè)很容易讓人產(chǎn)生誤解,使人誤以為是響應(yīng)不被緩存。實(shí)際上她是會被緩存的,只不過每次在向客戶端(瀏覽器)提供響應(yīng)數(shù)據(jù)時(shí),緩存都要向服務(wù)器評估緩存響應(yīng)的有效性。
(3) Cache-Control: no-store;這個(gè)才是響應(yīng)不被緩存的意思。
Last-Modified/If-Modified-Since:
(1) Last-Modified:標(biāo)示這個(gè)響應(yīng)資源的最后修改時(shí)間。web服務(wù)器在響應(yīng)請求時(shí),告訴瀏覽器資源的最后修改時(shí)間。
(2) If-Modified-Since:當(dāng)資源過期時(shí)(使用Cache-Control標(biāo)識的max-age),發(fā)現(xiàn)資源具有Last-Modified聲明,則再次向web服務(wù)器請求時(shí)帶上頭 If-Modified-Since,表示請求時(shí)間。web服務(wù)器收到請求后發(fā)現(xiàn)有頭If-Modified-Since 則與被請求資源的最后修改時(shí)間進(jìn)行比對。若最后修改時(shí)間較新,說明資源又被改動過,則響應(yīng)整片資源內(nèi)容(寫在響應(yīng)消息包體內(nèi)),HTTP 200;若最后修改時(shí)間較舊,說明資源無新修改,則響應(yīng)HTTP 304 (無需包體,節(jié)省瀏覽),告知瀏覽器繼續(xù)使用所保存的cache。
Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用。
(1) Etag:web服務(wù)器響應(yīng)請求時(shí),告訴瀏覽器當(dāng)前資源在服務(wù)器的唯一標(biāo)識(生成規(guī)則由服務(wù)器覺得)。Apache中,ETag的值,默認(rèn)是對文件的索引節(jié)(INode),大?。⊿ize)和最后修改時(shí)間(MTime)進(jìn)行Hash后得到的。
(2) If-None-Match:當(dāng)資源過期時(shí)(使用Cache-Control標(biāo)識的max-age),發(fā)現(xiàn)資源具有Etage聲明,則再次向web服務(wù)器請求時(shí)帶上頭If-None-Match (Etag的值)。web服務(wù)器收到請求后發(fā)現(xiàn)有頭If-None-Match 則與被請求資源的相應(yīng)校驗(yàn)串進(jìn)行比對,決定返回200或304。
既生Last-Modified何生Etag?
你可能會覺得使用Last-Modified已經(jīng)足以讓瀏覽器知道本地的緩存副本是否足夠新,為什么還需要Etag(實(shí)體標(biāo)識)呢?HTTP1.1中Etag的出現(xiàn)主要是為了解決幾個(gè)Last-Modified比較難解決的問題:
(1) Last-Modified標(biāo)注的最后修改只能精確到秒級,如果某些文件在1秒鐘以內(nèi),被修改多次的話,它將不能準(zhǔn)確標(biāo)注文件的修改時(shí)間。
(2) 如果某些文件會被定期生成,當(dāng)有時(shí)內(nèi)容并沒有任何變化,但Last-Modified卻改變了,導(dǎo)致文件沒法使用緩存。
(3) 有可能存在服務(wù)器沒有準(zhǔn)確獲取文件修改時(shí)間,或者與代理服務(wù)器時(shí)間不一致等情形。
Etag是服務(wù)器自動生成或者由開發(fā)者生成的對應(yīng)資源在服務(wù)器端的唯一標(biāo)識符,能夠更加準(zhǔn)確的控制緩存。Last-Modified與ETag是可以一起使用的,服務(wù)器會優(yōu)先驗(yàn)證ETag,一致的情況下,才會繼續(xù)比對Last-Modified,最后才決定是否返回304。
小結(jié)
(1) 瀏覽器第一次請求:
(2) 瀏覽器第二次請求:
DOM Storage 是指 HTML5 的本地存儲 API sessionStorage 和 localStorage。在介紹HTML5本地存儲之前,先來看一看前面幾個(gè)存儲方式的概念。
(1) HTTP Cookie: Cookie是為了解決HTTP無狀態(tài)的特性而出現(xiàn)的,也可以叫用戶識別機(jī)制。常用的用戶識別機(jī)制包括:
承載用戶信息的HTTP首部
客戶端IP地址追蹤技術(shù),通過用戶的IP地址對其進(jìn)行識別
用戶登錄,用認(rèn)證機(jī)制來識別用戶
胖URL,一種在URL中嵌入識別信息的技術(shù)
cookie,一種強(qiáng)大且高效的持久身份識別技術(shù)
對于購物網(wǎng)站而言,cookie是非常重要的,為了實(shí)現(xiàn)購物車功能,把已選物品加入cookie,可以實(shí)現(xiàn)不同頁面之間數(shù)據(jù)的同步,同時(shí)在提交訂單的時(shí)候又會把這些cookie傳到后臺,大大方便了前后端開發(fā)。
設(shè)置cookie:
function setCookie(name, value, options) { var expires = options.expires; var path = options.path; var domain = options.domain; var secure = options.secure; // 緩存時(shí)間轉(zhuǎn)為日期對象 if (typeof expires === "number") { expires = new Date(new Date().getTime() + expires * 864e+5); // 緩存時(shí)間單位:天 } document.cookie = name + "=" + escape(value) + (expires ? "; expires=" + expires.toUTCString() : "") + (path ? "; path=" + path : "") + (domain ? "; domain=" + domain : "") + (secure ? "; secure" : ""); return true; }
獲取cookie:
function getCookie(name) { var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)")); if (arr !== null) { return unescape(arr[2]); } // return null; return ""; }
(2) userData是微軟在上世紀(jì)90年代的瀏覽器大戰(zhàn)時(shí)推出的本地存儲方案,借助DHTML的behaviour屬性來存儲本地?cái)?shù)據(jù), 允許每個(gè)頁面最多存儲64K數(shù)據(jù),每個(gè)站點(diǎn)最多640K數(shù)據(jù),userData的缺點(diǎn)顯而易見,它不是Web標(biāo)準(zhǔn)的一部分,除非你的程序只需要支持IE, 否則它基本沒什么用處。
(3) Flash cookie的名字有些誤導(dǎo),它實(shí)際上和HTTP cookie并不是一回事,或許它的名字應(yīng)該叫做"Flash本地存儲”,F(xiàn)lash cookie默認(rèn)允許每個(gè)站點(diǎn)存儲不超過100K的數(shù)據(jù),如果超出了,F(xiàn)lash會自動向用戶請求更大的存儲空間,借助Flash的 ExternalInterface接口,你可以很輕松地通過Javascript操作Flash的本地存儲。Flash的問題很簡單,就是因?yàn)樗?Flash。
(4) Gears是Google在07年發(fā)布的一個(gè)開源瀏覽器插件,旨在改進(jìn)各大瀏覽器的兼容性,Gears內(nèi)置了一個(gè)基于SQLite的嵌入式 SQL數(shù)據(jù)庫,并提供了統(tǒng)一API對數(shù)據(jù)庫進(jìn)行訪問,在取得用戶授權(quán)之后,每個(gè)站點(diǎn)可以在SQL數(shù)據(jù)庫中存儲不限大小的數(shù)據(jù),Gears的問題就是 Google自己都已經(jīng)不用它了。
(5) HTML5 的本地存儲 API sessionStorage 和 localStorage
Dom Storage 是通過存儲字符串的 Key/Value 對來提供的,并提供 5MB (不同瀏覽器可能不同,分 HOST)的存儲空間(Cookies 才 4KB)。另外 Dom Storage 存儲的數(shù)據(jù)在本地,不像 Cookies,每次請求一次頁面,Cookies 都會發(fā)送給服務(wù)器。
DOM Storage 分為 sessionStorage 和 localStorage。localStorage 對象和 sessionStorage 對象使用方法基本相同,它們的區(qū)別在于作用的范圍不同。sessionStorage 用來存儲與頁面相關(guān)的數(shù)據(jù),它在頁面關(guān)閉后無法使用。而 localStorage 則持久存在,在頁面關(guān)閉后也可以使用。
簡單用法:
var name = sessionStorage.setItem("name","wangjuan"); alert(sessionStorage.getItem("name"));
并不是所有的瀏覽器都支持這兩個(gè)對象。在沒有原生支持localStorage的瀏覽器中使用時(shí),MDN給出了兼容代碼:https://developer.mozilla.org...
不同瀏覽器對于這兩種用法的差異的兼容代碼可參考: https://github.com/mortzdk/lo...
H5 也提供基于 SQL 的數(shù)據(jù)庫存儲機(jī)制,用于存儲適合數(shù)據(jù)庫的結(jié)構(gòu)化數(shù)據(jù)。根據(jù)官方的標(biāo)準(zhǔn)文檔,Web SQL Database 存儲機(jī)制不再推薦使用,將來也不再維護(hù),而是推薦使用 AppCache 和 IndexedDB。
查看更多:戳這里
Application Cache(簡稱 AppCache)似乎是為支持 Web App 離線使用而開發(fā)的緩存機(jī)制。它的緩存機(jī)制類似于瀏覽器的緩存(Cache-Control 和 Last-Modified)機(jī)制,都是以文件為單位進(jìn)行緩存,且文件有一定更新機(jī)制。但 AppCache 是對瀏覽器緩存機(jī)制的補(bǔ)充,不是替代。
AppCache 的原理有兩個(gè)關(guān)鍵點(diǎn):manifest 屬性和 manifest 文件。
W3C 官方的一個(gè)例子:
上面 HTML 文檔,引用外部一個(gè) JS 文件和一個(gè) GIF 圖片文件,在其 HTML 頭中通過 manifest 屬性引用了一個(gè) appcache 結(jié)尾的文件(即manifest文件)。
緩存的結(jié)果是:我們在 Google Chrome 瀏覽器中打開這個(gè) HTML 鏈接,JS 功能正常,圖片也顯示正常。禁用網(wǎng)絡(luò),關(guān)閉瀏覽器重新打開這個(gè)鏈接,發(fā)現(xiàn) JS 工作正常,圖片也顯示正常。當(dāng)然也有可能是瀏覽緩存起的作用,我們可以在文件的瀏覽器緩存過期后,禁用網(wǎng)絡(luò)再試,發(fā)現(xiàn) HTML 頁面也是正常的。
manifest 文件就是以 appcache 結(jié)尾的文件,是一個(gè)普通文件文件,列出了需要緩存的文件。
完整的 manifest 文件,如:
CACHE MANIFEST # 2012-02-21 v1.0.0 /theme.css /logo.gif /main.js NETWORK: login.asp FALLBACK: /html/ /offline.html
了解更多:戳我
4.5 Indexed DatabaseIndexedDB 也是一種數(shù)據(jù)庫的存儲機(jī)制,但不同于已經(jīng)不再支持的 Web SQL Database。IndexedDB 不是傳統(tǒng)的關(guān)系數(shù)據(jù)庫,indexedDB中沒有表的概念,類似于 Dom Storage 的 key-value 的存儲方式,但功能更強(qiáng)大,且存儲空間更大。它的特點(diǎn)是:
以key-value 的方式存取對象,可以是任何類型值或?qū)ο?,包括二進(jìn)制。
可以對對象任何屬性生成索引,方便查詢。
較大的存儲空間,默認(rèn)推薦250MB(分 HOST),比 Dom Storage 的5MB要大的多。
通過數(shù)據(jù)庫的事務(wù)(tranction)機(jī)制進(jìn)行數(shù)據(jù)操作,保證數(shù)據(jù)一致性。
異步的 API 調(diào)用,避免造成等待而影響體驗(yàn)。
了解更多:資料1,資料2
4.6 File System APIFile System API 是 H5 新加入的存儲機(jī)制。它為 Web App 提供了一個(gè)虛擬的文件系統(tǒng),就像 Native App 訪問本地文件系統(tǒng)一樣。由于安全性的考慮,這個(gè)虛擬文件系統(tǒng)有一定的限制。Web App 在虛擬的文件系統(tǒng)中,可以進(jìn)行文件(夾)的創(chuàng)建、讀、寫、刪除、遍歷等操作。
File System API 也是一種可選的緩存機(jī)制,和前面的 SQLDatabase、IndexedDB 和 AppCache 等一樣。File System API 有自己的一些特定的優(yōu)勢:
可以滿足大塊的二進(jìn)制數(shù)據(jù)( large binary blobs)存儲需求。
可以通過預(yù)加載資源文件來提高性能。
可以直接編輯文件。
了解更多:資料
五、總結(jié)之前對web緩存沒有系統(tǒng)的認(rèn)知,接觸過一兩點(diǎn),不過也不是很懂。這兩天查看了許多資料,雖然看過之后理解得也不太深入,不過有個(gè)整體的認(rèn)知也好,后面自己遇到相關(guān)問題再細(xì)究。
參考資料:
1、九種瀏覽器端緩存機(jī)制知多少
2、瀏覽器緩存原理
3、Web緩存機(jī)制系列
4、Web 前端實(shí)現(xiàn)本地存儲
5、H5 緩存機(jī)制淺析 - 移動端 Web 加載性能優(yōu)化
6、瀏覽器緩存機(jī)制
7、瀏覽器緩存機(jī)制詳解
8、透過瀏覽器看HTTP緩存
9、淺談瀏覽器http的緩存機(jī)制
10、瀏覽器緩存機(jī)制淺析
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/61871.html
摘要:最近關(guān)注的重學(xué)前端系列文章,也想把已知的前端知識體系梳理一遍,夯實(shí)基礎(chǔ)的同時(shí),總結(jié)提升。標(biāo)準(zhǔn)模式的排版和運(yùn)作模式都是以該瀏覽器支持的最高標(biāo)準(zhǔn)運(yùn)行。模式是目前最常用的模式。嚴(yán)格模式不允許展示型棄用元素和框架集。中空格不會被自動刪除。 最近關(guān)注winter的重學(xué)前端系列文章,也想把已知的前端知識體系梳理一遍,夯實(shí)基礎(chǔ)的同時(shí),總結(jié)提升。接下來會從HTML、CSS、JS、性能、網(wǎng)絡(luò)安全、框架通...
摘要:學(xué)習(xí)與實(shí)踐系列文章已整理至學(xué)習(xí)手冊,文字內(nèi)容已同步至。本系列文章學(xué)習(xí)與實(shí)踐會逐步拆解背后的各項(xiàng)技術(shù),通過實(shí)例代碼來講解這些技術(shù)的應(yīng)用方式。而隨著在中也開始支持其中的某些技術(shù),的舞臺更大了。這個(gè)最開始是不具備任何的能力。 《PWA學(xué)習(xí)與實(shí)踐》系列文章已整理至gitbook - PWA學(xué)習(xí)手冊,文字內(nèi)容已同步至learning-pwa-ebook。轉(zhuǎn)載請注明作者與出處。 PWA作為今年最火...
閱讀 3659·2021-09-22 15:15
閱讀 3564·2021-08-12 13:24
閱讀 1312·2019-08-30 15:53
閱讀 1824·2019-08-30 15:43
閱讀 1184·2019-08-29 17:04
閱讀 2794·2019-08-29 15:08
閱讀 1583·2019-08-29 13:13
閱讀 3088·2019-08-29 11:06