「JSConf JP(Day2)」に参加してきました

  • JSConf JPに参加してきました。
  • 2日目の参加メモです

jsconf.jp

タイムテーブル

時間 タイトル 発表者
11:00- 時間はただの幻想である… JavaScriptにおいては Jennifer Wong
InversifyJSを用いたレイヤードアーキテクチャの構築 奥野 賢太郎
Vue.js で D3.js を使ったインタラクティブなデータの可視化 Shirley Wu
11:30- ストリームの人生 Dominic Tarr
Build and scale multiple Voice application by using TypeScript Hidetaka Okamoto
13:00- Web の体積 Jxck
正攻法はあるのか !? 泥臭く戦った Node.js バージョンアップ一部始終 Masato Nishihara
パスワードは90年代の代物だ Sam Bellen
13:30- JavaScript, Rust and Wasm Walk into a Ramen Shop ... Irina Shestak
Migration from React Native to PWA ohbarye
npm i -g @next-and-beyond: Building the future of package management Claudia Hernández
14:15- JSConf Panel Talks Jan Lehnardt and Yosuke Furukawa
GraphQLを用いたECサイトにおけるパフォーマンス改善 澤井宣彦
Minimum Hands-on Node.js 栗山 太希
14:45- 悪用された npm パッケージの分析 Jarrod Overson
JavaScriptのままでTypeScriptを始める 高梨ギンペイ
15:30- Browser APIs: 知られざるヒーロー達 Rowdy Rabouw
Your benchmark may not guide a real application performance Tetsuharu OHZEKI
16:00- Anatomy of a Click Benjamin Gruenbaum
JavaScriptとSwift/JavaをつなげるCapacitorと、これからのWeb Frontned. 榊原昌彦
Recruit Speed Hackathon 新井 智士
16:45- AIとJavaScript による生物認識 Jonny Kalambay
大規模アプリケーション開発でのElm実践 海老原 圭吾
17:15- Pika: レジストリの再創造 Fred K. Schott
最新のWeb技術でIoT開発をする 木戸 康平

InversifyJSを用いたレイヤードアーキテクチャの構築

  • 奥野 賢太郎さん

密結合とは

  • 修正を加えた時にその影響箇所が見つけづらい状態
    • 予期しないところに影響が及ぶかもしれない状態
    • DBの構造
    • 外部サービス
    • APIの構造
    • 画面の構造
    • 画面の入力フォームの構造のままテーブル設計してしまった
    • 画面の構成変えたけどDBいじる余裕ないから無理やり対応することに・・・
  • 抽象化する中間の層が必要

レイヤードアーキテクチャ

  • DDD
    • Domain Driven Design
  • MDD
    • Model Driven Development
  • Repository

DIP

  • InversifyJS
    • DIの機能を提供するライブラリ
    • constructor injectionできる
    • TypeScriptで書いた方が相性が良い
  • TSyringe
    • Microsoft
    • InversifyJSと同じ感じのやつ
    • 好みではあるけど登壇者はこっちの方が好き
  • レイヤーごとにmodel objectを用意する
    • バグが起きたときの影響範囲がわかりやすいように寿命を短くするとよい
  • value objectを作るようにする
    • バリデーションはconstructorで
  • knex
    • ORMapper

Build and scale multiple Voice application by using TypeScript

  • Hidetaka Okamotoさん

スマートスピーカーのバックエンド

  • 音声/言語処理系の知識がなくても開発できる
    • Speach To Textや自然言語処理はサービス側の責務
    • バックエンドには処理後のJSONが送られる
  • Webhookの開発と同じような感じ
    • SlackやLINEのbotに近い
  • 文脈を覚えておくためにDBも持っておくことが多い

Alexa開発

  • ask-adkを使う
  • スキルが増えると起こる課題
    • スキルが増えるとLambdaも増えるからruntimeの更新など面倒
    • 同じような処理がいろんなスキルに存在してしまう
  • 多機能な1スキルか単機能な複数スキルか
    • 単機能なスキルの方が使いやすい
    • でも見つけてもらうのが大変かも
  • ServerlessFrameworkを使うと便利
    • 全部yamlで管理できる
    • runtimeのアップデートなども設定かえるだけ

まとめ

  • VUIはWebhookライク
  • in/outのフォーマットが一定のためTS相性良し
  • 汎用FWがまだない

正攻法はあるのか !? 泥臭く戦った Node.js バージョンアップ一部始終

  • Masato Nishiharaさん

背景

  • Node6を使ってたが2019/4にEOL
  • Node8は2019/10にEOLだったので一気に10に
    • 10のEOLは2021/4

やったこと

  • Node変更差分確認
  • 依存パッケージの変更差分確認
  • 全機能テストを複数回

パッケージの差分

  • 依存ライブラリのリリースノート全部見たりするのは現実的でない
  • Node10に対応しているか明記していないものもあった
  • =>全機能テストで動けばよいとすることに

全機能テスト

  • ブラウザバリエーションもあるので大変
  • 1回目で不具合を出して対応して2,3回目もやった

リリース後

  • CPU100%にはりつくトラブル
  • スレッドの切り替えをする処理が多発していた
    • Nodeはシングルスレッドじゃないのか?
    • 内部的にはマルチスレッドで動くところもある
    • libvuの中でマルチスレッドを利用している
  • このケースでは原因はDBサーバだった
    • 障害のあったサーバからDBサーバへのアクセスが遅延していた

まとめ

  • こまめに上げるようにするとよさそう
  • コアな部分だけでも自動テストはあった方がいい

Migration from React Native to PWA

  • ohbaryeさん

React NativeからPWAへ

  • iOS/Andorid対応のRNアプリをiOS/Android/Web対応のPWAにする
    • 後者のiOS/AndroidはWebViewでPWAを表示する

