1 of 51

スマートフォン体験を一歩先へ

プログレッシブウェブアプリの作り方

Eiji Kitamura

Last update: 2016/6

Confidential and proprietary

2 of 51

このスライドについて

  • Developer Festa Sapporo 2015, Google for Mobile 2015, Google Developers Meetup #2 で使用した資料の公開版です。
  • スピーカーノートがあります。合わせてご覧下さい。
  • この資料を流用してプレゼンをして頂いて構いません。
    • ただし、スライド中に使われている写真等のライセンスについては、念のため改めて確認して頂けるようお願いします。

Confidential and proprietary

3 of 51

Eiji Kitamura

Developer Advocate @ Google

Chrome / Web / Identity

Confidential and proprietary

4 of 51

A day in the life...

Photo by @28964535@N08 on Flickr

Confidential and proprietary

5 of 51

スマートフォンの月間利用時間

1:49

Smartphone

Source: スマートフォン視聴率情報 Nielsen Mobile NetView 2015 9 月より

http://www.netratings.co.jp/news_release/2015/11/Newsrelease20151125.html

1:28

0:23

App

Web

Confidential and proprietary

6 of 51

80

は、その人のトップ3アプリ

に費やされている

Source: comScore Mobile Metrix, U.S., Age 18+, June 2015

スマートフォンユーザの

時間

%

Confidential and proprietary

7 of 51

https://medium.com/inside-birdly/why-you-shouldn-t-bother-creating-a-mobile-app-328af62fe0e5

Confidential and proprietary

8 of 51

スマートフォンユーザーの

平均月間利用アプリ数

25

Chrome for Android ユーザーの平均月間訪問サイト数

100+

Source: comScore Mobile Metrix, U.S., Age 18+, June 2015; Internal Chrome Data

Confidential and proprietary

9 of 51

Progressive Web Apps

Confidential and proprietary

10 of 51

S

L

I

C

E

Secure

Linkable

Indexable

Composable

Ephemeral

Confidential and proprietary

11 of 51

Progressive Web App

Legacy Browsers

Modern Browsers

Native App like Experience

Regular Web App Experience

Confidential and proprietary

12 of 51

Confidential and proprietary

13 of 51

Confidential and proprietary

14 of 51

Homescreen Icon

Splash Screen

Fullscreen

Offline access

Theme color

Push Notification

Confidential and proprietary

15 of 51

User Experience

Confidential and proprietary

16 of 51

アプリインストールバナー

manifest を定義

Service Worker を使用

HTTPS で提供

5 分以上の間隔で複数回アクセス

Confidential and proprietary

17 of 51

{

"name": "Flipkart Lite",

"short_name": "Flipkart Lite",

"icons": [

{

"src": "/images/icon.png",

"sizes": "96x96",

"type": "image/png"

}, {

"src": "/images/icon@2x.png",

"sizes": "192x192",

"type": "image/png"

}

],

"start_url": "/?homescreen=1",

"display": "standalone",

"background_color": "#F1F1F1",

"theme_color": "#F1F1F1"

}

manifest.json

Confidential and proprietary

18 of 51

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

HTML

Confidential and proprietary

19 of 51

Service Worker

Photo by @tallkev on Flickr

Confidential and proprietary

Google for Mobile

20 of 51

push

Service Worker

Cache API

Push Notification

Confidential and proprietary

21 of 51

index.html

navigator.serviceWorker.register('/sw.js')

.then(function(registration) {

// Success!

}).catch(function(error) {

// Error...

});

Confidential and proprietary

22 of 51

Cache API

Photo by @taranos on Flickr

Confidential and proprietary

Google for Mobile

23 of 51

suumo

0.8sec

0.2sec

Confidential and proprietary

24 of 51

Cache API

self.addEventListener('fetch', function(event) {

event.respondWith(

caches.match(event.request).then(function(response) {

return response || fetch(event.request);

})

);

});

sw.js

Confidential and proprietary

25 of 51

sw-toolbox

https://github.com/GoogleChrome/sw-toolbox

1

2

3

cacheFirst

1

2

3

networkFirst

1

2

2

fastest

Confidential and proprietary

26 of 51

sw-precache

https://github.com/GoogleChrome/sw-precache

index.html

/style/main.css

/scripts/main.js

...

Confidential and proprietary

27 of 51

https://github.com/GoogleChrome/application-shell

Confidential and proprietary

28 of 51

Push Notification

Photo by @johanl on Flickr

Confidential and proprietary

Google for Mobile

29 of 51

Confidential and proprietary

30 of 51

Web Push Notifications

Confidential and proprietary

31 of 51

Confidential and proprietary

32 of 51

Firebase Cloud Messaging

Confidential and proprietary

33 of 51

プッシュ通知の購読

navigator.serviceWorker.ready().then(function(sw) {

sw.pushManager.subscribe({userVisibleOnly: true})

.then(function(sub) {

// After permission is granted

sendSubToServer(sub); // Send subscription to the server

});

});

index.html

Confidential and proprietary

34 of 51

プッシュ通知の受信

self.addEventListener('push', function(event) {

event.waitUntil(

self.registration.showNotification(title, {

body: body, icon: icon, tag: tag,

actions: [{action: 'remindMe', title: 'REMIND ME'}]

}

});

});

sw.js

push

Confidential and proprietary

35 of 51

プッシュ通知にカスタムボタン

self.addEventListener('notificationclick', function(event) {

event.notification.close();

if (event.action === 'remindMe') {

remindMeLater();

} else {

clients.openWindow("/inbox");

}

}, false);

sw.js

Confidential and proprietary

36 of 51

Background Sync

Photo by @lanier67 on Flickr

Confidential and proprietary

37 of 51

Confidential and proprietary

38 of 51

One-off Sync

Confidential and proprietary

39 of 51

index.html

navigator.serviceWorker.register('/sw.js')

.then(function(registration) {

return registration.sync.register('mySync');

});

sw.js

self.addEventListener('sync', function(event) {

if (event.tag == 'mySync') {

event.waitUntil(doSomething());

}

});

Confidential and proprietary

40 of 51

Periodic Sync

Confidential and proprietary

41 of 51

Summary

Confidential and proprietary

42 of 51

Making an improvement

Photo by @28964535@N08 on Flickr

Confidential and proprietary

43 of 51

Confidential and proprietary

44 of 51

Tips

Confidential and proprietary

45 of 51

Confidential and proprietary

46 of 51

https://chromestatus.com

Confidential and proprietary

47 of 51

Use Chrome Canary

Confidential and proprietary

48 of 51

Inspect devices

Confidential and proprietary

49 of 51

Debug on DevTools

Confidential and proprietary

50 of 51

thank

you

Google for Mobile

Confidential and proprietary

51 of 51

FAQ

  • プッシュ通知は iOS で使えますか?
    • いいえ。ただ、Desktop のみ、かつ W3C 標準ではない Safari 独自のプッシュ通知機能であれば、似た機能が利用可能です。

Confidential and proprietary