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

Web App Checklist 〜高品質のWebアプリケーションをつくるために〜 / Web App Checklist 2019 at Inside Frontend

Web App Checklist 〜高品質のWebアプリケーションをつくるために〜 / Web App Checklist 2019 at Inside Frontend

#insideFE slide with @tokimariri.

Web App Checklist😉:
💡Rendering patterns
💡CDN
💡Perf Budget
💡a11y
💡PWA
💡WASM in Web Worker
💡Monitoring tools
💡DX (including LGTM!)
and so on! 🙌

Kazunari Hara

May 18, 2019
Tweet

More Decks by Kazunari Hara

Other Decks in Technology

Transcript

  1. 高品質のWebアプリケーションをつくるために
    Web App Checklist - To make high quality app for better user experience
    2019.05.18 Inside Frontend @Abema Towers / Kazunari Hara & tokimari
    Web App Checklist

    View Slide

  2. 原 一成 Kazunari Hara
    Web Developer @ CyberAgent
    Twitterer
    Beer, Cat, Karting, Family
    @herablog

    View Slide

  3. ときまり tokimari
    Frontend Engineer @ CyberAgent
    Accessibility Police
    Beer, Cat, Knitting
    @tokimariri

    View Slide

  4. View Slide

  5. 喋るだけで
    ブログになる
    投稿機能
    Post function that
    creates blog entry just
    by speaking

    View Slide

  6. 幅広いユーザー
    投稿/閲覧スタイル
    Post function that creates
    blog entry just by speaking
    お風呂中にも子供を抱っこしていても、料理中でも寝
    ながらでも投稿、閲覧ができます

    View Slide

  7. 高品質のWebアプリケーションをつくるために
    Web App Checklist - To make high quality app for better user experience
    2019.05.18 Inside Frontend @Abema Towers / Kazunari Hara & tokimari
    Web App Checklist

    View Slide

  8. no genre title
    13 a11y 文字のコントラストは4.5:1以上
    14 a11y 色だけで説明しない
    15 a11y 要素の選択は適切に
    16 a11y キー操作だけで利用できる
    17 a11y,UX フォーカスを可視化する
    18 UX スクロール位置を復元
    19 UX,a11y 修正・削除ができる
    20 UX 継続的なモニタリング
    21 UX ストレスのない遷移とローディング
    22 UX レイアウトを固定する
    23 a11y,UX 突然音を出さない
    24 Security セキュリティ監査する
    no genre title
    1 UX 適切なレンダリングパターンを選択
    2 Perf 安定したサーバレスポンス
    3 Perf 圧縮したメディアフォーマットを利用
    4 Perf,UX リソースを必要なタイミングで読み込む
    5 Perf Webパフォーマンスを監視
    6 UX Off the main thread
    7 UX オフラインでも利用できる
    8 UX モバイルでもデスクトップでも使える
    9 PWA メタデータを提供
    10 DX OSSのように開発
    11 UX Progressive Enhancement
    12 a11y,SEO 画像に代替テキストを設定する
    Checklist: 36

    View Slide

  9. no genre title
    13 a11y 文字のコントラストは4.5:1以上
    14 a11y 色だけで説明しない
    15 a11y 要素の選択は適切に
    16 a11y キー操作だけで利用できる
    17 a11y,UX フォーカスを可視化する
    18 UX スクロール位置を復元
    19 UX,a11y 修正・削除ができる
    20 UX 継続的なモニタリング
    21 UX ストレスのない遷移とローディング
    22 UX レイアウトを固定する
    23 a11y,UX 突然音を出さない
    24 Security セキュリティ監査する
    no genre title
    1 UX 適切なレンダリングパターンを選択
    2 Perf 安定したサーバレスポンス
    3 Perf 圧縮したメディアフォーマットを利用
    4 Perf,UX リソースを必要なタイミングで読み込む
    5 Perf Webパフォーマンスを監視
    6 UX Off the main thread
    7 UX オフラインでも利用できる
    8 UX モバイルでもデスクトップでも使える
    9 PWA メタデータを提供
    10 DX OSSのように開発
    11 UX Progressive Enhancement
    12 a11y,SEO 画像に代替テキストを設定する
    Checklist: 36
    Today: only 20

    View Slide

  10. 適切なレンダリングパターンを選択
    Perf
    Checklist. 01
    Select appropriate rendering pattern for your app.

    View Slide

  11. Rendering on the Web
    https://developers.google.com/web/updates/2019/02/rendering-on-the-web

    View Slide

  12.   TTI = FCP
      Inflexible
    Server Side
    Rendering
    ロジックは
    サーバー側
    GET /
    Network
    JS
    TTIはJS構成
    に依存する
    Logics are in
    server side
    TTI depends on JS
    architecture

    View Slide

  13. Optimized Server-Side Web Application In 2018
    https://developers.cyberagent.co.jp/blog/archives/16818/

    View Slide

  14. Server Side Rendering Website
    アメーバニュース Ameba News
    はやいFCP
    https://news.ameba.jp/entry/20190516-669/をMobile、Simulated Fast 3G、4x CPU Slowdown、ローカル環境で測定。
    Fast FCP

    View Slide

  15. SSR with hydration
      Flexible
      TTI >>>> FCP
    データを使ってク
    ライアントで描画
    GET /
    Network
    JS
    DATA={}
    bundle.js
    render(DATA)
    Client rendering
    with initial data

    View Slide

  16. アメブロ2016 ~ React/ReduxでつくるIsomorphic web app ~
    https://developers.cyberagent.co.jp/blog/archives/636/

    View Slide

  17. SSR with Hydration App
    アメーバブログ Ameba Blog
    https://ameblo.jp/ca-seo/entry-12458541240.htmlをMobile、Simulated Fast 3G、4x CPU Slowdown、ローカル環境で測定。
    TTIが遅くなりがち Slow TTI

    View Slide

  18. Client Side
    Rendering
      Flexible, Fast TTFB
      TTI >>>> FCP
    GET /
    FCP TTI
    Network
    JS
    bundle.js
    render()
    FCPはもっと遅く
    なることも

    View Slide

  19. GET /
    FCP TTI
    JS
    app.js
    render()
    ● H2 Server Push (Preload)
    ● Web Components ...
    こえのブログ
    はCSRを選択
    できるだけはやい
    CSRに挑戦
    JSの並列配信
    Parallel JS requests
    Our challenge was
    to make CSR app
    as fast as possible
    小さいJS
    Light JS

    View Slide

  20. Lighthouse
    Performance
    程々にはやいFCP
    とはやいTTI
    https://voice.ameba.jp/をMobile、Simulated Fast
    3G、4x CPU Slowdown、ローカル環境で測定。
    So-so fast FCP
    and fast TTI.

    View Slide

  21. 安定したサーバレスポンス
    Keep fast and consistent server response.
    Perf
    Checklist. 02

    View Slide

  22. Server response is
    fundamental for web
    performance.
    サーバレスポンス
    は根本的
    サーバレスポンスが遅い
    と何も表示されない
    Waiting with blank page
    when server response is too
    slow.

    View Slide

  23. Reasons for
    server-side latency.
    サーバ遅延の要因
    ● 地理 Location
    ● 計算量 Computation
    ● キャパシティ Capacity
    ● リダイレクト Redirect
    ● DBクエリ DB Queries
    ...

    View Slide

  24. Use CDN for edge
    side caching.こえのブロ
    グで利
    CDNキャッシュ
    の利用
    高キャッシュヒット率で
    オリジンサーバーに
    1度しかリクエストしない
    Only requests content to the origin server
    once because of high cache hit ratio.

    View Slide

  25. Cache content in CDN
    as long as possible.
    できるだけ長く
    CDNキャッシュ
    長いTTLと
    Surrogate Keyを指定
    JavaScript
    TTL: 30days
    Key: web/release
    Entry data
    30days
    blogger/${ID}
    entry/${ID}
    Setting long TTL and Surrogate Key

    View Slide

  26. Event-driven cache
    purging.
    イベント駆動
    キャッシュパージ
    onDeploy onUpdate
    Purging with Surrogate Key
    web/release entry/${ID}

    View Slide

  27. Edge-side
    computing.
    エッジサイド
    コンピュー
    ティング
    URLからSurrogate Key
    を抽出
    sub vcl_fetch {
    declare local var.SurrogateKey STRING;
    if (req.http.x-url ~
    "/([a-z0-9-]{3,24})/([a-zA-Z0-9]+)") {
    set var.SurrogateKey = var.SurrogateKey + "
    blogger/" + re.group.1 +
    " entry/" + re.group.2;
    // e.g. ogger/abcde", "entry/12345"
    }
    set beresp.http.Surrogate-Key =
    var.SurrogateKey;
    }
    Extracting surrogate keys from URL

    View Slide

  28. 圧縮したメディアフォーマットを利用
    Select optimized media format.
    Perf/UX
    Checklist. 03

    View Slide

  29. According to Lighthouse, the size
    of images could still be reduced.
    まだまだ減らせる画像容量

    View Slide

  30. List of image file
    formats
    画像フォーマット
    ● JPEG
    ● Progressive JPEG
    ● PNG
    ● WebP
    ● SVG
    ● Animation GIF
    画質を指定して利用
    ファイルサイズに注意
    高圧縮
    動画のが軽いことも

    View Slide

  31. ImageOptim
    https://imageoptim.com/

    View Slide

  32. List of image CDN
    providers.
    Image CDN
    ● Akamai
    ● Cloudinary
    ● Imgix
    ● Fastly
    ● Hayabusa

    View Slide

  33. List of image CDN
    providers.
    Image CDN
    ● Akamai
    ● Cloudinary
    ● Imgix
    ● Fastly
    ● Hayabusa
    こえのブログ
    で利用

    View Slide

  34. サムネイルは低
    クオリティ指定
    自動判定で
    WebP配信
    Pixel ratio指定
    /image.jpg?auto=webp
    /image.jpg?dpr=${window.devicePixelRatio}
    /image.jpg?quality=60

    View Slide

  35. リソースを必要なタイミングで読み込む
    Load resources when necessity.
    Perf/UX
    Checklist. 04

    View Slide

  36. 画像の遅延
    読み込み
    Image lazy-loading
    無駄な画像を
    リクエストしない
    Reducing unnecessary
    image requests

    View Slide

  37. ブラウザ標準
    遅延読み込み
    Native lazy-loading

    View Slide

  38. Feature
    Detection
    if ('loading' in
    HTMLImageElement.prototype) {
    // Use Native lazy-loading
    } else {
    // Use Intersection Observer (or polyfill)
    }

    View Slide

  39. スクリプトの遅延読み込み
    index.html
    (Entrypoint)
    voice-app.js
    (App shell)
    voice-home.js
    (Fragment)
    voice-editor.js
    (Fragment)
    <br/>import(‘’)<br/>import(‘’)<br/>Script lazy-loading<br/>

    View Slide

  40. Webパフォーマンスを監視
    Monitor web performance constantly.
    Perf
    Checklist. 05

    View Slide

  41. Start Performance Budgeting
    https://addyosmani.com/blog/performance-budgets/

    View Slide

  42. パフォーマンス
    バジェットは
    超えちゃいけない制限
    Performance budget is a
    limit for pages which the
    team is not allowed to
    exceed.
    Timing
    Resource
    Rule
    カスタム指標もOK
    Custom metrics are also available

    View Slide

  43. “Performance budgets are not just thresholds. Much like a
    financial budget, they're something consciously spent.“
    Addy Osmani
    Perf指標を財政予算に見立てて管理

    View Slide

  44. こえのブログ
    Perf Budget
    Perf Budget Values.
    Entrypoint HTML <= 14KB
    App Shell JS <= 120KB
    Chunk JS <= 20KB
    FCP on Fast 3G <= 1.5s
    TTI on Fast 3G <= 3s
    品質劣化をはやめに検知する
    ため、アグレッシブな設定
    Aggressive budgets to find out quality deterioration
    予算オーバーすると
    デプロイできない CI stops deployment if resource size exceeds
    the budget

    View Slide

  45. Off the main thread
    Perf
    Checklist. 06

    View Slide

  46. メインスレッド
    Main Thread
    ロングタスクは
    ユーザー操作をブロックする Long-task blocks user input

    View Slide

  47. Web Worker上
    のWASMで
    音声変換
    Audio transcoding by
    WASM in Web Worker
    WAV MP3

    View Slide

  48. Comlink
    https://github.com/GoogleChromeLabs/comlink

    View Slide

  49. オフラインでも利用できる
    Respond with a 200 when offline.
    UX
    Checklist. 07

    View Slide

  50. 回線が常にあるとは
    限らない
    Network is not always
    available.
    常にはやいと
    も限らない
    Network is not
    always fast.

    View Slide

  51. Service Worker
    Precache
    index.html
    Revision:adcoaeo
    voice-app.js
    Revision:4f39dn3
    logo.svg
    Revision:mfj48dj
    Revision変
    わったファイ
    ルのみ再取得
    ビルドした全アセッ
    トをプリキャッシュ
    Precaching all assets Re-fetching only
    updated scripts

    View Slide

  52. Workbox.routing.registerNavigationroute(
    '/index.html', {
    whitelist: [
    /^\/editor/,
    /^\/embed/,
    ...
    ]
    },
    );
    特定パスへのナビゲー
    ションリクエスト時に
    プリキャッシュした
    index.htmlを返却する Return precache HTML when navigation request
    Service Worker
    Precache

    View Slide

  53. オフラインでの
    録音が可能
    Offline recording is
    available.

    View Slide

  54. モバイルでもデスクトップでも使える
    Usable on all devices.
    UX
    Checklist. 08

    View Slide

  55. and more devices...

    View Slide

  56. メディア
    クエリ
    Media Queries
    @media screen and (min-width: 1025px) {
    :root {
    --app-header-height: 60px;
    --app-page-background-color:
    var(--clr-whitesmoke);
    --app-drawer-width: 400px;
    }
    }
    カスタムプロパティで
    全体レイアウトを一箇
    所で指定 Set layout as custom properties in root selector.

    View Slide

  57. レスポンシブ
    画像
    Responsive Images
    src="toshi.jpg?size=80"
    srcset="
    toshi.jpg?size=160 2x,
    toshi.jpg?size=240 3x
    "
    />

    View Slide

  58. Image CDN
    /image.jpg?
    width=640&
    dpr=${window.devicePixelRatio}

    View Slide

  59. Desktop PWA
    でも使える
    Also available as
    Desktop PWA

    View Slide

  60. メタデータを提供
    Provide app meta data.
    PWA
    Checklist. 09

    View Slide

  61. Web App
    Manifest
    {
    “name”: “こえのブログ by Ameba”,
    “description”: “「こえのブログ」は...”,
    “lang”: “ja-JP”,
    “icons”: [...],
    “background_color”: “#fff”,
    “theme_color”: “#fff”,
    “start_url”: “/?source=homescreen”,
    “scope”: “/”,
    “display”: “standalone”
    }
    iOS 12.2での対応により
    スタンドアローンで
    OAuthも利用可能に OAuth is available in standalone mode on later iOS 12.2

    View Slide

  62. Meta for Social
    Media.




    content="https://voice.ameba.jp/share.jpg">


    content="https://voice.ameba.jp/embed/">

    content="https://voice.ameba.jp/share.jpg">
    SNS用
    メタデータ

    View Slide

  63. The new evergreen Googlebot
    https://webmasters.googleblog.com/2019/05/the-new-evergreen-googlebot.html
    SEOハックに
    さようなら
    Goodbye SEO Hacks.

    View Slide

  64. YHAAAAAAAA!

    View Slide

  65. OSSのように開発
    Have OSS-like development style.
    checklist. DX DX
    Checklist. 10

    View Slide

  66. README.md

    View Slide

  67. CONTRIBUTING.md

    View Slide

  68. CHANGELOG.md

    View Slide

  69. よいLGTM
    Good LGTM makes
    developers
    comfortable.

    View Slide

  70. LTTM (Chrome Extension)
    https://chrome.google.com/webstore/detail/lttm/jdidcgkdggndpodjbipodfefnpgjooeh

    View Slide

  71. View Slide

  72. Progressive Enhancement
    Checklist. 11 UX

    View Slide

  73. こえのブログの”投稿”
    =アメブロのプラスの投稿機能
    投稿の推奨環境を制限
    ● iPhone Safari 11.3~
    ● Android Chrome 61~
    “Posting by voice” is an additional feature of Ameblo.
    Limit browsers:

    View Slide

  74. ● IE11~
    ● Edge
    ● Android OS 5~
    ● iOS11~
    こえのブログの”閲覧”
    =アメブロの標準機能
    “Browsing” Koe-no-blog is a standard feature of
    Ameblo. User can experience it by followings browsers:

    View Slide

  75. Progressive Enhancement
    Graceful Degradation
    動作しないブラウザを起点に機能を考えない
    Don't think the feature based on the legacy browser that doesn’t work.
    Kazunari Hara

    View Slide

  76. {
    "builds": [
    {
    "name": "esm-bundled",
    "browserCapabilities": ["es2015","modules"],
    "js": { "minify": true },

    "bundle": true,
    "addServiceWorker": false
    }, {
    "name": "es5-bundled",
    "js": {
    "compile": "es5",
    "minify": false,
    "transformModulesToAmd": true
    },

    "bundle": true,
    "addServiceWorker": false
    }
    ]
    }
    ● ES Modules bundled file
    ● ES5 bundled file
    CDNで別の
    ファイルを配信
    Deliver another assets file by CDN.
    Method 1

    View Slide

  77. PASS ./build/es5-bundled/src/components/voice-app.js: 124.69KB < maxSize 140KB
    PASS ./build/esm-bundled/src/components/voice-app.js: 77.81KB < maxSize 120KB
    PASS ./build/es5-bundled/src/components/voice-embed.js: 21.49KB < maxSize 25KB
    PASS ./build/esm-bundled/src/components/voice-embed.js: 18.61KB < maxSize 20KB
    PASS ./build/es5-bundled/src/components/lazy-resources.js: 17.36KB < maxSize 20KB
    PASS ./build/esm-bundled/src/components/lazy-resources.js: 12.26KB < maxSize 15KB
    PASS ./build/es5-bundled/index.html: 9.47KB < maxSize 14KB
    PASS ./build/esm-bundled/index.html: 3.15KB < maxSize 14KB
    File size reduced: -37%
    ESModules bundle < ES5 bundle
    CDNで別の
    ファイルを配信
    Method 1
    Deliver another assets file by CDN.

    View Slide

  78. ● Web Share API
    ● Network Information API
    ● Intersection Observer
    ● Vibration API
    ● etc...
    Provide better experience with
    new technologies
    新しい技術を
    より良い体験に
    Web Share API Original Dialog
    Method 2

    View Slide

  79. ● Web Share API Only Safari,
    Android chrome
    新しい技術を
    より良い体験に
    Method 2

    View Slide

  80. 画像に代替テキストを設定する
    Checklist. 12 a11y, SEO
    Provide text alternatives for any non-text content.

    View Slide

  81. 画像の内容を伝える
    あらゆるユーザーエージェントに
    Provide content of images to various user agents.

    View Slide

  82. Screen reader, Google bots, etc...
    画像の内容を伝える
    あらゆるユーザーエージェントに
    Provide content of images to various useragents.

    View Slide

  83. 画像の”内容”を伝える
    Convey “content” of images.

    View Slide

  84. マイページ
    投稿する
    alt=”投稿”
    画像の”内容”を伝える
    Convey “content” of images.
    新規タブで開く

    View Slide

  85. 下で説明
    投稿のイメージ画像
    alt=””
    ”意味”を持たない場合
    Some images have no meaning.

    View Slide

  86. 文字のコントラストは4.5:1以上
    Checklist. 13 a11y
    The text has a contrast ratio of at least 4.5: 1.

    View Slide

  87. 閲覧の状況で見え方は違う
    How user sees it depends on the situation.
    ● 視力 Sight
    ● 色覚異常 Color blindness
    ● 外出先 Outside
    ● etc…

    View Slide

  88. 画像引用:
    信号機に夕日が差し込み反射すると何色かまったくわからないことがある
    https://dm2.co.jp/2015/11/shingouki.html
    Situation to view ?
    閲覧の状況?

    View Slide

  89. とはいえ現実はキビシイ
    But the reality is so difficult.

    View Slide

  90. Ameba Green: 4.26:1
    とはいえ現実はキビシイ
    But the reality is so difficult.
    Dark Green
    Green
    Light Green

    View Slide

  91. Too low (2.8:1)→ little higher (4.3:1)
    Use high contrast color for text
    ● Ameba Green: for logo, icon / 4.26:1
    ● Dark Green: for text / 4.66:1
    1か0かではなく、まずは向上する
    At first, we improve contrast a little more than now.

    View Slide

  92. 色だけで説明しない
    Checklist. 14 a11y
    Do not convey information only with visual color meaning.

    View Slide

  93. Which is active ?
    Before

    View Slide

  94. Which is active ?
    Before /
    in monochrome

    View Slide

  95. Which is active ? 1.08:1

    View Slide

  96. 色の見え方は人それぞれ
    色の違いなしに見分けられるのが良い
    → モノクロで確認する
    Make identification possible without color distinction. So, check in monochrome.
    Depending on the person, the way they see color changes.

    View Slide

  97. 画像引用:
    信号機に夕日が差し込み反射すると何色かまったくわからないことがある
    https://dm2.co.jp/2015/11/shingouki.html
    and situation to view
    閲覧の状況

    View Slide

  98. Which is active ?
    After

    View Slide

  99. Which is active ?
    After /
    in monochrome

    View Slide

  100. 要素の選択は適切に
    Checklist. 15 a11y, SEO
    Select appropriate elements according to the specification.

    View Slide

  101. クロちゃんのブログ
    クロちゃんのブログ
    Machine Readability
    Bot, Screen Reader, RSS, SNS medias, ...

    View Slide

  102. ,
    ● Keyboard accessible
    ● Visible focus
    「らしさ」を再実装しない
    Do not redevelopment it’s “likeness”.

    ● nothing

    View Slide

  103. キー操作だけで利用できる
    Checklist. 16 a11y
    Make all functionality available from keyboard.

    View Slide

  104. まだ見ぬ未来のデバイス、ちょっと変わったUI
    キー操作できる
    If it can be operated with the keyboard,

    色々なデバイスで操作できる
    it can be operated with various devices

    View Slide

  105.             ちょっと変わったUI
    Slightly odd UI component

    View Slide

  106. 操作対象が移る場合、特に注意
    Be especially careful when the operation target changes.
    Example 1

    View Slide

  107. Accessible Samples
    WAI-ARIA Authoring Practices 1.1
    https://www.w3.org/TR/wai-aria-practices

    View Slide

  108. page navigation
    on SPA
    Example 2

    View Slide

  109. if (prevPage && prevPage !== currentPage) {
    const title = `${title} | ${siteName}`;
    const announcer =
    document.getElementById('js-announcer');
    window.document.title = title;
    if (announcer) {
    announcer.innerHTML = documentTitle;
    }
    document.body.focus();
    }




    Move focus,
    Read title
    Example 2

    View Slide

  110. Move focus,
    Read title
    Example 2

    View Slide

  111. フォーカスを可視化する
    Checklist. 17 a11y, UX
    Visualize keyboard focus
    indicator.

    View Slide

  112. focusは
    何を操作するか
    The focus indicates what to
    operate.

    View Slide

  113. a, button {
    outline: none;
    }
    focusを
    可視化する
    Visualize the focus style.

    View Slide

  114. focusを
    可視化する
    a, button {
    outline: none;
    }
    Visualize the focus style.

    View Slide

  115. .drawer-list > a {
    color: var(--app-dark-text-color);
    font-size: 1.4rem;
    -webkit-tap-highlight-color:
    var(--app-focus-background-color);
    outline: none;
    text-decoration: none;
    }
    .drawer-list > a:focus {
    background-color:
    var(--app-focus-background-color);
    }
    スタイル適用
    → 標準スタイル削除
    Apply your own focus style and then
    remove the default style.

    View Slide

  116. .drawer-list > a {
    color: var(--app-dark-text-color);
    font-size: 1.4rem;
    -webkit-tap-highlight-color:
    var(--app-focus-background-color);
    outline: none;
    text-decoration: none;
    }
    .drawer-list > a:focus {
    background-color:
    var(--app-focus-background-color);
    }
    スタイル適用
    → 標準スタイル削除
    Apply your own focus style and then
    remove the default style.

    View Slide

  117. スクロール位置を復元
    Checklist. 18 UX
    Restore scroll position when returning to the page.

    View Slide

  118. 非同期コンテンツでは
    うまくいかない?
    Can't restore scroll position with
    asynchronous rendering?

    View Slide

  119. janpaul123/delayed-scroll-restoration-polyfill

    View Slide

  120. if (isChrome) {
    if ('scrollRestoration' in window.history) {
    // ブラウザの復元処理を使わない
    window.history.scrollRestoration = 'manual';
    }
    var scriptEl = document.createElement('script');
    scriptEl.setAttribute('src',
    'node_modules/delayed-scroll-restoration-polyfill/
    index.js');
    scriptEl.setAttribute('defer', 'defer');
    document.body.appendChild(scriptEl);
    }
    基本は
    ブラウザ任せ
    Use browser's standard
    process.

    View Slide

  121. if (isChrome) {
    if ('scrollRestoration' in window.history) {
    // ブラウザの復元処理を使わない
    window.history.scrollRestoration = 'manual';
    }
    var scriptEl = document.createElement('script');
    scriptEl.setAttribute('src',
    'node_modules/delayed-scroll-restoration-polyfill/
    index.js');
    scriptEl.setAttribute('defer', 'defer');
    document.body.appendChild(scriptEl);
    }
    マニュアル
    操作にする
    Use manual operation if
    possible.

    View Slide

  122. 修正・削除ができる
    Checklist. 19 UX, a11y
    Can be edited and deleted.

    View Slide

  123. 人間は間違える生き物
    UIも最適じゃないかもしれない
    完璧よりも、ミスを許容できることが重要
    Human beings make mistakes.
    It’s important to be able to fix mistakes.

    View Slide

  124. ● 重要なデータはindexedDBへ保存
    ● ブラウザバック時に保存を提示
    記事更新時に保存→提示
    Save to indexdDB every time important data is updated,
    and restore it at the required timing.

    View Slide

  125. 継続的なモニタリング
    Checklist. 20 UX, Perf
    Reduce monitoring cost by automation.

    View Slide

  126. System
    Configuration
    GCS
    /api/*
    /assets/*
    PURGE

    View Slide

  127. Datadog
    https://app.datadoghq.com/

    View Slide

  128. Stackdriver
    https://cloud.google.com/stackdriver/

    View Slide

  129. System
    Configuration
    Error
    GCS
    /api/*
    /assets/*
    PURGE

    View Slide

  130. Alert to Slack

    View Slide

  131. Sentry
    https://sentry.io/

    View Slide

  132. Speedcurve
    https://speedcurve.com/

    View Slide

  133. Firebase Performance Monitoring
    https://firebase.google.com/docs/perf-mon/
    Trying out firebase

    View Slide

  134. GCS
    /api/*
    /assets/*
    PURGE
    社内
    ログシステム
    System
    Configuration
    投稿監視
    チーム
    DELETE
    PATCH
    Error
    pub/sub
    Error Error

    View Slide

  135. Good Night
    However, until you hear an alert

    View Slide

  136. View Slide

  137. no genre title
    13 a11y 文字のコントラストは4.5:1以上
    14 a11y 色だけで説明しない
    15 a11y 要素の選択は適切に
    16 a11y キー操作だけで利用できる
    17 a11y,UX フォーカスを可視化する
    18 UX スクロール位置を復元
    19 UX,a11y 修正・削除ができる
    20 UX 継続的なモニタリング
    21 UX ストレスのない遷移とローディング
    22 UX レイアウトを固定する
    23 a11y,UX 突然音を出さない
    24 Security セキュリティ監査する
    no genre title
    1 UX 適切なレンダリングパターンを選択
    2 Perf 安定したサーバレスポンス
    3 Perf 圧縮したメディアフォーマットを利用
    4 Perf,UX リソースを必要なタイミングで読み込む
    5 Perf Webパフォーマンスを監視
    6 UX Off the main thread
    7 UX オフラインでも利用できる
    8 UX モバイルでもデスクトップでも使える
    9 PWA メタデータを提供
    10 DX OSSのように開発
    11 UX Progressive Enhancement
    12 a11y,SEO 画像に代替テキストを設定する
    Web App Checklist
    http://bit.ly/web_app_checklist

    View Slide

  138. ● アメブロ2019: こえのブログでのPWA | CyberAgent Developers Blog
    https://developers.cyberagent.co.jp/blog/archives/20506/
    ● アクセシブルなブログ開発、 その後どうなったの
    https://www.slideshare.net/MarinaToki/ss-135424096
    ● こえのブログでのPWA ~ 開発現場編 ~ / Koe-No-Blog PWA - Speaker Deck
    https://speakerdeck.com/herablog/koe-no-blog-pwa
    ● こえのブログでのPWA ~ PWA編 ~ / PWA Night Vol.4
    https://speakerdeck.com/herablog/pwa-night-vol-dot-4
    Related Slides

    View Slide

  139. AMA B-4
    Thank you!
    https://app2.sli.do/event/ppjicyvn/live/questions

    View Slide