なぜReactNativeだったか

  • プッシュ通知など使いたいからスマホアプリがいい
  • iOSエンジニアがいなかった

BYOD化

  • 端末を用意してインストールして渡してた
    • 端末配布をやめてBYOD化することにした
    • Android版の提供も始めることにした

マルチプラットフォーム対応

  • iOSで動くのにAndroidで動かないとかがかなりあった
  • JSのエラーなのかライブラリの中身が悪いのかネイティブのレイヤーが悪いのか

パッケージ管理

  • ReactNativeはnpmでライブラリ管理してるがその先にiOS/Androidのライブラリがある

ビルドデプロイシステム

脱ReactNativeの選択肢

  • PWA
  • Nativeで書き直す?
  • Flutter
  • => ブラウザで見たいという要件もあったのでPWAで
    • React使った

通知

  • Push Notificationの実現
    • AndroidはWebでも使える
    • iOSはWebViewとして使うのでネイティブの機能を使う

WebViewで苦労したこと

  • キャッシュのレイヤーが増えることに注意
  • WebViewのキャッシュを無効化するメソッド用意したりとか

PWAで供料したこと

  • Android ChromeだとアイコンにつけるバッヂはまだExperimental
  • フォアグラウンドでの通知がAndroid PWAだけ挙動が違った

テスト

  • cypressでintegrationテスト書いてる
  • ReactNative時代はスナップショットテストとかやってた

運用してみて

  • Webなので即時反映されるのでいい

まとめ

  • チームメンバーのスキルセットにあった技術選定が大事
    • 開発できる = 運用できるではない
  • モバイルアプリに近い体験要求されてもWebでもできるかも

GraphQLを用いたサイトにおけるパフォーマンス改善(ECサイトを題材に)

  • 澤井宣彦さん

背景

  • 歴史が長くページ遷移が遅い
  • 全社のリブランディング
  • ページ遷移の改善
  • 技術スタックの改善

リニューアル

  • フロントはReactをTSで
  • Backendは既存RailsAPI
  • API定義はGraphQL
    • トップページをリッチにしたい構想
    • フロント側に自由度をもたせたいから

パフォーマンス改善

計測

  • 実機で行うテスト
  • 合成環境で行うテスト
    • PageSpeed Insighrsを使った

ボトルネックの特定

  • ChromeのAudit
  • Opportunitiesの改善項目

改善

フロント側の改善
サーバ側の改善
  • APMを活用
    • 既に入れていたDataDogを活用
  • N+1のDBアクセス問題
    • batch-loader(rubyの場合)などを使って対応するようにする
QueryとSchemaの改善
  • ページングのない配列のrequest
    • 関連するレコードが全件取得されるので性能が劣化
    • ページングをつけて件数指定する
    • schemaのlinterで未然に防げそう
  • 全く使ってないデータを取得している
    • queryを消せばよい
    • なぜ画面に紐付いてないqueryが書かれてしまうか
    • FragmentとColocation
    • Fragment
      • queryを部分的に切り出したもの
      • 再利用できる
      • 部分定義できる
    • Colocation
      • Fragmentを集約して1つのqueryにまとめる
    • Reactコンポーネントの階層とqueryの階層をあわせるようにする

今後

  • Cacheの活用を検討
    • リアルタイム性が低いコンテンツもある
    • ゲストユーザは同じものが基本的に表示される
    • CDNのレイヤーでHTML/responseどちらもできるはず

JavaScriptのままでTypeScriptを始める

  • 高梨ギンペイさん

TypeScriptのいいところ

  • JSのスーパーセットであること
  • 型を持つこと

Typed-JavaScript

型がつくと何ができるようになるか

  • バリデーションできる
    • 関数を呼ぶ時にどんな引数を渡さないといけないか?
      • ドキュメント見る?
      • 動かしてみる?
      • 型があればすぐに分かる
      • エディタが対応してればその場でわかる
  • エディタの補完がきく
    • 自分で作ったAPIの補完も型を用意しておけば補完される
    • 標準関数なんかもググらなくてもその場で候補がでる
  • リファクタリングがしやすい
    • 変数名後から変えたり型を後から変えたり
    • 変更漏れがあればコンパイルエラーになってくれる

使い方

  • tsconfig.json
    • allowJsをtrueで.js対象になる
    • checkJSをtrueでjsもチェック対象になる
    • noEmitをtrueで型チェックだけするようになる
    • checkJSをfalseにしてチェックしたいファイルにコメントで@ts-checkつけるでもいける

まとめ

Your benchmark may not guide a real application performance

  • Tetsuharu OHZEKIさん

ソフトウェアのパフォーマンス

  • 遅いソフトウェアより速いソフトウェアの方がよい
  • どのように速くするか
    • Dont't guess, measure
  • ベンチマークを使う

ベンチマーク

  • シナリオに沿ったベンチマークになってますか?
  • 一般的な指標はベンチマークの1つでしかない
    • Lighthouseだけやってればいいわけではないケースも多い

JSの最適化

  • 一度の実行だと数ミリsecで差がわかりづらい
    • じゃあ数万回実行しよう
    • =>それでいいの?
      • 何度も実行されるとJSVMが複数レベルで最適化してくれる
      • その処理は何度も呼ばれるような処理なのか?

どのように改善を進めるか

  • プログラムを速くするには遅くなるようなことをやらないことが重要
  • CIとしてベンチマークを計測して継続してプロットするといい
    • 容易に起動できて再現可能であるようにする
    • 細かい上下は必ず起きる
    • 長期での傾向をチェックする

まとめ

  • パフォーマンスを改善するにはリアルなシナリオが必要
  • 闇雲に測定するのではなくリアルなシナリオに基づくこと
  • ベンチマークテストをテストケースの1つとして追加し実行できるようにすること
  • まずはどのように使われていてどのように速くなると嬉しいのか調べるところから

