Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scalable PWA

Kazunari Hara
February 01, 2020

Scalable PWA

Scalable PWA 〜こえのブログ最新事例〜


Kazunari Hara

February 01, 2020

More Decks by Kazunari Hara

Other Decks in Technology


  1. Feb. 1 2020, PWA Night CONFERENCE 2020 Kazunari Hara, CyberAgent

    Scalable 〜こえのブログ最新事例〜
  2. • Reliable - Load instantly even when offline • Fast

    - Respond quickly and no junk scrolling • Engaging - Feel like a natural app on the device https://developers.google.com/web/progressive-web-apps
  3. • Reliable - Load instantly even when offline • Fast

    - Respond quickly and no junk scrolling • Engaging - Feel like a natural app on the device • Scalable - Being improved consistently
  4. こえのブログ Posting a blog entry just by speaking • Audio

    recording • Speech-to-Text • Audio player • Installable •
  5. Getting Audio from Mic and save/post it later const mediaRecorder

    = new MediaRecorder(stream, options); mediaRecorder.addEventListener('stop', () => { const audioBlob = new Blob(recordedChunks); const audioUrl = URL.createObjectURL(audioBlob); downloadLink.href = audioUrl; downloadLink.download = 'audio.wav'; }); mediaRecorder.start();
  6. Transcoding with WASM reduces audio sizes https://github.com/Kagami/vmsg • In Web

    Worker • Execute periodically • WAV to MP3 -90% Audio sizes
  7. Speech-to-Text on Cloud converts audio to text by applying powerful

    neural network models const speech = require('@google-cloud/speech'); const client = new speech.SpeechClient(); const recognize = () => { const request = { audio: { uri: 'gs://...' }, config: { languageCode: 'ja-JP', enableWordTimeOffsets: true }, }; return client.recognize(request); };
  8. Playing Audio with the user’s permission • Asking permission to

    play audio after prompt on the first encounter • If the user says “OK”, start playing audio and save the status to the browser storage • If the user says “NO”, always ask before playing audio
  9. Add to Home Screen as an application on OSes Criteria:

    • https • Service Worker with fetch • Web App Manifest etc...
  10. Single Origin with HTTPS helps overcome many challenges in PWAs

    • Service worker scopes • New feature permissions • Controllable caches • Reading cookies https://web.dev/multi-origin-pwas/ https://voices.ameba.jp/*/ {api, assets, images, src} voice.ameba.jp
  11. App Strategy at Ameba こえのブログ shipped as a PWA: •

    To create experimental fetures • To provide app to major OSes • Not to increase native app sizes • PWA already works on many browsers
  12. Including Polyfill to provide modern functionality on older browsers Some

    polyfill options: Bundle JS files with polyfills like core-js Using polyfill services like polyfill.io Differential script loading is also recommended <script type="module" src="main.esm.mjs"></script> <script nomodule src="main.es5.js"></script> ECMAScript 2016+ compatibility table is almost all green, but we need to load polyfill for now https://kangax.github.io/compat-t able/
  13. Perf is Critical for user experience in PWA • High

    priority for better UX • Users prefer fast apps • Better for business metrics voice.ameba.jp -44% Client Rendering Time +57% Page Views https://developers.cyberagent.co.jp/blog/archives/636/
  14. Consistently Fast even during traffic spikes (13x traffic spikes occurred)

    Caches ensure site stability: • Server-side caches • Client-side caches
  15. CDN for server-side stability • Long TTL (1 day by

    default) • Event-driven cache purging • Serving stale content 98% Cache Hit Ratio 99% Cache Coverage
  16. Service Worker for client-side caching • Pre-caching app assets ◦

    updated precisely with server file update • Runtime assets caches (except partial audios) • HTTP caches if the browser does not support SW 98% Cache Cavarage
  17. Cache Overview to improve site speed and consistency Origin Server

    / DB CDN Browser Purge on data update 98% Cache Cavarage 98% Cache Hit Fetch on file change High cache hit/coverage reduces unnecessary network requests
  18. Perf Budget helps ensure good user experience and business metrics

    The team need to maintain • Perf budget • Performance monitoring • Improve decision making in development flow
  19. Lab data vs Field data Assessing app performance using both

    types of data Lab Controlled/Consistent Real-world/Wild Field Lighthouse DevTools SpeedCurve Chrome User Experience Report Firebase Performance Monitoring SpeedCurve
  20. Setting Perf Budget 1. Measuring the app in lab 2.

    Comparing metrics to competitors with 20% rule 3. Setting perf budgets 4. Monitoring budgets on a daily or a deployment basis 5. Updating budgets (e.g. adding Field metrics)
  21. Perf Budget Now Setting aggressive budgets to find out regressions

    early FCP on Fast 3G <= 1.5s TTI on Fast 3G <= 3s Entrypoint HTML <= 14KB App shell JS <= 120KB Chunk JS <= 20KB
  22. Monitoring Perf Budget Daily basis: SpeedCurve, Lighthouse CI... (Lab) Firebase

    Perf, CrUX… (Field) Deployment basis: SpeedCurve (Lab) Before deployment: Bundle size on CI
  23. Perf Budget in development flow Some steps before consuming perf

    budget: • Reducing size if possible • Finding reason for size increases • Issuing it to refactor later Exceeded? Ship it! Can reduce size? Reduce size Issue reason Consume budget Refactor Ship it! No Yes No Yes
  24. Continuous Deployment for site realiability • Deployment is fast, easy,

    safe, and frequent • Rollbacks are also easy • Master branch is deployed automatically (on a daily basis, planning) >= 1,000 Releases in 10 Month Push CLI Purge
  25. Tech Stack better performance, higher security, cheaper, easier scaling, and

    better DX Similar approach to JAMStack: • Entire Project on a CDN • Everything Lives in Git • Modern Build Tools • Automated Builds • Atomic Deploys • Instant Cache Invalidation Cloud Functions Cloud Storage Cloud Functions Web App Assets Audios API POST/DELETE API GET 93% Endpoints Cacheable https://jamstack.org/
  26. Writing Tests ensures continuous deployment and app quality • Logic

    unit testing • Visual regression testing (pages) Tests working in progress: • Logic unit testing on brosers • Server-side testing https://qiita.com/junkisai/items/016c567a9fbade08d65b
  27. Traffic reffarals to increase visitors Social media Native Apps Search

    engines Open PWA from native apps Primary pages are on ameblo.jp not voice.ameba.jp
  28. Differential Rendering for social media crowlers and browsers inc Googlebot

    Server-side meta rendering <title>${pageTitle}</title> <meta property="og:type" content="website"> <meta property="og:image" content="${image}"> <voice-app></voice-app> <script type="module" src="src/components/voice-app.js" crossorigin></script> Client-side app rendering
  29. Image CDN creates eyecatch images displayed in social media •

    Inserting landmark • Cropping, resizing • Converting appropriate format /image.jpg? crop=1200:630&width=1200&overlay=share
  30. Accessibility improves user experience • Color contrast • Machine readability

    • Keyboard usability • User preferences etc... voice.ameba.jp Only a subset of accessibility issues can be automatically detected
  31. Accessibility Tools checks additional accessibility issues Checking screen reader using

    VoiceOver Inspecting Accessibility Tree using DevTools Collaboration between designers and developers using VisBug
  32. Dark Mode respects prefers-color-scheme Applied with CSS custom properties @media

    (prefers-color-scheme: dark) { :root { --app-background-color: black; --app-text-color: white; } } Planning
  33. Accessibility Guidelines explains how can we improve user experience •

    Based on WCAG 2.1 • Web Bundle is available https://openameba.github.io/a11y-guidelines/ openameba.github.io https://github.com/openameba/a11y-guidelines/releases
  34. Progressive Enhancement to provide first-class experiences to the user Not

    only for visual designs: • Feature detections • Polyfill or other solutions voice.ameba.jp voice.ameba.jp
  35. Permissions API Not available: Always asking the permission Available: Checking

    the permission before recording const checkMicPermission = async () => { const permissionStatus = await navigator.permissions.query({ name: 'microphone', }); if (permissionStatus.state === 'denied') { // Display dialog... } else { // Start recording... } // You can also use addEventListener // permissionStatus.addEventListener('change'); };
  36. Native Lazy-loading defers the loading of off-screen elements <img alt=””

    data-src=”https://...” loading=”lazy” /> <noscript> <img alt=””src=”https://...” loading=”lazy” /> </noscript> if ('loading' in HTMLImageElement.prototype) { // copy value from data-src to src } else {} // fallback with Intersection Observer https://twitter.com/herablog/status/1164475719100952576
  37. Is Native Lazy-loading too eager? If it is true for

    your app, you can load images with • Intersection Observer • Element Lazy-rendering https://calendar.perfplanet.com/2019/native-image-lazy-loading-in-chrome-is-way-too-eager/
  38. Web Share invokes the native sharing mechanism of the device

    The apps or the person could be suggested based on the user’s engagement
  39. Web Share invokes the native sharing mechanism of the device

    if ('share' in navigator) { // Chrome, Safari navigator.share({ title: '', text: '', url: '' }); } else { // Display custom dialog }
  40. Wake Lock prevents devices from dimming while recording The users

    can • check the remaining time • tap the stop button • remove noises of when the device starts recording in background O rigin Trial
  41. Wake Lock prevents devices from dimming while recording if ('wakeLock'

    in navigator) { // Chrome let wakeLock; const requestWakeLock = async () => { try { wakeLock = await navigator.wakeLock.request('screen'); } catch (err) { console.error(err); } }; document.addEventListener('visibilitychange', handler); document.addEventListener('fullscreenchange', handler); } else { // you can use NoSleep.js if wake lock is a critical fearture // no fallback also makes sence } O rigin Trial
  42. Native File System enables developers to control device storage Use

    cases (planning): • opening files in the storage • saving recorded audios • downloading favorite audios Planning
  43. Native File System enables developers to control device storage //

    Chrome if (‘chooseFileSystemEntries’ in window) { const fileHandle = await window.chooseFileSystemEntries(); } else { // fallback with HTML element // use <input type=”file” /> to open file // use <a download> to download files } Planning
  44. Periodic Background Sync refreshes data periodically in backgound Use cases

    (planning): • updating rankings • downloading audios by favorite bloggers Planning
  45. Periodic Background Sync refreshes data periodically in backgound const registration

    = await navigator.serviceWorker.ready; if ('periodicSync' in registration) { // Chrome await registration.periodicSync.register( 'content-sync', { minInterval: 24 * 60 * 60 * 1000 } // one day ); } Planning
  46. UA Client Hints simplify User Agent string HTTP request header

    , User-Agent, is going to be freezed Tested in Google Chrome Canary 81 if (req.http.Sec-CH-UA ~ "Google Chrome (\d+)$") if (std.atoi(re.group.1) >= 63) { call esm_origin; } }
  47. @herablog Related documents: • アメブロ2019: こえのブログでのPWA https://developers.cyberagent.co.jp/blog/archives/20506/ • Web App

    Checklist 〜高品質のWebアプリケーションをつくる ために〜 https://speakerdeck.com/herablog/web-app-checklist-2019-at-inside-frontend • こえのブログでのPWA ~ PWA編 ~ https://speakerdeck.com/herablog/pwa-night-vol-dot-4 • こえのブログでのPWA ~ 開発現場編 ~ https://speakerdeck.com/herablog/koe-no-blog-pwa • 最新CDN入門 WEB+DB PRESS Vol.109 https://gihyo.jp/magazine/wdpress/archive/2019/vol109 • CDNフル活用でつくる高速 Webアプリ https://speakerdeck.com/herablog/using-cdn-to-improve-web-performance Life Have a nice