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! 🙌

2e0e89a34badf79dcff642cb7b5c126f?s=128

Kazunari Hara

May 18, 2019
Tweet

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
  2. 原 一成 Kazunari Hara Web Developer @ CyberAgent Twitterer Beer,

    Cat, Karting, Family @herablog
  3. ときまり tokimari Frontend Engineer @ CyberAgent Accessibility Police Beer, Cat,

    Knitting @tokimariri
  4. None
  5. 喋るだけで ブログになる 投稿機能 Post function that creates blog entry just

    by speaking
  6. 幅広いユーザー 投稿/閲覧スタイル Post function that creates blog entry just by

    speaking お風呂中にも子供を抱っこしていても、料理中でも寝 ながらでも投稿、閲覧ができます
  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
  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
  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
  10. 適切なレンダリングパターンを選択 Perf Checklist. 01 Select appropriate rendering pattern for your

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

  12.   TTI = FCP   Inflexible Server Side Rendering ロジックは

    サーバー側 GET / Network JS TTIはJS構成 に依存する Logics are in server side TTI depends on JS architecture
  13. Optimized Server-Side Web Application In 2018 https://developers.cyberagent.co.jp/blog/archives/16818/

  14. Server Side Rendering Website アメーバニュース Ameba News はやいFCP https://news.ameba.jp/entry/20190516-669/をMobile、Simulated Fast

    3G、4x CPU Slowdown、ローカル環境で測定。 Fast FCP
  15. SSR with hydration   Flexible   TTI >>>> FCP データを使ってク

    ライアントで描画 GET / Network JS DATA={} bundle.js render(DATA) Client rendering with initial data
  16. アメブロ2016 ~ React/ReduxでつくるIsomorphic web app ~ https://developers.cyberagent.co.jp/blog/archives/636/

  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
  18. Client Side Rendering   Flexible, Fast TTFB   TTI >>>>

    FCP GET / FCP TTI Network JS bundle.js render() FCPはもっと遅く なることも
  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
  20. Lighthouse Performance 程々にはやいFCP とはやいTTI https://voice.ameba.jp/をMobile、Simulated Fast 3G、4x CPU Slowdown、ローカル環境で測定。 So-so

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

  22. Server response is fundamental for web performance. サーバレスポンス は根本的 サーバレスポンスが遅い

    と何も表示されない Waiting with blank page when server response is too slow.
  23. Reasons for server-side latency. サーバ遅延の要因 • 地理 Location • 計算量

    Computation • キャパシティ Capacity • リダイレクト Redirect • DBクエリ DB Queries ...
  24. Use CDN for edge side caching.こえのブロ グで利 CDNキャッシュ の利用 高キャッシュヒット率で

    オリジンサーバーに 1度しかリクエストしない Only requests content to the origin server once because of high cache hit ratio.
  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
  26. Event-driven cache purging. イベント駆動 キャッシュパージ onDeploy onUpdate Purging with Surrogate

    Key web/release entry/${ID}
  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
  28. 圧縮したメディアフォーマットを利用 Select optimized media format. Perf/UX Checklist. 03

  29. According to Lighthouse, the size of images could still be

    reduced. まだまだ減らせる画像容量
  30. List of image file formats 画像フォーマット • JPEG • Progressive

    JPEG • PNG • WebP • SVG • Animation GIF 画質を指定して利用 ファイルサイズに注意 高圧縮 動画のが軽いことも
  31. ImageOptim https://imageoptim.com/

  32. List of image CDN providers. Image CDN • Akamai •

    Cloudinary • Imgix • Fastly • Hayabusa
  33. List of image CDN providers. Image CDN • Akamai •

    Cloudinary • Imgix • Fastly • Hayabusa こえのブログ で利用
  34. サムネイルは低 クオリティ指定 自動判定で WebP配信 Pixel ratio指定 /image.jpg?auto=webp /image.jpg?dpr=${window.devicePixelRatio} /image.jpg?quality=60

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

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

  37. ブラウザ標準 遅延読み込み Native lazy-loading <img loading=”lazy” ...>

  38. Feature Detection if ('loading' in HTMLImageElement.prototype) { // Use Native

    lazy-loading } else { // Use Intersection Observer (or polyfill) }
  39. スクリプトの遅延読み込み index.html (Entrypoint) voice-app.js (App shell) voice-home.js (Fragment) voice-editor.js (Fragment)

    <script type=”module”> import(‘’) import(‘’) Script lazy-loading
  40. Webパフォーマンスを監視 Monitor web performance constantly. Perf Checklist. 05

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

  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
  43. “Performance budgets are not just thresholds. Much like a financial

    budget, they're something consciously spent.“ Addy Osmani Perf指標を財政予算に見立てて管理
  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
  45. Off the main thread Perf Checklist. 06

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

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

    Worker WAV MP3
  48. Comlink https://github.com/GoogleChromeLabs/comlink

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

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

    is not always fast.
  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
  52. Workbox.routing.registerNavigationroute( '/index.html', { whitelist: [ /^\/editor/, /^\/embed/, ... ] },

    ); 特定パスへのナビゲー ションリクエスト時に プリキャッシュした index.htmlを返却する Return precache HTML when navigation request Service Worker Precache
  53. オフラインでの 録音が可能 Offline recording is available.

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

  55. and more devices...

  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.
  57. レスポンシブ 画像 Responsive Images <img height="80" width="80" src="toshi.jpg?size=80" srcset=" toshi.jpg?size=160

    2x, toshi.jpg?size=240 3x " />
  58. Image CDN /image.jpg? width=640& dpr=${window.devicePixelRatio}

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

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

  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
  62. Meta for Social Media. <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="@ameba_official">

    <meta name="twitter:title" content="1月24日のこえ"> <meta name="twitter:description" content="こんばんは..."> <meta property="twitter:image" content="https://voice.ameba.jp/share.jpg"> <meta property="fb:app_id" content="311629842256842"> <meta property="og:type" content="website"> <meta property="og:url" content="https://voice.ameba.jp/embed/"> <meta property="og:title" content="1月24日のこえ"> <meta property="og:image" content="https://voice.ameba.jp/share.jpg"> SNS用 メタデータ
  63. The new evergreen Googlebot https://webmasters.googleblog.com/2019/05/the-new-evergreen-googlebot.html SEOハックに さようなら Goodbye SEO Hacks.

  64. YHAAAAAAAA!

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

  66. README.md

  67. CONTRIBUTING.md

  68. CHANGELOG.md

  69. よいLGTM Good LGTM makes developers comfortable.

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

  71. None
  72. Progressive Enhancement Checklist. 11 UX

  73. こえのブログの”投稿” =アメブロのプラスの投稿機能 投稿の推奨環境を制限 • iPhone Safari 11.3~ • Android Chrome

    61~ “Posting by voice” is an additional feature of Ameblo. Limit browsers:
  74. • IE11~ • Edge • Android OS 5~ • iOS11~

    こえのブログの”閲覧” =アメブロの標準機能 “Browsing” Koe-no-blog is a standard feature of Ameblo. User can experience it by followings browsers:
  75. Progressive Enhancement Graceful Degradation 動作しないブラウザを起点に機能を考えない Don't think the feature based

    on the legacy browser that doesn’t work. Kazunari Hara
  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
  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.
  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
  79. • Web Share API Only Safari, Android chrome 新しい技術を より良い体験に

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

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

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

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

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

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

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

    of at least 4.5: 1.
  87. 閲覧の状況で見え方は違う How user sees it depends on the situation. •

    視力 Sight • 色覚異常 Color blindness • 外出先 Outside • etc…
  88. 画像引用: 信号機に夕日が差し込み反射すると何色かまったくわからないことがある https://dm2.co.jp/2015/11/shingouki.html Situation to view ? 閲覧の状況?

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

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

    Dark Green Green Light Green
  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.
  92. 色だけで説明しない Checklist. 14 a11y Do not convey information only with

    visual color meaning.
  93. Which is active ? Before

  94. Which is active ? Before / in monochrome

  95. Which is active ? 1.08:1

  96. 色の見え方は人それぞれ 色の違いなしに見分けられるのが良い → モノクロで確認する Make identification possible without color distinction.

    So, check in monochrome. Depending on the person, the way they see color changes.
  97. 画像引用: 信号機に夕日が差し込み反射すると何色かまったくわからないことがある https://dm2.co.jp/2015/11/shingouki.html and situation to view 閲覧の状況

  98. Which is active ? After

  99. Which is active ? After / in monochrome

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

    the specification.
  101. <h1>クロちゃんのブログ</h1> <p>クロちゃんのブログ</p> Machine Readability Bot, Screen Reader, RSS, SNS medias,

    ...
  102. <a>, <button> • Keyboard accessible • Visible focus 「らしさ」を再実装しない Do

    not redevelopment it’s “likeness”. <div> • nothing
  103. キー操作だけで利用できる Checklist. 16 a11y Make all functionality available from keyboard.

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

    = 色々なデバイスで操作できる it can be operated with various devices
  105.             ちょっと変わったUI Slightly odd UI component

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

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

  108. page navigation on SPA Example 2

  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(); } <body tabindex=”-1”> <div id="js-announcer" aria-live="assertive"></div> … </body> Move focus, Read title Example 2
  110. Move focus, Read title Example 2

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

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

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

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

    focus style.
  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.
  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.
  117. スクロール位置を復元 Checklist. 18 UX Restore scroll position when returning to

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

  119. janpaul123/delayed-scroll-restoration-polyfill

  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.
  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.
  122. 修正・削除ができる Checklist. 19 UX, a11y Can be edited and deleted.

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

    be able to fix mistakes.
  124. • 重要なデータはindexedDBへ保存 • ブラウザバック時に保存を提示 記事更新時に保存→提示 Save to indexdDB every time

    important data is updated, and restore it at the required timing.
  125. 継続的なモニタリング Checklist. 20 UX, Perf Reduce monitoring cost by automation.

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

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

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

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

  130. Alert to Slack

  131. Sentry https://sentry.io/

  132. Speedcurve https://speedcurve.com/

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

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

    DELETE PATCH Error pub/sub Error Error
  135. Good Night However, until you hear an alert

  136. None
  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
  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
  139. AMA B-4 Thank you! https://app2.sli.do/event/ppjicyvn/live/questions