JavaScriptとSwift/JavaをつなげるCapacitorと、これからのWeb Frontned.

  • 榊原昌彦さん

Capacitor

  • Webでアプリを作ってWebViewで表示できる
  • ネイティブの機能にアクセスできる
  • デスクトップアプリとしても作れる

Capacitorの使い勝ったあ

  • @capacitor/core
  • @capacitor/cli

iOS

  • SwiftをどうやってHTML/JSにつなげるのか
    • npx cap init
    • WebViewを100%表示されるものができる
    • Poddileでnode_modulesの中から引っ張ってきてる
  • HTML/JSがどうやってSwiftにアクセスしているか
    • ブリッジがwindowオブジェクトに値を埋め込んでる
  • Androidもだいたい同じ

UI

  • iOS/Androidそれぞれガイドに沿った見た目にできる

「JSConf JP(Day1)」に参加してきました

  • JSConf JPに参加してきました。
  • 1日目の参加メモです

jsconf.jp

タイムテーブル

時間 タイトル 発表者
13:00- Opening talk yosuke furukawa
13:30- The State of JavaScript Raphaël Benitte and Sacha Greif
14:15- 「繋がり」の可視化 Nadieh Bremer
WebAuthnで実現する安全・快適なログイン Eiji Kitamura / えーじ
JavaScript AST プログラミング: 入門とその1歩先へ Takuto Wada
14:45- オープンソース」の定義 Henry Zhu
覚醒するアクセシビリティ Lena Morita
4年分のプロシージャルなJS Andy Hall
15:30- Building and Deploying for the Modern Web with JAMstack Guillermo Rauch
Wrap-up: High Performance JavaScript Sho Miyamoto
JS開発者のためのSEOテクニック Martin Splitt
16:00- Write What Not How Jorge Bucaran
How to Boost Your Code with WebAssembly FUJI Goro / @gfx
Playing Pokémon Together with Node.js Samuel Agnew
16:45- Deno - JavaScript の新たな道筋 Kitson Kelly
Streams APIをちゃんと理解する 加藤 健志
You might also like... Maria Clara
17:15- Headers for Hackers Andrew Betts
Make it Declarative with React Toru Kobayashi
Web Accessibilityのすゝめ Nazanin Delam
18:45- 予測的 Prefetching によるパフォーマンス改善 Praveen Yedidi
18:55- Web Components era phase 2 Yoshiki Shibukawa
19:05- Cache Me If You Can Maxi Ferreira
19:15- Node.js でつくる Node.js - WASM/WASI ミニミニコンパイラー がねこまさし
19:25- React アプリのライセンス違反について dynamis

The State of JavaScript

  • Raphaël Benitte
  • Sacha Greif

JavaScriptの歴史

stateofjs.com

stateofcss.com

ES2019

  • Array.flat()
  • Object.formEntries()
  • Optional Catch Binding

フレームワーク

  • React
    • 使ってる人多いしそのほとんどがまた使いたいと言ってる
  • Vue
    • Reactよりは少ないけどのびてる
  • Svelte
    • 使ってる人は少ないけど学んでみたいという人は多い
  • Gatsby
    • 横ばい
  • Next.js
    • のびてる
  • ホスティングサービスも充実してきている
    • Netlify
    • Now
  • TypeScriptは60%くらいの人が使っている

WebAuthnで実現する安全・快適なログイン

  • Eiji Kitamuraさん

パスワードの問題点

  • Weak
  • Forgotten
  • Reused
  • Stolen

パスワードどうやって盗まれるか

ハックされる確率

  • キーロガーだと通常の40倍
  • フィッシングだと500倍
    • パスワード以外の情報もとられているケースが多いから
  • 被害の80%がフィッシング

パスワードが盗まれないようにする対策

  • 2段階認証
  • ワンタイムパスワード
    • SMS
    • フィッシングには弱い
    • 短時間有効なパスワードでもその場で送られたら意味がない
  • そこでWebAuthn

WebAuthn

  • これまでよりも強力なブラウザの認証
    • EdgeもFFも対応
    • Safariは部分的(でも時期に対応するだろう)
  • ハードウェアの鍵を使う(Authenticator)
  • 公開鍵暗号を活用した方式
  • Authenticatorにキーペアを作らせる
    • 公開鍵をサービスに送ってRegistrationする
  • 秘密鍵で署名をしてそれをサービスに送る
    • サービスは公開鍵で検証
    • 同じハードウェアを持っている人であると証明できる
  • 鍵はWebサイトのオリジンと紐付いて生成される
    • フィッシングに強い
    • たとえ盗んでも成功しない

二要素認証

  • ハードウェアをもっているという認証 + 記憶による認証
    • 多要素と多段階は違う
    • 記憶、所持、生体といった要素を複数組み合わせるのが多要素認証
  • セキュリティキー
    • PCに接続するとブラウザにポップアップ出る
    • ジェスチャーをすると署名を生成して送ってくれる
    • 名前をつけて登録する
      • キーをなくしてしまったら消せるように
    • SMS Codeも強いけどセキュリティキーの方が強固
  • 署名をサーバに送って登録されているものと同一であることを確認する
    • このサーバをFIDOサーバと呼ぶ

Authenticator

Roaming Authenticator

  • Authenticatorの1つにセキュリティキーがある
    • U2FかFIDO2に対応しているAuthenticatorであれば間違いない
  • R持ち運びできるからoaming Authenticatorと呼ばれる

Platform Authenticator

  • バイスに埋まってるから専用のものを買わせる必要がない
  • 指紋認証などで使うことも多いけど端末のロックNoなども同等の扱い
  • Local User Verification(LUV)
    • ローカルで生体と所持の二要素認証する
    • スマホで生体認証とかするとこれが実現できる
    • 生体情報はデバイスにしかないから安心(だからLocal User Verification)
      • つまり新しいデバイスに替えたら再登録が必要

