● 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
● 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
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();
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
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
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
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
ECMAScript 2016+ compatibility table is almost all green, but we need to load polyfill for now https://kangax.github.io/compat-t able/
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/
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
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
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
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
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
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)
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
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
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
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
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
Accessibility Tools checks additional accessibility issues Checking screen reader using VoiceOver Inspecting Accessibility Tree using DevTools Collaboration between designers and developers using VisBug
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
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
Native Lazy-loading defers the loading of off-screen elements
if ('loading' in HTMLImageElement.prototype) { // copy value from data-src to src } else {} // fallback with Intersection Observer https://twitter.com/herablog/status/1164475719100952576
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/
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
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
Native File System enables developers to control device storage Use cases (planning): ● opening files in the storage ● saving recorded audios ● downloading favorite audios Planning
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 to open file // use to download files } Planning
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; } }