TL;DR

Next.jsのPWA対応というとnext-offlineとかnext-pwaが有名かと思います。しかし、AMPページのキャッシュはこれらがデフォルトで対応していないので、自前でやる必要があります(参考issue)。自分はこの2つのパッケージを使って色々やってて永遠にPWA対応できなかったので、AMPと同時に対応しようとしている人は注意が必要です。

とはいえ、やることはほとんどexample/amp-firstをコピペするだけなのですが...。

publicフォルダの準備

manifest.json

まず、manifest.jsonを用意します。何で用意してもいいですが、必要なものとして以下が挙げられます(参考)。iconとか用意するのはめんどうなので、PWA manifest generatorを使いました。

  • start_url
  • name or shortname
  • icons (192 - 512 px)
  • display

また、このiconはmaskableである必要があるので、Maskable.app Editorで変換した後、"purpose": "any maskable"をiconのプロパティに足します。

とりあえずこのサイトのmanifest.jsonは以下のような感じです。

manifest.json
{
    "name": "illumination-k dev",
    "theme_color": "#f69435",
    "background_color": "#f69435",
    "display": "standalone",
    "start_url": "/",
    "icons": [
        {
            "src": "/icons/icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png",
            "purpose": "any maskable"
        },
        {
            "src": "/icons/icon-256x256.png",
            "sizes": "256x256",
            "type": "image/png",
            "purpose": "any maskable"
        },
        {
            "src": "/icons/icon-384x384.png",
            "sizes": "384x384",
            "type": "image/png",
            "purpose": "any maskable"
        },
        {
            "src": "/icons/icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png",
            "purpose": "any maskable"
        }
    ],
    "short_name": "ik.dev",
    "description": "Homepage of illumination-k"
}

apple touch icon

ここを見てもらったほうが早いですが、PWA対応したいページのヘッダーに

<link rel="apple-touch-icon" href="/icons/icon-192x192.png" />

を加えておきます。アイコンのサイズは192x192か180x180である必要があります。

serviceworker.js

examples/amp-first/public/serviceworker.jsをコピペしてpublicに置きます。たぶん、だいたいamp-swです。

serviceworker.js
/* global importScripts, AMP_SW */
importScripts('https://cdn.ampproject.org/sw/amp-sw.js')

/*
  This configures the AMP service worker to enhance network resiliency and
  optimizes asset caching. This configuration will:
  - Cache AMP scripts with a stale-while-revalidate strategy for a longer duration
    than the default http response headers indicate.
  - Cache valid visited AMP documents, and serve only in case of flaky network conditions.
  - Cache and serve an offline page.
  - Serve static assets with a cache first strategy.
  Checkout https://github.com/ampproject/amp-sw/ to learn more about how to configure
  asset caching and link prefetching.
*/
AMP_SW.init({
  assetCachingOptions: [
    {
      regexp: /\.(png|jpg|woff2|woff|css|js)/,
      cachingStrategy: 'CACHE_FIRST', // options are NETWORK_FIRST | CACHE_FIRST | STALE_WHILE_REVALIDATE
    },
  ],
  offlinePageOptions: {
    url: '/offline',
    assets: [],
  },
})

serviceworkerのregister

examples/amp-first/public/install-serviceworker.htmlをコピペしてpublicに置きます。

install-serviceworker.html
<!DOCTYPE html>
<title>installing service worker</title>
<script type="text/javascript">
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/serviceworker.js')
  }
</script>

PWA対応したいページでserviceworkerをインストールする

ampではserviceworkerのインストールはamp-install-serviceworkerで行えます。

PWA対応したいコンポーネントのbodyに以下を入れます。

<amp-install-serviceworker
    src="/serviceworker.js"
    data-iframe-src="/install-serviceworker.html"
    layout="nodisplay"
/>

offlineページの作成

これよくわかってないので後で調べるかもしれませんが、amp-firstの例ではofflineページが準備されています。コピペして置いておきましょう。serviceworkerのofflinePageOptionなんでしょう。

offline.js
import Layout from '../components/Layout'

export const config = { amp: true }

const Home = () => (
  <Layout>
    <h1>Offline</h1>
    <p>Please try again later.</p>
  </Layout>
)

export default Home

結果

以上でPWA対応は完了です。当サイトtopの2020/09/30現在のlighthouse performanceです。

lighthouse-next-blog

ちなみにWordpress時代はこんなんなので、非常に成長していると言えるでしょう。all 100は難しいですね...。

記事に間違い等ありましたら、お気軽に以下までご連絡ください

E-mail: illumination.k.27|gmail.com ("|" replaced to "@")

Twitter: @illuminationK

当HPを応援してくれる方は下のリンクからお布施をいただけると非常に励みになります。

Ofuse

Other Articles

Privacy Policy

Copyright © illumination-k 2020-2021.