SINKCAPITAL
SINKCAPITAL
Comapny Blog
s3のhostingでPWAを導入する方法
tech

背景

ネイティブアプリのご要望が増えるとともにwebアプリとの違いを気にされるお客様も多かったため、 勉強の意味も兼ねてPWA(Progressive Web Apps)の実装を行いました。 PWA自体はwebアプリをネイティブアプリっぽく見せる技術ですが、 webサービスをまだ持っていなかったため今回は自社アプリをPWA化してみました。 (会社ページをスマホのホーム画面に登録するのはおそらく経営陣ぐらいなので全く実用性はないです...笑)
 自社アプリはAWS S3 Hostingを使っているので、S3 Hostingでの実装方法という形でお伝えします。 ウェブフレームワークを使用せず静的サイトを提供している場合は同様の方法で導入できるかと思います。

PWAの効果

 PWAの特徴を挙げると以下のような特徴があります。

  • ホーム画面に追加するとsafariを経由せずアプリのようにサイトを開くことができる
  • safariのようなURLヘッダーやフッターが存在せず画面全体を利用することができる
  • キャッシュを本体側に残せるためロードが早くなる

 弊社のサイトで言うとuikitやvuejsを導入している影響でサイトが遅かったので、 PWA化による影響が一番感じられたのは読み込みスピードでした。

実装方法

 基本的には こちらのページ を参考に作成させていただきました。 具体的に追加・変更したファイルは以下ディレクトリ構成において「<=」をつけている4ファイルです。

frontend
├── img
│   └── ...
├── index.html <=
├── js
│   ├── app.js <=
│   ├── sw.js <=
│   └── ...
├── manifest.json <=
└── ...

index.html

 元々ホーム画面追加時のアイコンなどは設定していたので、 headerに以下2行を追加するだけで適応することができました。

<link rel="manifest" href="/manifest.json">
<script src="/js/app.js"></script>

app.js

参考ページに載っていたものからパスを修正して作成しました。

if('serviceWorker' in navigator){
    navigator.serviceWorker.register('/js/sw.js')
        .then(reg => console.log('service worker registered'))
        .catch(err => console.log('service worker not registered', err));
}

ちなみに最初ここのパスを間違えてしまい、 エラー文も以下のようなわかりづらいものが出るためしばらくハマっていました。 エラー文の解釈としてはおそらく存在しないパスを参照してerror.htmlが返されたことにより出ていたのだと思われます。

Uncaught (in promise) DOMException: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html').

sw.js

 こちらは参考ページに載っていたものにキャッシュするファイルを追加して作成しました。 cdnで読み込んでいるものもキャッシュできるのでとても便利です。

const staticCacheName = 'site-static-v1';
const assets = [
    '/',
    '/index.html',
    '/js/settings.js',
    '/js/particles.min.js',
    '/img/small/home-bg.jpg',
    '/img/medium/home-bg.jpg',
    '/img/large/home-bg.jpg',
    '/img/logo/meiko.jpg',
    '/img/service/db_consultant.jpg',
    '/img/service/it_consultant.jpg',
    '/img/service/taskcross.png',
    '/img/service/tsumiki.png',
    '/img/sinkcapital_logo.png',
    '/img/supportCase/aws.jpg',
    '/img/supportCase/education.jpg',
    '/img/supportCase/ga.jpg',
    '/img/supportCase/gcp.jpg',
    'https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js',
    'https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.3/css/uikit.min.css',
    'https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.3/js/uikit.min.js',
    'https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.3/js/uikit-icons.min.js',
    'https://code.jquery.com/jquery-2.2.3.min.js',
    'https://fonts.googleapis.com/css?family=Lato:400,700|Noto+Sans+JP:400,700',
];
// install event
self.addEventListener('install', evt => {
    evt.waitUntil(
        caches.open(staticCacheName).then((cache) => {
            console.log('caching shell assets');
            cache.addAll(assets);
        })
    );
});
// activate event
self.addEventListener('activate', evt => {
    evt.waitUntil(
        caches.keys().then(keys => {
            return Promise.all(keys
                .filter(key => key !== staticCacheName)
                .map(key => caches.delete(key))
            );
        })
    );
});
// fetch event
self.addEventListener('fetch', evt => {
    evt.respondWith(
        caches.match(evt.request).then(cacheRes => {
            return cacheRes || fetch(evt.request);
        })
    );
});