再認証(Re-authentication)

  • お金を払う手前とかで再度認証させるやつとか
    • ログインしてる状態でもう一度認証を求めるやつ
  • Pixel4の顔認証はまだ使えないけどChrome79から使える

参考

  • https:/goo.gle/FIDO
  • WebAuthnのコードラボもある

覚醒するアクセシビリティ

アクセシビリティ

  • 蔑ろにされることが多い
    • 不便と思う人を低く見積もりすぎ
    • 誰でも使えるようになることのよさを知らない
  • 障害者/健常者という区別がよくない
    • 環境や状況によって不便に感じることは誰でも起こりうる

Webにおけるアクセシビリティ

  • Webは世界中どこからでもアクセスできる
    • ブラウザの拡張などでカスタマイズできる

広義のアクセシビリティ

Wrap-up: High Performance JavaScript

  • Sho Miyamotoさん

intro

Layers

  • JavaScriptのレイヤー
    • Product
    • Runtime
      • Node
      • ブラウザ
      • Electron
    • Engine
  • JavaScriptの実装
    • サーバサイド
    • クライアントサイド

RuntimeとEngine

  • RuntimeとEngineどう違うか
    • Engine
      • parser/compile/execute
      • JIT/VM
    • Runtime
      • Engineが埋め込まれている
      • プラットフォームそれぞれのGlobalObjectを持っている
      • EventLoopをオーバーライドしてる

Optimization

  • 最適化
    • Product-level
      • memo化
      • キャッシュ
    • Runtime-level
      • 非同期
    • Engine-level
      • インラインキャッシュ
  • 効果
    • Product > Runtime > Engine
  • Micro Optimizationをするな
    • 自分でやらなくてもエンジンがやってくれる

Optimization

Server Side runtime

  • Node.js
  • イベントループ
    • 処理に時間のかかる動機処理があるとループをとめてしまう
    • 非同期でできるものはそうした方がよい
  • StreamAPI
    • Fileの読み出しとかを効率的に行える
    • Streamでないと情報を全てメモリにおいてそれを扱ってとなってしまって効率悪い

Client Side Runtime

  • ブラウザでJSが動くまで
    • fetch -> load -> parse -> compile -> execute
  • できるだけCodeCachingを使う
    • 次使う時にcompile済みになってるようにする
    • 頻繁に使われるものはServiceWorkerでcacheするといい
  • ESModules
    • ブラウザ上でimport/export
    • Preloading scripts
      • 実行はしないけどparseとcompileをしておいてくれる
  • idling
    • Idle Until Urgent
    • requestIdleCallbackを使うとCPUとかが暇な時に実行してくれる

Engine

  • V8
    • たくさん使われた処理ははやくとれるようにとか最適化してくれる
  • Inline Cache
    • Objectにどんな情報があるかを予め用意しておく?
    • ヒットしたらはやい

How to Boost Your Code with WebAssembly

  • FUJI Goroさん

WebAssemblyとは

  • ブラウザに搭載するバイトコードとその処理系仕様
  • JVMに近いけどランタイムはない

WebAssembly前夜

  • EmscriptenによってC/C++をJSにコンパイルすることができていた(2012)
    • ただし動作が非常に遅い
  • WebAssemblyに仕様議論開始(2015)
  • ブラウザにMVPレベルのサポート完了(2017)

WebAssemblyの価値

  • ブラウザにおいてはJSとできることは同じ
  • JSよりも速い
    • それが圧倒的価値
    • JSだと遅くて現実的でないことが可能になる
  • Cよりは数倍遅い
    • 安全性のために未定義動作(UB)をなくしてるから
    • この安全性が大きな利点

WebAssemblyのサポート状況

  • IE11以外は使える
    • 9割くらいのシェアのブラウザで使える

WebAssemblyの事例

  • eBayの事例
    • バーコードスキャナ

tech.ebayinc.com

言語ごとの速度イメージ

  • 1倍: C, C++, Rust
  • 3倍: Java, C#, Go, Swift
  • 5倍: JS(V8), Dart
  • 50倍: Ruby, Python, Perl, PHP
  • WebAssembly
    • WasmをV8で動かすと5倍の中では速い方

Streams APIをちゃんと理解する

  • 加藤 健志さん

StreamAPI

  • Readable Stream
  • Transform Stream
  • Writable Stream

Readable Stream

  • 読み込み可能なストリーム
  • データを分割して少しずつ読み込むことができる
  • fetchAPIのレスポンスのbodyは実はReadableStream

Writable Stream

  • 書込み可能なストリーム
  • pipeTo()を使うとReadableStreemのデータをそのままWritableStremに書き込める
  • 書き込み時にPromiseを返すと解決するまで待つので順序を保証できる
  • 分割されたデータを1つずつ順番に書き込むことができる

Transform Stream

  • 変換ストリーム
  • WritableStreamに書き込まれたデータをTransformStreamで変換してReadableStreamで読み込む
  • ReadableStreamからpipeThrough()でTransfirmStreamに渡してpipeTo()でWritableStreamに書き込める

バックプレッシャー

  • キューに空きがなくなったら通知して止めてもらう
  • Underlying Source
    • Push Source
      • 自発的にenqueueする
    • Pull Source
      • リクエストに応じてenqueueする
  • QueuingStrategy
    • highWaterMark
      • キャパシティを設定する
    • size(chunk)
      • 何をもってキューのサイズを決めるか

Streamsの今後

  • 5Gが来る
    • これまでボトルネックとされていたことが改善される
    • 大容量のファイルを配信できるようになる github.com

      - クライアントがボトルネックになる
          - Streamが役立つ!
      

Live Demo

