欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
改造你的網(wǎng)站,變身 PWA

最近有很多關(guān)于 Progressive Web Apps(PWAs)的消息,很多人都在問(wèn)這是不是(移動(dòng))web 的未來(lái)。我不想陷入native app 和 PWA 的紛爭,但是有一件事是確定的 --- PWA極大的提升了移動(dòng)端表現,改善了用戶(hù)體驗。

好消息是開(kāi)發(fā)一個(gè) PWA 并不難。事實(shí)上,我們可以將現存的網(wǎng)站進(jìn)行改進(jìn),使之成為PWA。這也是我這篇文章要講的 -- 當你讀完這篇文章,你可以將你的網(wǎng)站改進(jìn),讓他看起來(lái)就像是一個(gè) native web app。他可以離線(xiàn)工作并且擁有自己的主屏圖標。

Progressive Web Apps 是什么?

Progressive Web Apps (下文以“PWAs”代指) 是一個(gè)令人興奮的前端技術(shù)的革新。PWAs綜合了一系列技術(shù)使你的 web app表現得就像是 native mobile app。相比于純 web 解決方案和純 native 解決方案,PWAs對于開(kāi)發(fā)者和用戶(hù)有以下優(yōu)點(diǎn):

  1. 你只需要基于開(kāi)放的 W3C 標準的 web 開(kāi)發(fā)技術(shù)來(lái)開(kāi)發(fā)一個(gè)app。不需要多客戶(hù)端開(kāi)發(fā)。

  2. 用戶(hù)可以在安裝前就體驗你的 app。

  3. 不需要通過(guò) AppStore 下載 app。app 會(huì )自動(dòng)升級不需要用戶(hù)升級。

  4. 用戶(hù)會(huì )受到‘安裝’的提示,點(diǎn)擊安裝會(huì )增加一個(gè)圖標到用戶(hù)首屏。

  5. 被打開(kāi)時(shí),PWA 會(huì )展示一個(gè)有吸引力的閃屏。

  6. chrome 提供了可選選項,可以使 PWA 得到全屏體驗。

  7. 必要的文件會(huì )被本地緩存,因此會(huì )比標準的web app 響應更快(也許也會(huì )比native app響應快)

  8. 安裝及其輕量 -- 或許會(huì )有幾百 kb 的緩存數據。

  9. 網(wǎng)站的數據傳輸必須是 https 連接。

  10. PWAs 可以離線(xiàn)工作,并且在網(wǎng)絡(luò )恢復時(shí)可以同步最新數據。

現在還處在 PWA 的早期,但已經(jīng)有 很多成功案例 。

PWA 技術(shù)目前被 Firefox,Chrome 和其他基于Blink內核的瀏覽器支持。微軟正在努力在Edge瀏覽器上實(shí)現。Apple沒(méi)有動(dòng)作 although there are promising comments in the WebKit five-year plan。幸運的是,瀏覽器支持對于 PWA 似乎不太重要...

PWAs 是漸進(jìn)增強的

你的app仍然可以運行在不支持 PWA 技術(shù)的瀏覽器里。用戶(hù)不能離線(xiàn)訪(fǎng)問(wèn),不過(guò)其他功能都像原來(lái)一樣沒(méi)有影響。綜合利弊得失,沒(méi)有理由不把你的 app 改進(jìn)為 PWA。

不只是 Apps

Google 引領(lǐng)了 PWA 的一系列動(dòng)作,所以大多數教程都在說(shuō)如何從零開(kāi)始構建一個(gè)基于 Chrome,native-looking mobile app。然而并不是只有特殊的單頁(yè)應用可以PWA化,也不需要一定遵循 material interface design guidelines。大多數網(wǎng)站都可以在數小時(shí)內實(shí)現 PWA 化。這包括你的 WordPress站點(diǎn)或者靜態(tài)站點(diǎn)。

示例代碼

示例代碼可以在https://github.com/sitepoint-editors/pwa-retrofit找到。

