我如何在15分鐘內開發了Nothing PWA
Tags: pwa, web, netlify
Published: 2018-12-19 03:35:35

---
title: 我如何在15分鐘內開發了Nothing PWA
published: true
description: 看看我如何在15分鐘內將一個19MB的應用程序縮小到205KB。
cover_image: https://i.imgur.com/PVmTXL1.jpg
tags: pwa, web, netlify 
---

> 英文版 (English Version): [Zero to 15 — Building a Nothing PWA in 15 mins](https://dev.to/henrylim96/zero-to-15--building-a-nothing-pwa-in-15-minutes-258j)

## 什麼是 Nothing?
![](https://cdn-images-1.medium.com/max/1600/1*XZkZE7VkNnfQ5q18LpMBow.jpeg)

原版的“[Nothing](https://play.google.com/store/apps/details?id=com.gorro.nothing)” Android 應用程序是由Chilango Lab所開發的。這應用程序在Google Play 商店已經突破了一百萬下載了， 並有高達4.2顆星星的高評價🎉 。

而這Android版的Nothing應用，其實也沒有什麼功能。但是這應用裡卻又一個非常獨特的彩蛋 ( ͡° ͜ʖ ͡°).

話說如此，這Android版的Nothing應用程序大小卻是14MB。更慘的是，在安裝後卻佔據了19.24MB。這讓我突發奇想，我有什麼辦法能縮小這個應用程序的大小呢？

![](https://thepracticaldev.s3.amazonaws.com/i/5jnvpxtc0e1jrp10a194.png)
*(左圖) Nothing Android 應用: 19.24MB — (右圖) Nothing 漸進式網頁應用: 205KB*

解決方法是非常的簡單。我可以使用HTML, CSS, 和 JavaScript來縮小應用程序的大小。但是，我可以將它帶到更高的水平，那就是將它提升成漸進式網頁應用(PWA)。這樣，用戶能在沒有互聯網的情況之下使用，並還是可以正常地使用，同時也能將這PWA添加到主頁。

## 👩🏻‍🎨 Icon 設計

在我開始深入討論前，讓我先為這個Nothing PWA設計一個*美麗*的icon。

我今天所使用的工具是叫[Launcher Icon Generator](https://romannurik.github.io/AndroidAssetStudio/icons-launcher.html)。這是由一名叫[Roman Nurik](https://twitter.com/romannurik)的谷歌員工所開發的[開源工具](https://github.com/romannurik/AndroidAssetStudio)。

![](https://cdn-images-1.medium.com/max/1400/1*IlOsAMmxr7AUcq2K5maV9Q.png)

我在超短的時間裡，使用了Launcher Icon Generator來設計了一個非常漂亮的icon(見上圖)。

此外，這個工具也會自動地講icon導出到不同的大小: 48px, 72px, 96px, 144px, 192px 以及 512px。這功能提供了極大的方便。

## PWACompat

好的，我已經將icon設計好了，下一步就是icon放進網頁裡。

首先，我先創建一個新的[Web App Manifest](https://developers.google.com/web/fundamentals/web-app-manifest/)文件，並將icon的資料、應用的名字、主題顏色、等等寫在manifest.json文件中。這樣的話，Android版的Chrome將會在這PWA啟動時，會自動地顯示啟動畫面。

但是不是每個游覽器都支持這啟動畫面的功能。我要怎樣做才可以將這個功能帶到全部游覽器呢？

讓我來介紹[PWACompat](https://github.com/GoogleChromeLabs/pwacompat)，PWACompat是一個能將Web App Manifest的功能帶到不支持Web App Manifest的瀏覽器的工具庫。這一來，這能將漸進式網頁應用(PWA)的功能帶到更多的瀏覽器。

這PWACompat非常容易地使用，您只需要在你的代碼中加入Web App Manifest (`manifest.json`)以及PWACompat (`pwacompat.min.js`) 即可 (見以下的代碼)。

```
<link rel="manifest" href="manifest.json" />
<script async src="https://cdn.jsdelivr.net/npm/pwacompat@2.0.6/pwacompat.min.js"
    integrity="sha384-GOaSLecPIMCJksN83HLuYf9FToOiQ2Df0+0ntv7ey8zjUHESXhthwvq9hXAZTifA"
    crossorigin="anonymous"></script>
```

![](https://thepracticaldev.s3.amazonaws.com/i/59vmpvldy9p74bt0wio7.gif)
*在Safari中的啟動畫面 (iOS)*

就這樣，我成功地將PWA啟動畫面帶到了舊游覽器 (以上的例子是iOS的Safari)。但是這不是PWACompat全部的功能，PWACompat的功能是比你想像中還要多喔。

就讓我看看PWACompat有什麼其他的功能:

— 根據Manifest文件中的icon資料，自動地在`<head>`中添加icon meta標籤 (以及favicon)

— 根據Manifest文件中的`theme_color` 属性，自動地在`<head>`中添加主題顏色的meta標籤

— 等等

## 🏠 添加到主屏幕

這是我在漸進式網頁應用中最喜歡的功能了，那就是添加到主屏幕(A2HS)。但是，在Chrome 68之後，[Chrome將會顯示一個比較小個的迷你信息欄，來取代之前的比較大個的安裝橫幅](https://developers.google.com/web/updates/2018/06/a2hs-updates)：

![](https://cdn-images-1.medium.com/max/800/1*3GwP3kbKBFSedyTaI4NWZQ.png)
*😵 再見了，網絡應用安裝橫幅 (Chrome 67 前)*

儘管如此，這個迷你信息欄也是一個暫時性的解決方案，這將會在未來的Chrome更新中去除。因此，我需要使用一個更好的添加到主屏幕的UX。

![](https://thepracticaldev.s3.amazonaws.com/i/gv6errto96fbkd8blotl.png)
*(左圖) 安裝按鈕 — (中圖) 安裝按鈕 + A2HS 迷你信息欄 — (右圖) A2HS 對話框*

如果游覽器支持添加到主屏幕的功能，這將會在網頁上方顯示一個“安裝”按鈕。當用戶點擊安裝按鈕，網頁就會顯示A2HS對話框 (見以下的代碼)。

```

var installPromptEvent;
var btnInstall = document.querySelector('#install');

window.addEventListener('beforeinstallprompt', function (event) {
    event.preventDefault();
    installPromptEvent = event;
    btnInstall.removeAttribute('disabled');
});

btnInstall.addEventListener('click', function () {
    btnInstall.setAttribute('disabled', '');
    installPromptEvent.prompt();
    installPromptEvent.userChoice.then((choice) => {
        if (choice.outcome === 'accepted') {
            console.log('User accepted the A2HS prompt');
        } else {
            console.log('User dismissed the A2HS prompt');
        }
        installPromptEvent = null;
    });
});
```
*如果網頁符合了添加到主屏幕的條件，游覽器將會發動“beforeinstallprompt”的事件(event)*

## 🥚 彩蛋

![](https://cdn-images-1.medium.com/max/1000/1*ePTthP8JcXDteH9p7G8gqQ.jpeg)
*Spoiler Alert !!!*

這是Nothing PWA裡的彩蛋: 科拿米秘技 (Konami Code) + [10 個小時的YouTube視頻](https://twitter.com/Nick_Craver/status/720062942960623616)。

![](https://cdn-images-1.medium.com/max/600/1*9f-Coe9dfwz_UmlsTUmHjA.gif)
*⬆️⬆️⬇️️⬇️⬅️➡️⬅️➡️👆🏻👆🏻*

當用戶成功的完成了科拿米秘技，這Nothing PWA將會把用戶轉載到這個非常特別的[YouTube視頻](https://stackoverflow.com/admin.php)。

在這Nothing PWA中，我是使用了這[Konami-JS](http://snaptortoise.github.io/konami-js/)。我選擇使用這個的原因是因為它的文檔非常小，而且非常容易的使用。

並且如此，這Konami-JS也支持了手機。而唯一的分別是這科拿米秘技會從“`上,上,下,下,左,右,左,右,B, A`” 變成 “`上,上,下,下,左,右,左,右,點擊,點擊`”。

## 拉動刷新

就在這時，我發現到了一個小問題。若是用戶是使用著手機或是使用觸碰螢幕時，當他們在往下滑的時候，就會不小心刷新到網頁。

![](https://cdn-images-1.medium.com/max/800/1*cDXJ33JdnhzIUfzy8R_14g.gif)

我應該要怎樣解決這個問題呢？

好消息是，我可以使用`overscroll-behavior-y: contain`來避免拉動刷新網頁。

就這樣，問題解決了!

## ☁️ 網頁託管

這Nothing PWA是部署在Netlify上。

### 什麼是Netlify呢？

Netlify是一個功能非常完整的前端網頁託管平台。而這次我選擇使用Netlify的原因十分簡單，那就是Netlify非常的容易使用，而且Netlify是可以免費使用的！

![](https://cdn-images-1.medium.com/max/1200/1*xLFM3ifLVb5X63Nj7XZHUw.png)
*Netlify Dashboard*

如果您要將您的網頁部署到Netlify的話，您有3個辦法: 使用命令行工具、手動部署、或者是使用持續部署。

#### 命令行工具 (CLI)

這是部署網站最普遍的方式了。將Netlify命令行工具安裝到您的電腦，登錄到您的Netlify，初始化項目， 然後您就能將您的網站部署到Netlify了。

```
> brew tap netlify/netlifyctl 
> brew install netlifyctl
> netlifyctl login
> netlifyctl init
> netlifyctl deploy
```

#### 手動部署

這個方法是Netlify最簡單的部署網頁的方式: 拖放部署 (Drag and Drop)。

![](https://cdn-images-1.medium.com/max/1600/1*8eB2dwalDXgHBHR4Pm83Iw.png)

通過這個方式，開發者只需要將網頁的文件夾拖放進去Netlify的網站就可以了。這個功能非常酷，這讓我希望Firebase能在Firebase Hosting中添加這個功能。

#### 持續部署 (Continuous Deployment)

這Nothing PWA我是使用持續部署來自動的講網頁部署到Netlify。

當我的GitHub項目連接到Netlify後，只要我將代碼push到GitHub時，Netlify就會自動地將網頁部署到Netlify。這自動部署，提供了自動更新的功能真是非常的方便!

### 🔒 HTTPS!
由於漸進式網頁應用的其中一個必要條件是來自安全的 origin, 所以我必須確保這網頁是有正确地实施HTTPS。

好消息是Netlify提供了免費的HTTPS給大家，這也包括了自定義域名。

![](https://cdn-images-1.medium.com/max/1000/1*cu1Zs1B4ziZFkJVXj7lwTA.png)

Netlify也提供了一個非常棒的功能，那就是HSTS ([HTTP Strict Transport Security](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security))。啟動後，您的網頁將會強制性地被轉載到HTTPS版。這可以確保網頁是一直在HTTPS的情況下運行。

## 💡Lighthouse
[Lighthouse](https://developers.google.com/web/tools/lighthouse/)是一個開源的自動化工具，用於改進網絡應用的質量。您可以使用Lighthouse來分析網頁的性能，SEO，等等。您可以根據Lighthouse報告來研究如果將您的網頁變到更好。

![](https://cdn-images-1.medium.com/max/1600/1*85AX9Hs1Tty316wkADoifQ.png)


欸不錯哦? 我成功了在performance拿到97分，及PWA, accessibility, best practices 和 SEO都拿到了滿分100。 🔥

您可以在這裡查看完整的Lighthouse報告: [https://builder-dot-lighthouse-ci.appspot.com/report.1533954675085.html](https://builder-dot-lighthouse-ci.appspot.com/report.1533954675085.html)

## 🎉 嘗試看看

![](https://cdn-images-1.medium.com/max/800/1*hA7rq9gWv2ea6UEIwMIDOw.gif)

就這樣，我成功了地在15分鐘內將一個19MB的Android應用程序轉換成一個漸進式網頁應用，並將應用縮小到205KB！🎉

🚀 您可以在這裡嘗試Nothing PWA: [nothing.limhenry.xyz](https://nothing.limhenry.xyz)

這PWA的代碼可以在GitHub上找到: [github.com/limhenry/nothing](https://github.com/limhenry/nothing)