「Mercari x Merpay Frontend Tech Talk vol.3」に参加してきました

  • Mercari x Merpay Frontend Tech Talk vol.3に参加してきました。

mercari.connpass.com

タイトル 発表者
Creating Serverless CMS from Scratch @sottar_
Vue.jsでのCSS設計 @tacamy
The Challenge of Web re-architecture using GraphQL and Apollo @lightnet328
Practical tips for making a global EC site @yayoc_

Creating Serverless CMS from Scratch

  • @sottar_さん

キャンペーンのページを作るまで

  • 従来のフロー
    • PMからどんなターゲットでどんあんことをしたいか伝えられる
    • デザイナーがコードを書く
    • フロントエンドエンジニアがレビューする
    • PMに返して問題なければリリース
  • 課題
    • デザイナーがコード角の大変(pug/css)
    • フロントエンドエンジニアがレビューするの大変
    • 一文字とか一部分変えるだけでもGitHubでフロー回さないといけない
  • キャンペーンページ作るのに時間かかる
    • 一ヶ月に1,2本くらいしか作れない

CMSを作った

  • コンポーネントを作ってCMS上で組み合わせるようなものがほしい
  • 必要なページ
    • キャンペーンの一覧ページ(過去に作ったものとか)
    • 編集ページ
  • なんでOSSを使わなかったか
  • 考えないといけないこと
    • 権限周り
    • セキュリティ
    • 履歴管理
    • プレビュー
    • => いろいろあるけどまずはMVPを作ってさわってもらう

アーキテクチャ

  • S3にCMSページの静的ファイルを配置
  • Cloud Storageにキャンペーンページを置いておいてそれをdynamic importして表示
  • GCPAWS混ざってる
    • 基本はGCPを使ってる
    • 社内版GitHubPages的なものをS3で作ってる
  • 認証はAuth0

Vue.jsでのCSS設計

  • @tacamyさん

コンポーネント

  • 機能が自己完結する
  • 再利用できる
  • Vueではscopedをつけると擬似的にスコープをもたせることができる
    • ShadowDOMとは違う

Scoped CSSの留意点

コンポーネント命名規則

ディレクトリ構成

  • assetsの中にscssに変数とかmixin
    • 実態はcomponentsの中
  • 階層が深くなりすぎないようにした方がよさそう
  • 細かすぎる分割はパフォーマンスにも影響
  • 最初はシンプルに作って規模に応じて変更していくと良さそう

The Challenge of Web re-architecture using GraphQL and Apollo

  • @lightnet328さん

メルカリWebにリアーキテクチャ

  • 新しい技術で作り直してる
    • TS
    • Next
    • React
    • Apollo
    • GraphQL
  • ページごとに部分的に公開している

GraphQLとApollo

  • なぜGraphQL
    • スキーマはドキュメントより実装と乖離するリスクが小さい
    • クエリの可読性高い
  • なぜApollo Clients
    • リモートデータの取得管理を任せたい
    • キャッシュによってリクエストが減る
  • なぜApollo Server
    • BFFとしての役割
      • スキーマをフロントエンドのために整理
      • ロギング
      • 認証
      • 将来的にgRPCでマイクロサービスに接続
      • クライアントが1つのエンドポイントだけ知ってればよい

Practical tips for making a global EC site

  • @yayoc_さん

UNIQLO Global EC

  • 特徴
    • 22カ国
    • O2Oもサポート
    • 機能が国によって異なる
  • これまで
    • 国ごとに異なるアプリ
    • クライアントヘビー
  • これらを解決させるプロジェクト
    • 1つのコードで複数の国対応
    • パフォーマンスはやく
    • a11y
    • コンシューマだけでなく管理画面のUXも改善
  • ページによってSSR
  • 国別にリダイレクトリライト

グローバルサイト構築

URL構造

  • /:country/:language
  • countryなかったらCDNの国
  • languageなかったらAccespt-Languageの言語

SEO

  • GoogleBot以外も考慮
  • JSレンダリングしてくれなかったのでHTML返した方が無難(SSR)

CMS

パフォーマンス

  • 毎日WebPAgeTest/Lighthouseを国別で実行
  • Performance Budget
    • total 200kb
    • chunk 80kb
  • webpack-bundle-analyzer
    • バンドルファイル内の内訳を可視化

ローカライゼーション

  • i18n- webpack-plugin
  • エントリーポイントを分けている
  • ルーティングベースでコードスプリッティングしてるから余計なのは入らない
  • 一部プレースホルダーで出し分け
    • 単数系/複数形とか
  • 決済フローなんかは国によって異なったりするのでコンポーネント出し分けてる
  • minificationで不要なものは削除される

a11y

  • ビジネスサイドからの要件も強い
  • Lighthouseでスコアとるだけでなくそれ以外の項目もチェック
    • 画像説明
    • CSSなしで動くか

画像

  • 一般的に画像が大きいほどコンバージョンは高い
  • CDNでWebPに変換してサイズ圧縮
  • プレースホルダーおいてリフロー防ぐ
  • 遅延ロード

BFF

  • マイクロサービスへのAPIリクエストを束ねる
    • クライアントヘビーな実装軽減
    • クライアントが扱いやすいような構造に整形
  • キャッシュ
    • max-ageを見て設定
  • ロギング
  • HMAC認証をサポート

「PWA Night vol.10 ~PWA × 技術~」に参加してきました

  • PWA Night vol.10 ~PWA × 技術~に参加してきました。

pwanight.connpass.com

タイトル 発表者
とある個人開発PWAのSEO奮戦記 大岡由佳さん
PWA×クラウドゲーミング おりばーさん
コードサイズの大きなプログラムのロード時間:WebAssemblyの場合 @chikoskiさん
うわさのJAMStackでPWAをさわってみた のまどまんさん
Monaca × PWA × 3D VMT-Yamashitaさん