代碼提供了一個(gè)簡(jiǎn)單的四個(gè)頁(yè)面的網(wǎng)站。其中包含一些圖片,一個(gè)樣式表和一個(gè)main javascript 文件。這個(gè)網(wǎng)站可以運行在所有現代瀏覽器上(IE10+)。如果瀏覽器支持 PWA 技術(shù),當離線(xiàn)時(shí)用戶(hù)可以瀏覽他們之前看過(guò)的頁(yè)面。

運行代碼前,確保 Node.js 已經(jīng)安裝,然后再命令行里啟動(dòng)服務(wù):

node ./server.js [port]

[port]是可配置的,默認為 8888。打開(kāi) Chrome 或者其他基于Blink內核的瀏覽器,比如 Opera 或者 Vivaldi,然后輸入鏈接 http://localhost:8888/(或者你指定的某個(gè)端口)。你也可以打開(kāi)開(kāi)發(fā)者工具看一下各個(gè)console信息。

瀏覽主頁(yè),或者其他頁(yè)面,然后用以下任一方法使頁(yè)面離線(xiàn):

  1. 按下 Cmd/Ctrl + C ,停止 node 服務(wù)器,或者

  2. 在開(kāi)發(fā)者工具的 Network 或者 Application - Service Workers 欄里點(diǎn)擊 offline 選項。

重新瀏覽任意之前瀏覽過(guò)的頁(yè)面,它們仍然可以瀏覽到。瀏覽一個(gè)之前沒(méi)有看過(guò)的頁(yè)面,你會(huì )看到一個(gè)專(zhuān)門(mén)的離線(xiàn)頁(yè)面,標識“you’re offline”,還有一個(gè)你可以瀏覽的頁(yè)面列表:

連接手機

你也可以通過(guò) USB 連接你的安卓手機來(lái)預覽示例網(wǎng)頁(yè)。在開(kāi)發(fā)者工具中打開(kāi) Remote devices 菜單。

在左邊選擇 Settings ,點(diǎn)擊 Add Rule 輸入 8888 端口。你可以在你的手機上打開(kāi)Chrome,打開(kāi) http://localhost:8888/。

你可以點(diǎn)擊瀏覽器菜單里的 “Add to Home screen”。瀏覽幾個(gè)頁(yè)面,瀏覽器會(huì )提醒你去安裝。這兩種方式都可以創(chuàng )建一個(gè)新的圖標在你的主屏上。瀏覽幾個(gè)頁(yè)面后關(guān)掉Chrome,斷開(kāi)設備連接。你依然可以打開(kāi) PWA Website app -- 你會(huì )看到一個(gè)啟動(dòng)頁(yè),并且可以離線(xiàn)訪(fǎng)問(wèn)之前你訪(fǎng)問(wèn)過(guò)的頁(yè)面。

將你的網(wǎng)站改進(jìn)為一個(gè) Progressive Web App 總共有三個(gè)必要步驟:

第一步:開(kāi)啟 HTTPS

由于一些顯而易見(jiàn)的原因,PWAs 需要 HTTPS 連接。

HTTPS 在示例代碼中并不是必須的,因為 Chrome 允許使用 localhost 或者任何 127.x.x.x 的地址來(lái)測試。你也可以在 HTTP 連接下測試你的 PWA,你需要使用 Chrome ,并且輸入以下命令行參數:

  • --user-data-dir

  • --unsafety-treat-insecure-origin-as-secure

第二步:創(chuàng )建一個(gè) Web App Manifest

manifest 文件提供了一些我們網(wǎng)站的信息,例如 name,description 和需要在主屏使用的圖標的圖片,啟動(dòng)屏的圖片等。

manifest文件是一個(gè) JSON 格式的文件,位于你項目的根目錄。它必須用Content-Type: application/manifest+json 或者 Content-Type: application/json 這樣的 HTTP 頭來(lái)請求。這個(gè)文件可以被命名為任何名字,在示例代碼中他被命名為 /manifest.json:

{  "name"              : "PWA Website",  "short_name"        : "PWA",  "description"       : "An example PWA website",  "start_url"         : "/",  "display"           : "standalone",  "orientation"       : "any",  "background_color"  : "#ACE",  "theme_color"       : "#ACE",  "icons": [    {      "src"           : "/images/logo/logo072.png",      "sizes"         : "72x72",      "type"          : "image/png"    },    {      "src"           : "/images/logo/logo152.png",      "sizes"         : "152x152",      "type"          : "image/png"    },    {      "src"           : "/images/logo/logo192.png",      "sizes"         : "192x192",      "type"          : "image/png"    },    {      "src"           : "/images/logo/logo256.png",      "sizes"         : "256x256",      "type"          : "image/png"    },    {      "src"           : "/images/logo/logo512.png",      "sizes"         : "512x512",      "type"          : "image/png"    }  ]}

在頁(yè)面的<head>中引入:

<link rel="manifest" href="/manifest.json">

manifest 中主要屬性有:

  • name —— 網(wǎng)頁(yè)顯示給用戶(hù)的完整名稱(chēng)

  • short_name —— 當空間不足以顯示全名時(shí)的網(wǎng)站縮寫(xiě)名稱(chēng)

  • description —— 關(guān)于網(wǎng)站的詳細描述

  • start_url —— 網(wǎng)頁(yè)的初始 相對 URL(比如 /

  • scope —— 導航范圍。比如,/app/的scope就限制 app 在這個(gè)文件夾里。

  • background-color —— 啟動(dòng)屏和瀏覽器的背景顏色

  • theme_color —— 網(wǎng)站的主題顏色,一般都與背景顏色相同,它可以影響網(wǎng)站的顯示

  • orientation —— 首選的顯示方向:any, natural, landscape, landscape-primary, landscape-secondary, portrait, portrait-primary, 和 portrait-secondary。

  • display —— 首選的顯示方式:fullscreen, standalone(看起來(lái)像是native app),minimal-ui(有簡(jiǎn)化的瀏覽器控制選項) 和 browser(常規的瀏覽器 tab)

  • icons —— 定義了 src URL, sizestype的圖片對象數組。

MDN提供了完整的manifest屬性列表:Web App Manifest properties

在開(kāi)發(fā)者工具中的 Application tab 左邊有 Manifest 選項,你可以驗證你的 manifest JSON 文件,并提供了 “Add to homescreen”。

第三步:創(chuàng )建一個(gè) Service Worker

Service Worker 是攔截和響應你的網(wǎng)絡(luò )請求的編程接口。這是一個(gè)位于你根目錄的一個(gè)單獨的 javascript 文件。

你的 js 文件(在示例代碼中是 /js/main.js)可以檢查是否支持 Service Worker,并且注冊:

if ('serviceWorker' in navigator) {  // register service worker  navigator.serviceWorker.register('/service-worker.js');}

如果你不需要離線(xiàn)功能,可以簡(jiǎn)單的創(chuàng )建一個(gè)空的 /service-worker.js文件 —— 用戶(hù)會(huì )被提示安裝你的 app。

Service Worker 很復雜,你可以修改示例代碼來(lái)達到自己的目的。這是一個(gè)標準的 web worker,瀏覽器用一個(gè)單獨的線(xiàn)程來(lái)下載和執行它。它沒(méi)有調用 DOM 和其他頁(yè)面 api 的能力,但他可以攔截網(wǎng)絡(luò )請求,包括頁(yè)面切換,靜態(tài)資源下載,ajax請求所引起的網(wǎng)絡(luò )請求。

這就是需要 HTTPS 的最主要的原因。想象一下第三方代碼可以攔截來(lái)自其他網(wǎng)站的 service worker, 將是一個(gè)災難。

service worker 主要有三個(gè)事件: install,activatefetch。

Install 事件

這個(gè)事件在app被安裝時(shí)觸發(fā)。它經(jīng)常用來(lái)緩存必要的文件。緩存通過(guò) Cache API來(lái)實(shí)現。

首先,我們來(lái)構造幾個(gè)變量:

  1. 緩存名稱(chēng)(CACHE)和版本號(version)。你的應用可以有多個(gè)緩存但是只能引用一個(gè)。我們設置了版本號,這樣當我們有重大更新時(shí),我們可以更新緩存,而忽略舊的緩存。

  2. 一個(gè)離線(xiàn)頁(yè)面的URL(offlineURL)。當離線(xiàn)時(shí)用戶(hù)試圖訪(fǎng)問(wèn)之前未緩存的頁(yè)面時(shí),這個(gè)頁(yè)面會(huì )呈現給用戶(hù)。

  3. 一個(gè)擁有離線(xiàn)功能的頁(yè)面必要文件的數組(installFilesEssential)。這個(gè)數組應該包含靜態(tài)資源,比如 CSS 和 JavaScript 文件,但我也把主頁(yè)面(/)和圖標文件寫(xiě)進(jìn)去了。如果主頁(yè)面可以多個(gè)URL訪(fǎng)問(wèn),你應該把他們都寫(xiě)進(jìn)去,比如//index.html。注意,offlineURL也要被寫(xiě)入這個(gè)數組。

  4. 可選的,描述文件數組(installFilesDesirable)。這些文件都很會(huì )被下載,但如果下載失敗不會(huì )中止安裝。

// configurationconst  version = '1.0.0',  CACHE = version + '::PWAsite',  offlineURL = '/offline/',  installFilesEssential = [    '/',    '/manifest.json',    '/css/styles.css',    '/js/main.js',    '/js/offlinepage.js',    '/images/logo/logo152.png'  ].concat(offlineURL),  installFilesDesirable = [    '/favicon.ico',    '/images/logo/logo016.png',    '/images/hero/power-pv.jpg',    '/images/hero/power-lo.jpg',    '/images/hero/power-hi.jpg'  ];

installStaticFiles()方法添加文件到緩存,這個(gè)方法用到了基于 promise的 Cache API。當必要的文件都被緩存后才會(huì )生成返回值。

// install static assetsfunction installStaticFiles() {  return caches.open(CACHE)    .then(cache => {      // cache desirable files      cache.addAll(installFilesDesirable);      // cache essential files      return cache.addAll(installFilesEssential);    });}

最后,我們添加install的事件監聽(tīng)函數。 waitUntil方法確保所有代碼執行完畢后,service worker 才會(huì )執行 install。執行 installStaticFiles()方法,然后執行 self.skipWaiting()方法使service worker進(jìn)入 active狀態(tài)。

// application installationself.addEventListener('install', event => {  console.log('service worker: install');  // cache core files  event.waitUntil(    installStaticFiles()    .then(() => self.skipWaiting())  );});

Activate 事件

當 install完成后, service worker 進(jìn)入active狀態(tài),這個(gè)事件立刻執行。你可能不需要實(shí)現這個(gè)事件監聽(tīng),但是示例代碼在這里刪除老舊的無(wú)用緩存文件:

// clear old cachesfunction clearOldCaches() {  return caches.keys()    .then(keylist => {      return Promise.all(        keylist          .filter(key => key !== CACHE)          .map(key => caches.delete(key))      );    });}// application activatedself.addEventListener('activate', event => {  console.log('service worker: activate');    // delete old caches  event.waitUntil(    clearOldCaches()    .then(() => self.clients.claim())    );});

注意,最后的self.clients.claim()方法設置本身為active的service worker。

Fetch 事件

當有網(wǎng)絡(luò )請求時(shí)這個(gè)事件被觸發(fā)。它調用respondWith()方法來(lái)劫持 GET 請求并返回:

  1. 緩存中的一個(gè)靜態(tài)資源。

  2. 如果 #1 失敗了,就用 Fetch API(這與 service worker 的fetch 事件沒(méi)關(guān)系)去網(wǎng)絡(luò )請求這個(gè)資源。然后將這個(gè)資源加入緩存。

  3. 如果 #1 和 #2 都失敗了,那就返回一個(gè)適當的值。

// application fetch network dataself.addEventListener('fetch', event => {  // abandon non-GET requests  if (event.request.method !== 'GET') return;  let url = event.request.url;  event.respondWith(    caches.open(CACHE)      .then(cache => {        return cache.match(event.request)          .then(response => {            if (response) {              // return cached file              console.log('cache fetch: ' + url);              return response;            }            // make network request            return fetch(event.request)              .then(newreq => {                console.log('network fetch: ' + url);                if (newreq.ok) cache.put(event.request, newreq.clone());                return newreq;              })              // app is offline              .catch(() => offlineAsset(url));          });      })  );});

最后這個(gè)offlineAsset(url)方法通過(guò)幾個(gè)輔助函數返回一個(gè)適當的值:

// is image URL?let iExt = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].map(f => '.' + f);function isImage(url) {  return iExt.reduce((ret, ext) => ret || url.endsWith(ext), false);}// return offline assetfunction offlineAsset(url) {  if (isImage(url)) {    // return image    return new Response(      '<svg role="img" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title>offline</title><path d="M0 0h400v300H0z" fill="#eee" /><text x="200" y="150" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="50" fill="#ccc">offline</text></svg>',      { headers: {        'Content-Type': 'image/svg+xml',        'Cache-Control': 'no-store'      }}    );  }  else {    // return page    return caches.match(offlineURL);  }}

offlineAsset()方法檢查是否是一個(gè)圖片請求,如果是,那么返回一個(gè)帶有 “offline” 字樣的 SVG。如果不是,返回 offlineURL 頁(yè)面。

開(kāi)發(fā)者工具提供了查看 Service Worker 相關(guān)信息的選項:

在開(kāi)發(fā)者工具的 Cache Storage 選項列出了所有當前域內的緩存和所包含的靜態(tài)文件。當緩存更新的時(shí)候,你可以點(diǎn)擊左下角的刷新按鈕來(lái)更新緩存:

不出意料, Clear storage 選項可以刪除你的 service worker 和緩存:

再來(lái)一步 - 第四步:創(chuàng )建一個(gè)可用的離線(xiàn)頁(yè)面

離線(xiàn)頁(yè)面可以是一個(gè)靜態(tài)頁(yè)面,來(lái)說(shuō)明當前用戶(hù)請求不可用。然而,我們也可以在這個(gè)頁(yè)面上列出可以訪(fǎng)問(wèn)的頁(yè)面鏈接。

main.js中我們可以使用 Cache API 。然而API 使用promises,在不支持的瀏覽器中會(huì )引起所有javascript運行阻塞。為了避免這種情況,我們在加載另一個(gè) /js/offlinepage.js 文件之前必須檢查離線(xiàn)文件列表和是否支持 Cache API 。

// load script to populate offline page listif (document.getElementById('cachedpagelist') && 'caches' in window) {  var scr = document.createElement('script');  scr.src = '/js/offlinepage.js';  scr.async = 1;  document.head.appendChild(scr);}

/js/offlinepage.js locates the most recent cache by version name, 取到所有 URL的key的列表,移除所有無(wú)用 URL,排序所有的列表并且把他們加到 ID 為cachedpagelist的 DOM 節點(diǎn)中:

// cache nameconst  CACHE = '::PWAsite',  offlineURL = '/offline/',  list = document.getElementById('cachedpagelist');// fetch all cacheswindow.caches.keys()  .then(cacheList => {    // find caches by and order by most recent    cacheList = cacheList      .filter(cName => cName.includes(CACHE))      .sort((a, b) => a - b);    // open first cache    caches.open(cacheList[0])      .then(cache => {        // fetch cached pages        cache.keys()          .then(reqList => {            let frag = document.createDocumentFragment();            reqList              .map(req => req.url)              .filter(req => (req.endsWith('/') || req.endsWith('.html')) && !req.endsWith(offlineURL))              .sort()              .forEach(req => {                let                  li = document.createElement('li'),                  a = li.appendChild(document.createElement('a'));                  a.setAttribute('href', req);                  a.textContent = a.pathname;                  frag.appendChild(li);              });            if (list) list.appendChild(frag);          });      })  });

開(kāi)發(fā)工具

如果你覺(jué)得 javascript 調試困難,那么 service worker 也不會(huì )很好。Chrome的開(kāi)發(fā)者工具的 Application 提供了一系列調試工具。

你應該打開(kāi) 隱身窗口 來(lái)測試你的 app,這樣在你關(guān)閉這個(gè)窗口之后緩存文件就不會(huì )保存下來(lái)。

最后,Lighthouse extension for Chrome 提供了很多改進(jìn) PWA 的有用信息。

PWA 陷阱

有幾點(diǎn)需要注意:

URL 隱藏

我們的示例代碼隱藏了 URL 欄,我不推薦這種做法,除非你有一個(gè)單 url 應用,比如一個(gè)游戲。對于多數網(wǎng)站,manifest 選項 display: minimal-ui 或者 display: browser是最好的選擇。

緩存太多

你可以緩存你網(wǎng)站的所有頁(yè)面和所有靜態(tài)文件。這對于一個(gè)小網(wǎng)站是可行的,但這對于上千個(gè)頁(yè)面的大型網(wǎng)站實(shí)際嗎?沒(méi)有人會(huì )對你網(wǎng)站的所有內容都感興趣,而設備的內存容量將是一個(gè)限制。即使你像示例代碼一樣只緩存訪(fǎng)問(wèn)過(guò)的頁(yè)面和文件,緩存大小也會(huì )增長(cháng)的很快。

也許你需要注意:

  • 只緩存重要的頁(yè)面,類(lèi)似主頁(yè),和最近的文章。

  • 不要緩存圖片,視頻和其他大型文件

  • 經(jīng)常刪除舊的緩存文件

  • 提供一個(gè)緩存按鈕給用戶(hù),讓用戶(hù)決定是否緩存

緩存刷新

在示例代碼中,用戶(hù)在請求網(wǎng)絡(luò )前先檢查該文件是否緩存。如果緩存,就使用緩存文件。這在離線(xiàn)情況下很棒,但也意味著(zhù)在聯(lián)網(wǎng)情況下,用戶(hù)得到的可能不是最新數據。

靜態(tài)文件,類(lèi)似于圖片和視頻等,不會(huì )經(jīng)常改變的資源,做長(cháng)時(shí)間緩存沒(méi)有很大的問(wèn)題。你可以在HTTP 頭里設置 Cache-Control 來(lái)緩存文件使其緩存時(shí)間為一年(31,536,000 seconds):

Cache-Control: max-age=31536000

頁(yè)面,CSS和 script 文件會(huì )經(jīng)常變化,所以你應該改設置一個(gè)很短的緩存時(shí)間比如 24 小時(shí),并在聯(lián)網(wǎng)時(shí)與服務(wù)端文件進(jìn)行驗證:

Cache-Control: must-revalidate, max-age=86400

譯自 Retrofit Your Website as a Progressive Web App

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Service Worker
開(kāi)發(fā)一個(gè)漸進(jìn)式Web應用程序(PWA)前都需要了解什么?
面向.NET開(kāi)發(fā)人員的Dapr——入門(mén)
Node.js基礎入門(mén)第四天
人們常說(shuō)的前端工程化到底是什么?
通過(guò)一個(gè)簡(jiǎn)單的 Node.js 文件上傳應用程序來(lái)了解 IBM Bluemix
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久