manifest.json

こちらは参考ページに載っていたコードからアイコンの部分だけ修正して作成しました。

{
  "name": "Sink Capital",
  "lang": "ja",
  "short_name": "SinkCapital",
  "start_url": "/index.html",
  "display": "standalone",
  "background_color": "#F4F4F4",
  "theme_color": "#F4F4F4",
  "orientation": "portrait-primary",
  "icons": [
    {
      "src": "/img/apple-touch-icon.png",
      "type": "image/png",
      "sizes": "180x180"
    }
  ]
}

感想

 PWAの対応は様々な記事が出ておりほぼコピペで対応できたのでとても楽でした。 自社サイトをPWA化したメリットはほぼ何もないですが、 PWA化によるサイト読み込みスピードの変化は実感することができました。 主にvuejsやuikitのcdnを読み込むスピードが爆速化していました。 アプリとの対比でいうとアプリっぽいUIを作れるのであれば、 PWAでも全然問題なく対応できそうでした。 もし機会があれば次はアプリっぽい見た目のPWAサイトを作成してみようと思います。

参考リンク

Nuxt上でのd3を利用した散布図の作成方法
櫻井 裕司
2021/10/29 櫻井 裕司
techdataAnalytics
クリック可能な散布図をNuxtjs上で作成する場合にd3.jsが汎用性が高く便利でした。利用するにあたって難しかった点などを備考録としてまとめています。
アクセスログを可視化しGAのデータを直感的に理解できる型態にする試み(ネットワーク型)
櫻井 裕司
2021/09/05 櫻井 裕司
techdataAnalytics
ビジネスに活きる分析を進める上で弊社では「理解できる」ことを重要と考えており、特に直感的理解は可視化を進める上で特に重要だと考える内容の一つです。弊社では様々なお客様のデータ分析を進める上で常により示唆の大きい可視化を追求しており、今回はその中で最近試みているネットワーク側の可視化についてまとめたいと思います。
代表櫻井による特別講演会が白陵高等学校で開かれました
櫻井 裕司
2021/07/31 櫻井 裕司
eventpersonal
2021年の夏に兵庫県の私立白陵高等学校において、代表櫻井による特別講演会を開催いたしました。今振り返って高校の頃の自分に伝えたいことについてお話しました。
Nuxtで動的ページを随時追加する場合にNot Foundとなる
櫻井 裕司
2021/05/31 櫻井 裕司
tech
Nuxtで動的ページを登録する方法はありますが、登録後に随時コンテンツが追加される際はNot Foundとなってしまうので、そう言った際の対処方法について
GKEをやめてCloud Runを始めてみました
櫻井 裕司
2021/04/19 櫻井 裕司
tech
firebaseで構築したシステムの裏で動かすバッチの負荷が大きく、cloud functionsで終わらなかったためCloud Runを利用してみました。動作確認までの知見等を雑多にまとめてみました。
AWSをやめてfirebaseを使い始めて感じたメリットやデメリットとそれの対応策(LT登壇内容)
櫻井 裕司
2021/03/26 櫻井 裕司
techeventpersonal
みそかつウェブ・GDG Nagoya主催の「around firebase」とCloud Native Nagoya主演の「Cloud Native Nagoya」にてfirebaseのLTをさせていただきました。そこで会話させていただいたfirebaseを使い始めて感じたメリット・デメリットについてまとめています。
PWA+SPAのwebアプリ作成にnuxtjs+firebaseがめちゃ便利だった
櫻井 裕司
2021/01/16 櫻井 裕司
tech
PWA+SPAのwebアプリを作る際にnuxt.js+firebaseを合わせて利用すると便利だったので知見を書き留めています
dockerでseleniumを動かしてみる(chrome_headless)
櫻井 裕司
2020/12/06 櫻井 裕司
tech
seleniumの相談をいただくことが増えたため、seleniumの勉強もかねてdockerでの実行テストを行いました
THE DECKのイベントにお邪魔させていただきました
本林 秀和
2020/12/05 本林 秀和
eventpersonal
大学コンソーシアム大阪のイベント@The DECK にお邪魔してきました
flutter(dart)を触ってみた感想
櫻井 裕司
2020/11/18 櫻井 裕司
tech
android向けアプリへの対応も考慮してflutter(dart)を触ってみたので、感想をまとめておこうと思います。理解が深まっていく中で定期的にまとめていければと思います。
代表本林による特別講演会が滝高校で開かれました
本林 秀和
2020/11/07 本林 秀和
eventpersonal
2020年11月7日(土)愛知県の私立滝高校において、代表本林による特別講演会を開催いたしました。IT業界やデータサイエンスについてお話しました。
AWS・GCPを選ぶ際の観点
櫻井 裕司
2020/10/28 櫻井 裕司
tech
AWSかGCPを選ぶ際の観点について書き留めておこうと思います
CloudFormationとterraformの比較
櫻井 裕司
2020/10/04 櫻井 裕司
tech
AWS CloudFormationとterraformの両方を使ってみて感じた違いをまとめてみました。
iosのcallkit周りでできること
櫻井 裕司
2020/08/24 櫻井 裕司
tech
新規事業を検討する上でios(swift)の電話周りでできることを調査したため、調査結果をブログとして残しています。
【個人ブログ】CTOの株運用ブログ_順調な滑り出し
櫻井 裕司
2020/07/19 櫻井 裕司
personalstock
長年放置してた株に少し手を出してみました。自分なりに少し情報整理と分析と予想をしたので記事にしてみます。
総務省特定サービス産業実態調査のデータ分析
櫻井 裕司
2020/07/18 櫻井 裕司
techdataAnalytics
総務省がAPIで市場データを公開しており、分析技術向上と市場感を養うことを目的に定期的に分析を行なっていこうと思います。今回は「特定サービス産業実態調査」について見ていこうと思います。
「お絵かきつみ木バトル」をリリースしました
櫻井 裕司
2020/07/12 櫻井 裕司
techapp
タスク管理を二次元的に行うアプリ「お絵かきつみ木バトル」をリリースしました。SinkCapitalはデータコンサルですが、知見蓄積のため様々な媒体での実験的開発を行っています
総務省工業統計調査のデータ分析
櫻井 裕司
2020/07/11 櫻井 裕司
techdataAnalytics
総務省がAPIで市場データを公開しており、分析技術向上と市場感を養うことを目的に定期的に分析を行なっていこうと思います。今回は「工業統計調査」について見ていこうと思います。
【個人ブログ】CTOが個人的に株をはじめました
櫻井 裕司
2020/07/08 櫻井 裕司
personalstock
長年放置してた株に少し手を出してみました。自分なりに少し情報整理と分析と予想をしたので記事にしてみます。
総務省サービス産業動向調査のデータ分析
櫻井 裕司
2020/07/08 櫻井 裕司
techdataAnalytics
総務省がAPIで市場データを公開しており、分析技術向上と市場感を養うことを目的に定期的に分析を行なっていこうと思います。初回は「サービス産業動向調査」について見ていこうと思います。
タスク管理アプリ「タスククロス」をリリースしました
櫻井 裕司
2020/04/08 櫻井 裕司
techapp
タスク管理を二次元的に行うアプリ「タスククロス」をリリースしました。SinkCapitalはデータコンサルですが、知見蓄積のため様々な媒体での実験的開発を行っています
【terraform】gcpでcicd環境を構築する方法
櫻井 裕司
2020/01/04 櫻井 裕司
tech
企業サイトはAWSを利用しているのですが、要件によってはGCPの方が適している場合もあるため、GCPでのcicd構築も行いました。AWSと比較しつつ説明しているため是非ご参考にしてみてください。
【合格体験記】GCP_Cloud_Archtectに受かりました
櫻井 裕司
2019/12/23 櫻井 裕司
personalqualification
Google Professional Cloud Architectに合格したので、勉強法別のコスパをまとめてみました。
AWSでサブドメインなし(wwwなし)からサブドメインあり(wwwあり)へのリダイレクト設定
櫻井 裕司
2019/12/23 櫻井 裕司
tech
もともと企業サイトがサブドメインありで公開していたが、サブドメインなしでもエラーなく接続できるように設計。terraformで作成しているので是非ご参考ください。
マークダウンで記事を書けるようにしてみた
櫻井 裕司
2019/12/16 櫻井 裕司
tech
ホームページのブログをマークダウンを使用してかけるようにしました。gatsbyなどもありますが、今回はお手製cicd+pythonを使用してライトに作成しました。