とある個人開発PWAのSEO奮戦記

  • 大岡由佳さん(@oukayuka)

Mangarel

  • 個人でPWAなアプリを作った
  • Googleで検索しても3件しかひっかからない
    • 1万ページ以上存在してるのに
    • 最近のクローラーはJS解釈してくれるんじゃなかったのか・・
  • Problem
    • ページがインデックスされない
    • タイトルや詳細が個別に表示されない
    • コンテンツがレンダリングされない

ページがインデックスされない

  • サイトマップを作って送った
  • 正常に処理されましたと返ってきたけど
    • 認識はされるけどExclusionに入ってる
    • 内部リンクされてないのが原因?
  • ページを増やして内部リンクを増やした
    • 少しずつインデックスされるページが増えてきた!

タイトルや詳細が個別に表示されない

  • React HelmetでHTMLヘッダを上書き
    • ブラウザからは書き換わってるけどGoogle上では変わってない
  • CloudFunctionsで動的にヘッダを書き換えた
    • ボットからのアクセスの時だけ発動するように

コンテンツがレンダリングされない

  • SearchConsoleで試してみたらFirestoreからデータをとってくるはずがとってこれてない
    • ページによっては運がよければ表示される
    • レンダリングに時間がかかると諦めてるっぽい
  • Lighthouseで計測したらパフォーマンス50点台
  • TreeShakingした
    • ビルド時に不要なコードを削除
  • CodeSplitting
    • 初回のレンダリング時には必要なJSだけロードしそれ以外は遅延ロード
  • Lighthouse60点台
  • 無限スクロール

PWA×クラウドゲーミング

  • おりばーさん@Black Inc.(@oliver_diary)

クラウドゲーミング

OOParts

  • 開発してるクラウドゲーミング
  • ゲームをWebブラウザでアクセスするときの残念なところ
    • アドレスバーが邪魔
    • 余白がもったいない
    • アクセスするまでの導線が長い
    • => PWA化で解決!
  • 他にも
    • 起動時の初期表示が速い
    • アプリと違って審査いらない
  • PWAとクラウドゲーミングの相性抜群

コードサイズの大きなプログラムのロード時間:WebAssemblyの場合

  • @chikoskiさん

WebAssembly

WebAssemblyのいいところ

  • JSあるのになぜWebAssembly?
    • エコシステム
      • 他の言語の資産を使える
    • パフォーマンス
      • 速いけどそれだけじゃなくてブレが少なくて安定感が高い
  • 音声ファイルの扱い
    • ファイルサイズでかいので圧縮してmp3にして扱いたいとか
    • でもJSだけではできないのでWebAssemblyが役立つ

WebAssemblyの注意点

  • コンパイルするとjsとwasmが出力される
    • ファイルサイズがでかい
    • キャッシュを活用する
    • ネイティブのコードはブラウザにキャッシュされる
  • キャッシュにのったコードをいかに使い続けるか
    • 不必要なコードの変更をしない
      • ドメインとファイルを対応づけて保存されている
      • コンテンツが変わったら破棄されてしまう
    • URLを変更しない
      • クエリも変わらないように
    • ステータスコードを正しく返す
      • 200が返ると新しいコンテンツが来たと認識する
      • 変わってなければ304を返す
    • wasmのファイルを小さくしすぎない
      • 小さすぎるとキャッシュが破棄される(150kb以下くらい)
    • 最適化オプションをつける
    • システムライブラリをシェアする
    • application/wasmをつける
      • 全部のデータをダウンロードする前にある程度溜まったらコンパイルするという動きをしてくれる

うわさのJAMStackでPWAをさわってみた

  • のまどまんさん

JAMStack

  • 動的なデータコンテンツを取り扱う静的サイト
  • 事前に静的ページを生成しておく

JAMStack作ってみた

PWA化してみた

  • GatsbyにPWAのプラグインがある
  • キャッシュ使ったらパフォーマンス上がった
    • コンテンツがユーザ単位などで頻繁に変わる場合はキャッシュが活かしきれないかも

Monaca × PWA × 3D

  • VMT-Yamashitaさん

Monaca

  • ハイブリット開発環境
  • PWAのテンプレートがある

「LINE DEVELOPER DAY 2019 Day1」に参加してきました

  • LINE DEVELOPER DAY 2019に参加してきました。

linedevday.linecorp.com

  • セッションの資料はこちらに随時公開されるとのこと

speakerdeck.com

  • 今回はDay1の午後だけ参加してきました
  • 以下セッションのメモです

Inside of Blog; 15年熟成されたサービスの光と影、カオスとレガシーへの挑戦

  • 大森 貴博さん

livedoor Blog

  • 構成
    • LAMP
    • 30近くのサブシステム
  • 15年での蓄積
    • Developper
      • 70+
    • サーバ
      • 750+
      • 200がDB
    • DBテーブル数
      • 550+
    • ファイル数
      • 43500+
    • プログラムファイル数
    • コードの行数
      • 410000+
  • 今動いているブロジェクト

カオスとレガシー

ドキュメントがない

  • セットアップ方法がわからない
  • デプロイ方法がわからない
  • 普段触ってないサブシステムだと特に

開発サーバがない

  • 誰からも忘れられていて安定して動いたサブシステム
    • それに手を入れようとしたら環境がない
  • 開発サーバはあるか?
  • 正常に動いているか?
  • 本番との差分がないか?
  • 本番のデータを使っていないか?

テストがない

DNSレコードが多すぎる

  • 300レコード以上
    • ユーザが設定してる独自ドメインとかは入ってない
    • 調査したら230が不要だった
    • 古い機能とか過去のキャンペーンでの残骸
    • 整理して削除するだけで数ヶ月

機能が多すぎる

  • 目に見えるもの見えないものたくさん削除してる

