よく分かってなくてもNuxt.jsでPWAが作れた話
この記事はPWA Advent Calendar 2018の6日目の記事になります。
既視感のあるタイトルですが気にしないでください。
毎年何かしら自分のレベルに合わせて新技術に触れてみる・作ってみるみたいなのを課してるのですが、
今年個人的にチャレンジしてみようと思ったものの1つにPWAがあります。
そこで今回は大した知識が無くともPWAを作ることができた話をしようと思います。
内容として他の皆様と大したことやってないかもですが、こんなんでも形になったぞというのを知ってもらいたいのもあるので温かい目で見てくださいませ。
Reading…
Link: https://reading.yamanoku.net
GitHub: https://github.com/yamanoku/reading/
日頃自分が見ているニュースを集約してまとめてみたらどうなるだろうか、情報の蓄積・可視化みたいなのを考えておりそういうのができないかなと思ってそれを題材にPWAにしてみようと思いました。以下は経緯みたいなやつです。
動作イメージ
自分が最近見た20件のニュース×5ページ分にした計100件を表示。
ページ間はページネーションで動きます。
使用技術
API | ホスティング | フレームワーク |
---|---|---|
Slack API AWS API GateWay |
Netlify | Nuxt.js |
Nuxt.jsのプラグイン・モジュールは以下を使用
-
vue-paginate
- ページネーション。asyncもあって複数で連携できたり、
- 個人的には色々あるページネーションの中で導入が簡単(な印象)
-
nuxt-community/pwa-module
- 皆様ご存知のNuxt.jsでPWAにするなら必要になる
- PWAにしなくともキャッシュ高速化にも使える
あと当初はNuxt1.0で作成していましたが、今年の2.0の発表に合わせてアップデートしました。
Nuxt 2でgenerateしたPWAサイトです
https://twitter.com/yamanoku/status/1043119076489318401
フローチャート
図です。
-
投稿自体はTwitter
- シェアする内容の文頭に
Reading...
とつけてツイート - 別に「Reading」じゃなくてもいいけど、昔使ってたニュースアプリの名残で自発的にやってる
- 主な発言地帯がTwitterなだけなので、別にIFTTTと連携できるならなんでもいい
- シェアする内容の文頭に
-
DBは個人用Slack
- IFTTTで投稿連携
- Slack APIの制約もあり100件までを抽出。古いものは取得内から消えていく。
- なぜSlackをデータベースにしたのか?
- お手軽サーバーレス体験
- Slack側のメッセージの修正や消去で即JSONに反映してくれる
- 無料で作れて垢バンの心配がない
- Twitter単体だと心配
- 日経の米朝首脳会談の速報ページで前例あり
-
AWSでAPI GatewayとLambda FunctionにてAPI変換
- Slack APIから直接経由だと制約があってしんどかった
- 変えてよかったこと
- tokenを完全隠蔽した
- CORS対応したのでどこでも取得できる
- gzip配信もできる
- 今のところは自分用なのもあって無料枠で収まる内容になってる
-
Netlify Meetup Tokyo #2で
Netlify Functions
でもいけそうって話を@mottox2さんから聞けたのでNetlify内で完結できる方向に変えようかと考え中
-
Netlifyでホスティング
- GitHubリポジトリと紐づけてる
-
nuxt generate
&push-dir --dir=dist --branch=master --cleanup
- 静的書き出しした
dist
をmaster
ブランチにプッシュ -
master
ブランチをホスティング - SSL化やらカスタムドメイン可やらプレレンダリング(今回は未使用)やら無料でやってくれてすごい。
- あとプライベートリポジトリも使える。
パフォーマンス
lighthouse
- Device: Emulated Nexus 5X
- Network throttling: 150 ms TCP RTT, 1,638.4 Kbps throughput (Simulated)
- CPU throttling: 4x slowdown (Simulated)
上記設定で計測。Perfomance部分は変動ある感じですがだいたいこんな感じ
2018/9/6 計測
2018/12/2 計測
WebPageTest
- From: Tokyo, Japan - EC2 - Chrome - Cable
上記設定で計測。
2018/9/6 計測
https://www.webpagetest.org/result/180905_90_60fd3b52c101b6aaeb61fda8ac192468/
2018/12/2 計測
https://www.webpagetest.org/result/181202_Q9_0b087ea9b135cf3ee5e8c790e07853a7/
Fixed & Updates
あんまりPWA要素と関係ないかもですが、更新したことなど。
ページネーションをクリックするとスクロール位置が保存されたままになってる
- 中間くらいまでスクロールした状態で移動するとページ間でその位置のまま
-
position: fixed
とvh
を使っているせい
-
- ページが切り替わったときの制御に
scrollTop
をかませた
methods: {
onPageChange() {
document.getElementsByClassName('news-list')[0].scrollTop = 0;
}
}
<paginate-links
for="lists"
@change="onPageChange" <!-- ここ -->
:show-step-links="true"
:limit="2">
</paginate-links>
絵文字がパースされていない
単純にパースしてあげればいいのかなと思ったので、
node-emoji を使いました。
👍👍👍👍👍
ナイトモード実装
21時〜翌6時までの間は自動的に適応するようにしています。
ただカラーをナイトモード用に自制したというよりかは filter: invert(100);
を使って
色反転させただけという超シンプルナイトモードです。
export default {
mounted() {
if((new Date()).getHours() >= 21 || (new Date()).getHours() < 6 ) {
document.body.className += "night-mode";
}
},
}
.night-mode {
animation: night 2s ease 0s 1 normal;
animation-fill-mode: forwards;
background-color: #fff;
}
@keyframes night {
0% {filter:invert(0);}
100% {filter:invert(100);}
}
ちなみに、Vue.jsでhtml
とかbody
をマウントするのよくないらしいです。
与えられた要素は単にマウントするポイントとして機能します。Vue 1.x とは異なり、マウントされた要素は、全てのケースで Vue によって生成された DOM に置き換えられます。
従って、ルートインスタンスを<html>
または<body>
にマウントすることは推奨されません。
https://jp.vuejs.org/v2/api/index.html#el
ページネーションのボタンアクセシビリティ対応
今回ページネーションのライブラリで使用したvue-paginateですが、<a>
タグのみでhref
で明確なリンク遷移が明示されていない、リンクとして未完成な状態のままでした。
また、tabindex
指定もないのでタブキーでのフォーカスも効かない状態でした。
そこでページネーションのボタン部分をリンク要素としてではなくbutton
タグに変更して、意味あるタグを設置・タブにおけるフォーカスの両方を解消しようと思いました。
ただ、この内容についてIssueで報告する・プルリクエストを提出することを考えた時、個人での運用なのでいつ見てもらえるか・かつ受け入れられるかもわからないという不安がありました。
そこで、リポジトリをforkして自分専用用のモジュールを作ったほうが早いと感じたので、早速対応しました。
https://github.com/yamanoku/vue-paginate
ただ、開閉時のaria-expanded
ほかWAI-ARIA部分などはまだまだ対応しきれていないので、今後も改良する余地はありそうです(自前実装になる?)。
今後の更新・TODOなど
以下Scrapboxのページにて順次手作業で更新予定です
https://scrapbox.io/yamanoku/Reading…
PWAを作ってみての感想
- Nuxt.jsにおけるPWA導入が圧倒的にやりやすい・分かりやすいかなと思いました
- Vue.js依存ですが…
- PWAだけに限らないですが、何かしら動くものを作ってみると、新しいものがきたらそこから派生してみる・検証することができる
- まだまだ改善の余地は大きい部分はあるが試行錯誤していろんなことが検証できるのが楽しい
- こうしたらいいよ的なアドバイスお待ちしております(コメントでもTwitterでも)
- 今後の派生として、妻を個人Slackに招待して、家族間でのURL共有みたいなのがやれたらいいかなと思っている
- 妻が結構検索しまくって共有してくれる(育児・買い物・行きたいところ 等)
- 夫婦間での共有を簡易・履歴として残すようにしたい
- 自分でPWAを実装してみてAndroid実機で動かせるのがこれまでにない感覚で面白かった
- ちなみにポートフォリオサイトもPWA化しています
- GitHub Pagesと紐づけているので、配下のページ(リポジトリ)も自動的にPWA判定になっている?
- Birthday-Countdown.js など
- Service Workerがルートディレクトリで設定されているから?
- 実際にPWAとして使えるものを使ってみたり検証したりしてみる
- Service Workerがどういう感じで使われているか とか
- 自分はTwitterはネイティブではなくTwitter Lite(PWA版)のを使うようにしています。
- 企業の制作実体験記みたいなのが気になりだす(業務内でのノウハウや失敗など)
- 最近だとHTML5カンファレンスや7月のHTML5 APP CONFERENCE 2018でその辺が聞けました
- iOSマジお前...となる気持ちがよくわかる
以上になります。ご覧いただきありがとうございました。
明日(12/7)は@_lemon2003_さんになります。
【弊社アドベントカレンダーPR】
最後に宣伝になりますが、私が所属している株式会社GEEKでもアドベントカレンダーをやっております。良ければご覧になってみてください。
自分はこのアドベントカレンダーほか色んな所に出張執筆予定です。
GEEKアドベントカレンダーの次回担当はマークアップエンジニアの大房さんになります。
Author And Source
この問題について(よく分かってなくてもNuxt.jsでPWAが作れた話), 我々は、より多くの情報をここで見つけました https://qiita.com/yamanoku/items/19825228f2629dedd024著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .