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

こえのブログでのPWA ~ 開発現場編 ~ / Koe-No-Blog PWA

こえのブログでのPWA ~ 開発現場編 ~ / Koe-No-Blog PWA

Frontrend × Bonfire Frontend (https://frontrend.connpass.com/event/124995/) での発表資料です。

「こえのブログ」はアメブロに追加された音声配信機能です。新機能開発における技術選定、開発フローやドキュメント作成など「開発現場」に焦点を当ててお話します。

関連ブログ: https://developers.cyberagent.co.jp/blog/archives/20506/

Kazunari Hara

April 16, 2019

Transcript

68 slides
  1. 2010 JavaScript 2011 Node.js 2016 React, Redux, DevOps 2018 CDN

    HTML5 Web Applicationの つくりかた https://ameblo.jp/ca-1pixel/entry-1100959 8050.html アメブロ2016 ~ React/Reduxでつ くるIsomorphic web app ~ https://developers.cyberagent.co.jp/blog/archives/ 636/ Optimized Server-Side Web Application In 2018 https://developers.cyberagent.co.jp/blog/archi ves/16818/ Amebaプラットフォームの 作りかた https://www.slideshare.net/herablog/ameba-2 2035207
  2. index.html voice-app.js voice-editor.js voice-home.js lazy-resources.js shared dependencies Entrypoint App Shell

    Lazy Load Fragment PRPL Pattern <script type=”module”> await import(); await import(); await import();
  3. コンポーネント指向での開発 <voice-app> <voice-header> <button type=”button”> メニューを開く</button> </voice-header> <voice-mic recording> </voice-mic>

    </voice-app> class VoiceMic extends LitElement { render() { const label = this.recording ? ‘停止する’ : ‘開始する’; } } class VoiceHeader extends LitElement { render() { return html` <slot></slot> `; } }
  4. :host { --mic-size: var(--voice-mic-size, 72px); } .mic { height: var(--mic-size);

    } .icon { … } font-family: sans-serif; <voice-mic> <voice-editor> voice-mic { --voice-mic-size: 100px; } Custom Property Cascading Scoped
  5. ブラウザの マイクを利用 navigator.mediaDevices .getUserMedia({ audio: { autoGainControl: false, channelCount: 1,

    echoCancellation: true, noiseSuppression: true, }, }) .then((stream) => { // use the stream }) .catch((err) => { // NotAllowedError or // NotFoundError });
  6. マイクパー ミッション を取得 const installMicPermissionWatcher = async callback => {

    const permissionStatus = await navigator.permissions .query({ name: 'microphone' }); // granted or prompt or denied callback(permissionStatus.state); permissionStatus .addEventListener('change', () => callback(permissionStatus.state) ); };
  7. FCP: 1.8s -> 1.5s (Updated) TTI: 4s -> 3s (Updated)

    App shell JS size: 120KB Chunk JS size: 20KB

More Decks by Kazunari Hara

Other Decks in Technology