Perl

  • Perlのバージョンがとても古い
    • 5.6(2002年)
    • ローンチしてから変えてない
  • 新しいバージョンのPerlも一部使ってる
    • バージョンが混在している
    • 環境など全て2倍必要

MySQL

  • MySQLのバージョンが古すぎる
    • 4.0(2003年)
    • ローンチしてから変えてない
  • 4.0でできないこと
    • Online DDL
    • Fast Index Creation
    • Trigger
    • => オンラインでalter tableできない
      • テーブルコピーしてデータ移行して、、と無理やり頑張った(数ヶ月かかる)
      • データが2倍だからディスク容量が逼迫
  • バージョンを上げないのか?
    • サーバマイグレーションのタイミングで考えた
    • ブログの特殊な事情と時間的制約で断念
      • 1つのテーブルに複数文字コードが混ざってる
      • そのせいで正攻法でのバージョンアップができない

LINE BLOG

  • LINEとの連携が強い
  • 2014年リリース
  • 2016年リニューアル
    • 一般公開
    • 独立したサービスに
      • livedoor Blogをフォークした
      • livedoor Blogのカオスとレガシーも引き継いだ
      • => LINEのエンジニアが本気出して数々の問題を解決

Next 15 Yeras

  • 15年後を考えて開発していくことが大切
  • 小さなことからでも始めること
    • コメント一行書くだけでも
    • 不要なファイルを削除しておくだけでも

LINE NEWSの記事配信を支える技術

  • 稲葉 大樹さん

LINE News

  • 2013年開始
  • 2017年からLINEのタブに加わった
  • ニュース以外に運行情報や地震速報なども
  • 月間680万ユーザ
  • インフラ
    • Amon2(Perl) 44台
    • Spring Boot(Java) 30台
  • DB

Personalized Recommendation

  • 多大な記事数ユーザ数をもとに記事をレコメンドしている
  • ML + Manual(運営の手動)
  • 表示対象かつ表示期間中のものがユーザに表示される

MLによるレコメンド

  • 社内のMLチームで生成されたものをもとにレコメンド
    • 1億人超えのデータが入っている
    • ユーザ一人に付き200件の記事を選んでる

手動によるレコメンド

  • 運営チームがCMS上で設定
  • 属性に応じてどの記事を表示するか選ぶ
    • どの媒体をフォローしてるかとかも属性として選べる

MLのレコメンドだけを使っていた時代

  • CDNを活用して記事を取得していた

    • レコメンドを取り入れると属性が必要なのでCDN活用できなくなった
  • ユーザからの記事取得リクエストの流れ

    • Redisにレコメンドした記事を事前に入れておく
    • ユーザから記事取得のリクエストが来るとRedisから取得する
    • 取得した記事をキャッシュに保存しておく
    • 次からはキャッシュにあればそこから、なければMySQLから取得する

ML + Manualでレコメンドしていた時代

  • Central Dogma
    • jsonとかyamlの設定ファイルを管理する
    • 変更をwatchすることができる
  • Datalakeから対象ユーザのIDを取得してCMSにアップロード
  • 記事IDとユーザのマッピングをRedisにあげる
  • Central Dogmaに記事の情報をあげる
  • 課題
    • 記事とユーザのマッピングデータの形式の影響でスケーラビリティがない
    • パフォーマンス

今後

  • 今はユーザからのレスポンスが反映されるまで1時間かかったる
    • リアルタイムに反映させたい
    • 今ABテストで一部のユーザに適用
  • レコメンド適用範囲の拡大
    • ダイジェストは今全員同じものを出してる

コミュニケーションアプリ「LINE」の機能改善を支えるデータサイエンス

  • 高口 太朗さん

LINE App Improvement Project

  • Uesrs First
  • Data Driven
  • Diverse Team
  • In-houes Developmemt

データサイエンスチーム

  • Data Science And Engineering Center
    • Data Labs
      • Data Science Team
  • Data Science Team
    • LIENマンガ
    • LINEトップ
    • LINE Pay
    • LINE ad

プロジェクトのサイクル

  • ユーザリサーチ -> 計画 -> 開発 -> テスト -> フィードバック -> 計画 -> ...

ユーザリサーチ

  • Focused Interview
  • Online Suvey
  • Dashboard Monitoring
  • 定量と定性を組み合わせる

計画/開発

  • 計画
    • どうデータではかれば良いか考える
  • 開発
    • どのようなログを集めればよいか定義など

テスト/フィードバック

  • テスト
    • オンラインでのABテスト
    • 2018~で20回以上者ABテストをやってきてる

LINEアプリ改善の取り組み

  • LINEアプリならでは
    • ユーザが多い
    • 使い方もさまざま
  • LINEアプリを評価する単独のKPIが存在しない
    • メッセンジャーは無料の機能
    • すでに多くのユーザを獲得してるからユーザ数xx増加とかもやりづらい
  • LINEのコアバリュー
    • LINEのミッション
      • Closing the Distance
    • メッセンジャーアプリにあてはめると
      • 身近な友達と簡単にやりとりできること
    • そのために改善すべき機能を考える
  • 友達ネットワークを分析
    • 社会的なネットワークが反映されている
    • グループ機能の改善がターゲットに

グループ機能の改善

  • ユーザリサーチ
    • グループ作成の手順がわかりづらい
    • 当初
      • グループ名やアイコン決めてからメンバー選択
      • 急にグループ名聞かれても困るのでは
  • 計画
    • グループ名選択よりも前にメンバー選択を持ってくる
  • ABテスト
    • 入れ替えてもグループ作成成功率は変わらなかった
  • フィードバック
    • どこに目をつけるか
      • 成功したユーザに着目?
      • 失敗したユーザに着目?
      • 時間帯に着目?
      • 地域に着目?
    • グループ名アイコンを選ぶ画面まで進んでない人が多い
      • スムーズにメンバーを選べていない
      • テスト期間中に複数回失敗したユーザ30%程度
  • 計画
    • 最近トークした友達を上に持ってくる
    • グループ名アイコンとメンバー選択を一画面で
  • ABテスト
    • 2種類×2の4通りテスト
      • 比較のパターンが多いので偶然の差異を拾ってしまう可能性がある
      • 組み合わせの一つを諦めて3パターンを検証
  • フィードバック
    • 大きな差はでなかった
    • グループ作成までにかかる時間が短くなってれば成功なのでは?
      • 最近トークした友達を上に持ってくると短縮されていた
    • 1画面にした結果はネガティブ
      • メンバー1人でグループ作成が増えた
      • メンバー2人以上だけをみると作成成功率低下
    • 2画面のままで最近トークした友達を上に持っていくのを採用

データサイエンスツール

  • 分析の環境とツールによってこれらの改善は支えられている
  • ABテストするためには
    • 必要なサンプルサイズの選定
    • テストユーザ選定
      • LIBRA
    • モニタリングダッシュボード
      • LIBRA REPORT
        • GitHubを通じて集計に必要なクエリを登録
        • ブラウザベースのダッシュボードに出力してくれる
      • R Shiny
        • より高頻度でチェックしたい
    • テスト結果のレポート

XXE、SSRF、安全でないデシリアライゼーション入門

  • 徳丸浩さん

XXE

  • XML外部実体参照
  • 外部実体参照
    • XMLはentityを定義して参照することができる
  • 攻撃の例
    • SYSTEM /etc/hostsとか指定すると内容がとれてしまう
    • URLを指定するとその内容が読み込まれてXMLに展開される
      • SSRF(Server Side Request Forgery)
  • 原因
    • XMLのもともと保つ機能
  • 対策
    • XMLを使わずJSONを使う
    • XMLを使わなければいけない場合はどうする?
      • Javaの場合DTD(Document Type Definition)を禁止する
      • PHPだと外部実体参照を停止する設定になっている
      • RailsではREXMLを使う
        • nokogiriだとNOENTオプションを設定しない

SSRF

  • Server Side Request Forgery
  • 攻撃イメージ
    • 直接アクセス不可の内部サーバがある
    • 公開サーバを通して内部サーバにアクセスを許可している
    • 公開サーバを踏み台にして内部サーバにアクセスすること
  • 攻撃の例
    • プレビュー機能でのSSRF攻撃
    • http://169.254.169.254にアクセスするとEC2のインスタンス情報をとれる
    • このURLをプレビューするとSecretAccessKeyなどとれてしまう
    • EC2インスタンスを踏み台にしてクレデンシャルな情報にアクセスできてしまう
  • 原因
  • 事例
    • Capital Oneの例はSSRFだった
    • WAFの設定ミスによるもの
    • HostヘッダにEC2インスタンスを指定することによる攻撃
    • WAFの権限がS3へのアクセスなど広く与えられすぎていた
  • 対策
    • ホスト名がIPアドレスであることをチェックするだけではダメ
      • リダイレクトされてしまうなどさまざまなケースが有る
    • ネットワーク的にチェックする
      • 許可されたURLかどうかチェックする

安全でないデシリアライゼーション

  • シリアライズ
    • バイト列に変換してオブジェクトに格納できるようにする
  • 外部から来たシリアライズデータをデシリアライズするとどんなオブジェクトでも作れてしまう
    • メソッドをいじったりとかはできない
      • プロパティを工夫するといろいろできてしまう
  • 対策
    • シリアライズ形式でなくJSONを使う
    • クッキーやhiddenパラメータではなくセッション変数を使う

LINEのメッセージングプラットフォームにおけるマイクロサービス化への長い道のり

  • 井出 真広さん

LINE Messaging Platform

  • 2011年ローンチ当初はモノリシックだった
    • talk-server/redis/msql
    • 1つのチーム/1つのサーバでうまくいっていた
    • どんな機能を追加していくか同じ方向を向いてできていた
  • 追加したい機能がたくさん増えてきてチーム全体で調整する必要がでてきた
    • 速度を持って進められなくなってきた
    • チームを分割してサービスを分けるようにしていった
    • チーム単位でそれぞれコントロールできるようになった
    • スタンプ/メッセージング/認証/...
  • 現在は多くのサービスが連携し合いながら動いている
    • チームごとにやりたいことにフォーカスしながら開発している
  • マイクロサービス化して
    • よかったこと
      • コンフリクトが少なくなった
    • よくなかったこと
      • ネットワークレイテンシ
      • 障害

マイクロサービスを構築するためのツール

  • Coneectivity
  • Directory Service
  • Routing

Coneectivity

  • Armeria
  • 非同期なRPC/RESTライブラリ
  • Java/Netty/HTTP2
  • ロギングや分散トレーシングの仕組み
  • 障害を伝播させないためのサーキットブレーカーの仕組み

Directory Service

  • Central Dogma
  • サービス間で設定を共有したい
  • 通信先のサービスがどこにあるのか把握したい
  • どのホストが度のサービスを配信しているか
  • gitをバックエンドとしたバージョン管理の仕組み
    • どの時点でどの設定だったか管理

Routing

事例

  • スタンプが普及してきた
  • 1ユーザで万単位で持っている人もでてきた
  • スタンプを購入するたびにRedisにスタンプの所有情報を再構築していた
    • その時にスロークエリが発生して一瞬talk-serverが止まる
    • talk-serverにはいろんな場所からリクエストがくる
    • メッセージングプラットフォーム全体の障害となりかねない
  • どこかが一瞬とまるようなことがあっても波及しない構成に再構築
    • サーキットブレーカーなどの仕組みをいれる
    • レイテンシを悪化させないように
    • スケール