GitHub x CircleCI x Azure でやってみようDevOps!に参加しました

概要

GitHub x CircleCI x Azure でやってみようDevOps!に参加した内容をまとめました。

microsoft-events.connpass.com

CircleCI セッション

  • CircleCIは日本語サポートを今後完全に行う予定
    • 日本のページから行けば日本語で問い合わせを対応

DevOpsの歴史と重要性

  • 2010年

    • 継続的デリバリー
      • ソフトウェアが常にデプロイ可能な状態に保つというプラクティス
  • Puppet社が調査

    • 業績が高い会社ほどテストパターンとデプロイパターンの再利用をしている
    • 優れた企業は、
      • 予定外の作業や同じ作業に費やす時間が21%少ない
      • 新しい作業に費やす時間が44%多い

CI/CDとはなんなのか

CI継続的インテグレーション

  • what
    • 共有リポジトリの全てのコミットをトリガーにしてビルドとテストを繰り返すこと
  • why
    • チームの生産性、効率、満足度をあげること
  • できること
  • CIは比較的開発チームに閉じているもの
  • 解決する問題
    • 全てのコミットに対してCIすると
    • 早い段階でバグを発見できる
    • 設定で制御可能
    • 静的解析などで標準化
    • コードの品質UP
    • テスト失敗したコードのマージブロック
    • masterブランチの安全保障

CD継続的デリバリー/デプロイメント

  • CDには2種類存在する

    • 常にリリース可能な状態を維持する
    • 自動でステージング・本番環境へデプロイする
  • Continuous Delivery(継続的デリバリー)

    • リリース作業に人間の意思が介在する
  • Continuous Deployment(継続的デプロイメント)

    • リリース作業に人間の意思が介在しない
  • 大事なのはCDを考える時にステップを刻むこと、ステークホルダーを巻き込むこと

    • 一足跳びに本番自動デプロイは難しい

5 Metrics You Should

Know to Understand Your Engineering Efficiency

https://www2.circleci.com/rs/485-ZMH-626/images/5-Key-Metrics-Engineering.pdf

  • commit-to-deploy time
    • コードがコミットされてからデプロイされるまでの時間
  • Build Time
    • CIビルドにかかる時間
  • Queue Time
    • CIビルドが始まるまでに待たされる時間
  • How often Master is Red
    • masterブランチが壊れている時間
  • Engineering Overhead
    • ツールのメンテナンスなど開発時間にかかっている時間

これらの指標を理解しておいて最適化する

CircleCIのご紹介

Dockerをサポート

  • 高速にビルド環境を立ち上げることができる

.circleci/config,ymlでテスト環境を統一することができる

  • コンフィグはファイルに書かれるべき
    • コードと同じくレビューとバージョン管理を行う
  • 明示的であるべき
  • その結果のデメリット
    • 一から設定を書かないと行けない
    • 冗長になりがち
      • これらの点を解決しているのが後述するorbs

ワークフロー

  • ビルド設定を分解して、依存関係や並列処理を行う
  • ワークフローのタイプ
    • スケジューリング
    • マニュアル承認
    • ブランチ指定: 特定のブランチへのコミットによって実行
    • タグ指定: Gitのタグによって実行

SSHデバッグ

  • Rebuild wth SSHでコンテナが起動したまま維持してくれるので今ビルドされているdockerコンテナに入れる
    • 入ってエラーログなどを確認できる

ビルドの高速化

キャッシュ

  • 同一ジョブ間のキャッシュ
    • 外部のライブラリなどを毎回ダウンロードするのには時間がかかるのでキャッシュしておく
  • 同一ワークフロー内のキャッシュ
    • 一番最初のジョブで実行コードを作る
    • そのあといろんなテストで使い回す

並列処理

  • テストを並列にdockerコンテナを起動して行う
    • 4並列で合計400個のテストを実行など
  • どのテストファイルを分けるか?
    • 前回のテスト結果からどう分けると一番早いのか自動で判断してくれる
      • 便利!
  • 設定のパッケージングと再利用(Orbs)
    • 設定のメンテナンスが難しくなる問題への対応策
    • 設定を再利用することができる
    • 他の人が書いたCircleCIの設定を自分のプロジェクトのconfigに差し込める
      • プライベートorbsがないので公開には注意が必要(公開したら全公開しかない)
      • orbsには公式、公認パートナー、3rd partyの3つ種類がある
      • 一番使われている3rd partyは日本人が作ったもの

GitHub x CircleCI x Azure

デモ

  • CIが入るとレビューのタイミングが変わる

    • テストが終わった状態でレビューができる
  • Azureとの連携

    • クラスターを作ったり消したりするのに時間がかかる

質問

  • Windowsのサポートはあるか?
    • 興味がある人にだけclosedなバージョンを提供している
    • 使ってみたいという相談があれば提供

GitHub セッション

エンタープライズオープンソースの両方の世界のデファクトスタンダード

DevOps?

今や当たり前のプラクティス 今はDevSceOpsが重要 Securityの観点を入れる そして自動化する

Security?

  • 99%のプロジェクトがオープンソースを利用している
  • 広く使用されているオープンソースソフトウェアにバッグドアが仕込まれる
    • 去年npmのライブラリに悪意あるコードが埋め込まれた
      • メンテナーに新しく参加した人によるもの

開発者に役立つ機能

  • セキュリティ脆弱性アラート
    • 去年2千7百万件のアラートを送っている
    • WhiteSourceという脆弱性業界の会社と連携している
    • 先に踏み込んだ機能
      • ディペンデンシー・インサイト
        • アラートの上がっているライブラリを利用しているリポジトリの可視化、どれくらいの危険度なのか可視化
  • 脆弱性の修正をオープンソース上で行うと脆弱性があることが周囲にバレてしまい悪用される可能性が生まれる

  • 70%以上の脆弱性がアラートの後パッチ適用されていない

  • 解決するツールDependabot

    • 解決するパッチを自動で当てるツール
    • 解決するp-rを出せる(出してくれる)
  • Open source開発の持続可能なものにしていきたい

    • Sponsor機能
      • 善意とボランティアで動いていたものを持続可能なものにするもの
  • GitHub Sponsors Matching Fund
    • 寄付額と同じ額をGitHubも払う(寄付額の倍の金額をコントリビューターヘ送られる)
    • GitHubは手数料を取っていないので全額送られる

Microsoft セッション

Azure Container Registryを使い倒す

ACR=docker hubのimageの置き場所 docker imageのプライベートレジストリ

ACRタスク

  • Azureのクラウド上docker buildできる
  • 使っているbaseのイメージがアップデートされたらbuildし直す

geo-replication

  • コンテナイメージを構築するためのコードをコミットすると別のリージョンにもプッシュされる

    • premiumプランのみサポート
  • circleCIにACRの拡張がある

Microsoft Learn

感想

  • 存在するとは聞いたことがあったけど、並列でのテスト実行で前回のテスト結果からどう分けると一番早いのか自動で判断してくれるの便利
  • 開発者やステークホルダーの満足度をあげるためもCI/CDは必要
    • 特にアジャイル開発だと常に最新で動かせる成果物があることが重要なので必須と言っても良さそう
    • 例えばスクラムのスプリントレビューで毎回成果物の確認のために工数がかかっていてはまずい(そのうちやらなくなることもありえる)
  • GitHubは最近新しい機能が増えてるなとは思っていたけどちゃんと使ってなかったので今回知ったのを機に使っていきたい
  • Microsoft LearnのACRのラーニングやってみる!

PWA Night vol.5 ~PWAのミライや活用方法をみんなで考えよう~に参加しました

概要

PWA Night vol.5に参加したので発表の内容をまとめました。

WordPressをやめ静的サイトジェネレーターで高速化した話(仮題) by 池田さん@ICS

https://ics.media/entry/190410

サイトの構成

  • 記事以外はnuxt.js
  • 記事部分だけAMP
  • PWA✖A️MP

AMP

  • AMPはHTMLのサブセット
  • 読み込みを高速化できる
  • 通常のウェブサイトをPWAに対応するのと同じ
    • manifest.json + service worker
    • amp-install-serviceworkerというライブラリを使う
      • service workerはキャッシュにのみ利用している
      • キャッシュはWorkboxを使って実装
  • キャッシュ戦略
    • 記事画像
      • キャッシュ優先
    • AMPライブラリ
      • キャッシュ優先(裏側でフェッチ)
    • それ以外(記事HTML)
      • ネットワーク優先

HTMLの変換技術

  • マークダウンで管理している記事をnodeをかましてHTMLに変換している
    • node.jsのmarkdown-itモジュールでhtmlタグに変換
    • マークダウンをプレーンなhtmlへ変換
    • マークダウン変換のカスタマイズ
  • ampの制約
    • amp-imgタグを利用する必要がある
  • 画像の配信の最適化
  • サーバ

あのサービスの開発から運用に関して by 小野谷さん@DMM

  • (※業務委託なので口外無用とのこと)
  • 開発の経緯やwebでネイティブアプリぽいUXにするための工夫が聞けて面白かった

Nuxt.jsのPWAモジュールの話 by 菅家さん@TAM

  • 実際にnuxt.jsのPWAモジュールで何をしているのかについての発表

workbox

  • sw.jsとworkbox(ライブラリ)を生成する
  • 新しいserviceworkerがある場合
  • ランタイムキャッシュの設定
  • プリキャッシュ
  • swインストール時にキャッシュ
  • app shellのための静的リソール

    • リビジョンで管理できる
  • ランタイムキャッシュフェッチチベントジにキャッシュ

  • キャッシュの有効期限や優先順位などのキャッシュ戦略を立てる
  • モジュールv3から仕様が変わった

    • バンドルファイルがプリキャッシュに入らなくなった
    • プリキャッシュは自分で設定する
    • 全てのバンドルファイルをプリキャッシュしない意図で変更された
    • むやみにキャッシュサイズが膨らむから
    • 参考
  • manifest

  • meta
  • icon

    • 地味にめんどくさいこれらを自動でやってくれる
    • 必要であればnuxt.config.jsで上書き可能
  • onesignal

    • push通知
    • PWAモジュールのデフォルトではない
  • nuxtjs/pwaは簡単すぎてブラックボックスになるがちなのでやっていることを理解してやることでより良いアプリにしていきましょう

Elmが思っていたより良かった話

Elmとは

TEAとは

  • Elmのフレームワーク
  • Reduxの始祖と呼ばれているもの
  • Update
    • Cmdを返す
  • View
    • ElmはTEAでアプリケーションを構築するための言語
  • いいところ
    • 基本的に実行時エラーが出ない
    • 仕様が小さいので学習コストが極めて低い
    • コンパイルが早い
    • エラーメッセージが親切すぎる
    • 型付けに頑張るも頑張らないとかない
  • 辛いところ
    • unsafeなものをelmアプリケーションの外側に出すためにボイラープレートが必要
    • 小さいUIパーツに独立した状態を持たせられないので複雑なUIを作ろうとすると辛い
  • とにかく堅牢にいきたいときだけelm使っている

Service Worker Life Cycle “Install”

  • スライド

  • install

    • swごとに1度しか呼ばれない
    • 必要なリソースをキャッシュするのに使われる
  • activated
    • 一度しか呼ばれない
    • 古いキャッシュを削除するのによく使われる
    • acticated=service workerによる制御開始ではない
    • 初回アクセス時にswの制御が開始されない
    • 2回目のアクセス時にacivatedされたswがあればswによるfetchが行われる
    • client.claim()で1回目でも強制的に捕まえられる

プログラミング歴1年のエンジニアがPWAでweb開発した話

  • memeというスニーカーショップのwebアプリ
    • PWAにした理由
      • サイトをブックマークをする人が多かった
      • 記事に対してSEO対策を行うことで記事からの流入も見込める

所感

  • 某サービスのPWAで起動がユーザのX分のYもあると知って驚いた
    • 今後もPWAが周知されればもっと増えるはず
  • nuxt.js全盛
    • 6つの発表のうち4つがnuxt.jsの話
    • @nuxtjs/pwaが便利すぎる
      • v3から仕様が変わるので注意
  • 現状PWA対応はできたからついでにやったというところが多い印象
    • やはりiosがネック
    • ホーム起動対応はコスト低いのでどこもやってる、キャッシュは各々コストかけて頑張ってる

HTML5 ゲームを支える技術勉強会に参加しました

6/17のHTML5 ゲームを支える技術勉強会に参加してきました。 connpass.com 各発表の内容と感想等をまとめます。

HTML5 ゲームフレームワーク開発について

発表の目的

  • HTML5ゲーム開発に必要な要素を知ってもらう
  • それをHTML5でどう実現するのか共有する

アジェンダ

  • ゲーム開発用に必要な要素
  • ゲームとして成立させるための要素
  • ゲーム開発で楽するための要素
  • HTML5でどう実現する?
  • スマホとPCの両対応が前提
  • 約2年前のブラウザでも動作する機能
  • まとめ

ゲーム開発用に必要な要素

  • グラフィック描画
  • サウンド再生
  • ムービー再生
  • プレイヤーとの対話
  • リソース管理
  • ライフサイクル管理
  • デバッグ機能

HTML5でどう実現する?

グラフィック描画

  • WebGLを使う
    • GPUを使って高速に描画可能
    • HTML要素はcanvasだけあればok
    • 描画ライブラリを使うとお手軽
      • 2DならPixiJS
      • 3Dならthree.js
  • requestAnimationFrameで定期的に更新
    • ブラウザの描画タイミングを拾えるAPI
    • 最高60FPSで呼ばれる
    • 負荷が高いとフレーム間隔が伸びる
      • 60FPS前提でフレームごとに固定値のアニメーションは❌
      • じゃあどうするか
        • performance.now()でフレーム間隔を算出する
        • 起動からの経過時間をマイクロ秒単位で取得できる
        • 経過時間を算出し時間ベースでアニメーションさせる

サウンド再生

  • Web Audio APIを使用する
    • エフェクトかけたり色々できる
    • 自動再生ポリシーへの対応
      • ユーザの操作を契機に再生開始する必要がある
    • メモリ使用量に注意
      • 解放バグや解放のためにテクニックが必要です
    • バックグラウンドでも音が鳴り続ける
      • ライフサイクル制御により連携が必要
    • その他の問題や対策などqiitaにあります

t.co

ムービー再生

  • videoをWebGLに食わせる
    • WebGLはHTMLVideoElementをテクスチャとして受け入れる
    • iOSはplayinline属性が必要
    • videoも自動再生ポリシーに抵触する

プレイヤーとの対話

  • MouseEventsとTouchEventsを併用
    • イベントリスナーでキャッチできる
    • 離すイベントが発火しないパターンに注意
  • PointerEventsがやってくる
    • MouseとTouchの統合イベント

リソースの管理

  • ブラウザキャッシュで通信量節約
  • IndexeddbでJS主導の通信量節約
    • idb-cacheを使っている

t.co

ライフサイクル管理

  • resizeイベントを検知してからcanvasリサイズ
    • リサイズは少し待ってからする

デバッグ機能

  • ブラウザ備え付けの開発者ツール使う
    • drecom/stats.js

t.co

PWAゲーム開発の課題と対策

クライアント・サーバのアーキテクチャ紹介

クライアント(図で階層分けてあった・・)

  • Application(SPA)
    • animation video audio
    • afterEffects Spline.js GameFramework

サーバ(こっちも図がありましたが、構成要素だけ抜き出し)

  • AWS
  • APIリクエス
  • ALB
  • ECS
  • Target Group Blue
  • Target Group Green
    • nginx
    • API(Go)
    • fluentd
    • EC2

通信量をできるだけ減らすためのアセット配信

  • ユーザの期待
    • 出先でも遊べるようにとにかく通信量を減らして欲しい
    • どんなに面白いゲームでも通信量をがかさむゲームは遊びたくない
    • 期待に応えたい、でもゲームはwebアプリに比べアセットが肥大化しやすい
      • 最近はそうアセットサイズが1GMを超える事も珍しくない
    • ディスクキャッシュ容量はモバイルSafariだと50MB程度しかない
  • CacheStorageは救世主になるか
    • Android(chrome)限定だが、CacheStorageとPersistent Storegeの組み合わせで1GB超えのアセットの永続化はできる
    • しかしPWAを作るとなるとiOSも対応したい

通信量を減らすためにできる事

  • Cache-Controlで1年キャッシュ
    • index.html等の読み込みの起点となるファイル以外は全てmax-ageを1年にする
      • CDNへの更新確認リクエストすら飛ばさない
      • 何か不具合があっても時間が経てばキャッシュが消えて直すといった淡い期待は持たない
      • 絶対に消えないキャッシュを作るという強い意志を持ってキャッシュする
      • 同一のアセットを更新したいときにキャッシュが効くと困るため、必ずクエリにバージョン番号をつけて取得する
  • キャッシュの削除戦略
    • アセット名にコミットハッシュ(revision)を含める
    • アセットリクエストのクエリにバージョン番号を含める
    • どちらを選んでも参照するためのハッシュ値orバージョン番号を何らかの手段で取得しなければならない
  • キャッシュの取得方法
    • アプリケーションビルド時にjsやhtmlにバージョン付きで埋め込む
    • アセット取得パスを動的に組み立てる場合
    • 都度サーバのapiレスポンスに必要なアセットのバージョンを含める
    • アセットパスとバージョンの対応関係が書かれたマニフェストファイルをあらかじめ取得しておく
    • 弊社ではサーバのレスポンスに一部のアセットのバージョンだけを含める対応コストが高かったため、全てのアセットのパスとバージョン番号の書かれたファイルを参照した
  • デフォルトでgzip圧縮対象でないファイル形式のgzip対応
    • 全ての主要ブラウザがAccept-Encoding: gzipヘッダ付きでアセットを取りにきてくれるので少し工夫すると上記以外のアセットも圧縮・配信することができる
    • S3にアップロードする際、Content-Encoding: gzipをつけておけばどんなアセットでもgzip圧縮済みとして配信できる
    • ファイル形式によって圧縮効率が変わるため、ほぼ意味がない場合もある(pngとかjpeg)ので適材適所で利用する
    • 動画とかは効果が高い
  • 圧縮フォーマットの利用
    • pngはwebpにしてchormeはwebpを使う
      • chomeブラウザで遊ぶユーザのためだけに用意している
      • クライアント側で利用ブラウザで判定してリクエストを全てwebpに置き換える
  • アトラス化
    • 画像のアトラス化はやって当たり前
    • 音声データのアトラス化もある
      • asm.jsを利用したJSのwebassembly対応
      • 両方用意しておいてwebassembly非対応のブラウザの場合はasm.js側のファイルをリクエストする

ソースコードや通信内容が容易に見れる中でのチート対策

API通信内容の秘匿化

  • 大前提としてリクエスト・レスポンスの内容は簡単に見ることができる
  • リクエスト内容がわかると同じリクエストを複製したり一部を書き換えて偽装したリクエストを送ることが容易になる
    • botを作られるリスクが上がる
  • レスポンス内容がわかるとそこからゲームの攻略情報が漏れてしまう危険性がある

対策

  • リクエスト内容を共通鍵暗号方式で暗号化、復号する
    • 暗号化処理はC++で書かれたものをEmscriptenを使ってasm.js/WebAssembly化して行う
    • 通常リクエスト本文をヘッダを含めて暗号化し、POSTリクエストのbodyに入れて送る
    • 復号は専用のnginx moduleを通して行い。bodyの中身を復号したのち、本来のリクエスト内容を入手してアプリケーションサーバにリバースプロキシする
  • レスポンスの暗号化・復号

アセットパスの類推対策

  • アセットへのアクセス内容は全て簡単に見ることができる
  • アセットパスが類推可能な場合公開前のリソースを抜かれるリスクがある
  • アセット内容がjsonなどのテキストデータの場合は直接見ることができるのでゲームの攻略情報に繋がる情報を取得されるリスクがある

アセットパスの類推対策案

  • パスの途中にサーバが払い出した文字列を含める
    • サーバからもらったハッシュ値を含めてアセットを取得する
    • サーバが払い出したハッシュ値がナイトアクセスできないのでオリジンに先にアセットをアップロードしたとしても抜かれる心配がない
    • 問題: ローカルに保存したあと、ファイル名を推測されやすい
  • パス全体をハッシュ化して難読化する
    • ファイル名を含めたパスを完全に難読化する
    • 拡張子も、存在しないと動かない場合を覗きできる限りとる
    • 問題: 難読された後のパスを使ってデバッグするのは困難

実際に行った対策

  • サーバが払い出したハッシュ値を使って組み立てたアセットパス全体を難読化する
    • 難読化ロジックはc++で記述し、Emscriptenで変換する(JSのライブラリを利用していない理由は、変換後のソースが読みにくい事をあえて利用しているから)
    • アセットパス全体を難読化するのはステージング環境に限定し、開発環境ではハッシュ値付きの状態では扱う
      • デバッガビリティの確保

アセット自体の秘匿化

  • テキスト形式のファイルの秘匿化
    • apiリクエスト・レスポンス同様共通鍵方式で暗号化したものをアップロードする

画像の秘匿化

  • 画像はそのままだとdevtoolを使って見る事やダウンロードすることができてしまう
    • リリース前に実験したが、実装の問題でメモリに対する負荷を許容できなかったため見送りしたがやり方を紹介
  • HTMLImageElementを作るとどうしてもdevtoolに表示されてしまう
  • DataURLSchemaを使ってもダメ
  • WebGLに対応していることが前提になるが、WebGLRenderingContext.tex(Sub)Image2DにはImageDataを渡すことができる

アプリケーションコードの秘匿化

  • 共通鍵暗号・復号を行なっている箇所を特定されたり鍵を取られると今までの対策が破られてしまう
    • uglifyをかけた程度のソースコードでは該当の処理を特定される
    • 元のソースコードをA、暗号化した後のソース事をxhr経由で取得して復号した後にevalするプラグラムをC++で作成し、これをemscriptenで変換して利用する
      • evalしたコードはdevtoolに表示されない
      • そのままevalするとsourcemapで追えなくなるので、//#sourceUR=https://exmaple.com/app.jsのようにあのテージョンを付与してevalするとデバッグできるようになる
      • sourceURLをつけるとchromeが良かれと思ってdevtookにその名前でソースコードを表示してしまう
      • ソースコードなしの状態で一度evalしておくと、ソースコードが表示されない状態でdevtool上に表示される

インゲームのチート対策

  • ゲームの構成をインゲームとアウトゲームに分けた場合、インゲームはそのゲームの遊びのキモでありやりがいがある部分
    • それだけに攻撃を受けやすい

ロジックをどこで動かすか

  • クライアントのみで動かす場合
    • チーターから攻撃を受けやすく対策もしづらい
  • サーバのみで動かす場合
    • チートの攻撃は受けにくく対策もしやすい
    • サーバアプリケーションを書く必要がある
    • 通信していない事を意識されるゲーム体験を提供したい場合は応答速度に気を配る必要がある
  • クライアントとサーバの両方で動かす場合
    • 比較的ターン制のゲームに向いている
    • 同じロジックがサーバでも動くでチートはほぼ不可能でクライアントで計算した結果をすぐに表示できるのでユーザ体験もよくなる
    • アーキテクチャ的にも複雑になる

PWAのネイティブアプリ化

  • 期待されている事
    • 通信量の削減
    • パフィーマンスの向上
    • 各種ブラウザ起因のバグの解消
  • 実際の実装はwebviewを使うことがほとんどなのでブラウザ特有の問題は残る
  • 通信量の削減だけは対応できた(xhrとimage編)
  • WKWebViewのWKUserScriptを.atDocumentStartとして作れば任意のJSをアプリケーションロード前に読み込まれることができる
    • プリソードするJS内でXMKHttpRequestやHTMLImageElementの読み込みりょりをフックしてURLをネイティブ側にプロキシする
  • 動画編
    • あらかじめネイティブ側でダウンロードしたバイナリデータをblobに変換し、与えたblobデータを使って動画を再生できるようになる

まとめ

  • 触れられなかった具体的な話はbuilderscon tokyo 2019でする予定

HTML5でリアルタイム対戦の3Dシューティングゲームを開発してしまった。反省会

  • 技術的な条件
    • 3Dでサクサク
    • 縦画面
    • 片手で遊べる
    • 20人/サーバ
    • iPhone6(+)対応
  • 技術選定
  • Unity❌
    • モバイルで3D動かない
  • three.js❌
    • エディターがない
  • PlayCanvas⭕️(?)
    • 一見なかなかいい
    • 短期間でそれっぽいプロトタイプ
    • エディタがいい
    • 3Dサクサク

ドローコール管理

  • ドローコールの予算を立てる(100~150)

    • キャラクター、環境、発射体、シャドウ
    • スキンしたメッシュのバッチングはできない
    • マテリアルを減らす
    • カスタムシェーダを必要最低限
    • ライティング戦略
      • ライティングは贅沢
      • Scene全体に対し、ライト1つだけ
      • ポイントライトは必要最低限に
      • ベイクしたライティングを使用したいが、
        • バグがでとる
        • ダウンロードサイズが大きくなる
        • 静的オブジェクトは一度生成したらそのあとも使うのでドローコール1回で済むようにしている
  • FBXのインポートに要注意

    • PlayCanvasのFBXインポート機能は素晴らしい
    • マテリアルが組み込まれているFBXがあるとドローコールが倍に
  • パフォーマンスまとめ
    • 3Dアセット=重い
    • エンジン信用するな

ネットワーク

  • 要件
    • latency: 20~40ms(LTE/4G)
  • websocket: Head-of-Line blocking(1つのパケットを失うとその後のパケットも再度通信が必要に)
    • MTUを見極める:〜1400bytes超えちゃうと2個になる=>latencyが上がる
    • 通信不良によるパケット損失
  • 解決策
    • メッセージのサイズを1265bytesに制限
    • 移動:メッセージをバッチし、50msごとに通信
    • バッチにタイムスタンプをつけて、100ms以上古いメッセージを捨てる
    • 補完と外挿
    • ライブイベントはリアルタイムで通信

ビルドサイズ

  • ビルドサイズ7〜10MB
    • モデルはtextureなしで250k(45k圧縮)
    • CDNコスト3~5万円/月 for 5000~7000 DAU
    • キャッシュが残らない
    • PlayCanvasのアセットバンドリングを対応していない

ネットワークまとめ

  • メッセージングサーバはややこしい
  • ネットワークの深いところまで知っておかないと痛い目にある
  • ビルドサイズは気をつけないとバカにならない

まとめ

  • 3Dの課題は技術だけでは解決できない
  • 完璧なフレームワークはまだまだ
    • Unityがなんとか頑張ってくれる事を期待

感想

  • ブラウザゲーム特有(またはブラウザだけ顕著に現れてしまう)問題に向き合って一つ一つ対応している知見が聞ける素晴らしい勉強会でした
  • HTML5のゲームちゃんと作るにはネットワーク周りの知識がかなり必要
  • DRECOMさんのAROWおもしろそう

arow.world

PWA Night vol.3 ~PWAのミライや活用方法をみんなで考えよう~に参加しました

4/17のPWA Night vol.3 ~PWAのミライや活用方法をみんなで考えよう~にブログ枠で参加しました。 pwanight.connpass.com

各発表の内容と感想等をまとめます。

初めてのPWA開発 あなたのWebサイトがPWAになるまで

speakerdeck.com

PWAとはGoogleが推進する先進的なモバイルウェブのユーザ体験の指針

  • Reliable
  • Fast
  • Engaging
    • ネイティブアプリのように直感的に操作できる
  • PWAでできることの中で以下の三つについて話す
    • ネットワークに接続に依存しない
    • インストール可能
    • 常に最新

Service Worker

  • アプリごとにブラウザに登録され、バックグラウンドで動くスクリプト
  • swのイベント
    • install
      • ブラウザに登録
    • activate
      • アプリを制御できる状態
    • wait
      • 更新の登録待ち
    • unintall
      • ブラウザへの登録を解除

Service Workerが更新された時の流れ

  • すぐにswはインストールされずに待機状態になる
  • ユーザがアプリケーションを終了するとswがアップデートされる
  • そのあと最新のリソースをswが取得する

各場合別の挙動

  • 初回起動
    • アセットをキャッシュ
  • 2回目以降
    • リクエストを監視
    • データをキャッシュ
  • swの更新あり
    • アセットを再キャッシュ
    • リクエストを監視
    • データをキャッシュ

PWAを実装する

  • ネットワーク接続に依存しない
  • 常に最新

    • を満たす
  • installイベントでアセットをキャッシュする

  • 2回目以降はアセットのリクエストを検知する
  • fetchイベントで検知
    • データのリクエストを検知する
    • キャッシュのキーをswのバージョンにしておくことで、swを更新した時に最新のキャッシュを最新にする

Q&A

  1. アプリが使えるキャッシュストレージの容量
  2. ブラウザによってバラバラ

  3. ブラウザ標準のHTTPキャッシュ機能の影響は?

  4. わからない

  5. ブラウザごとの対応状況の違いへの対処

  6. アプリにとって重要な役割を担うような使い方は避ける 必要であれば非対応環境のユーザに向けてその旨と解決方法を伝える方法を考える

Cache APIに触れる by @tiwu_officialさん

「ネットワークに依存しない」とは

  • swがリクエストを傍受してキャッシュしたデータを返す
  • swは

    • プッシュ通知
    • バックグラウンド同期
    • オフライン対応
      • やってくれる
  • respondWith()でレスポンスを返す

    • caches.open()でキャッシュ取得
    • cache.match()でキャッシュが存在するか判定
    • 存在したらreturn responseでレスポンスを返す
  • swがキャッシュの仕組みを持っているわけではない

    • swはリクエストにイベントを貼ることができるだけ
      • => Cache APIがキャッシュを行なっている
  • window、workerスコープで利用できる

    • localstorageと同じ感覚
    • swで結びつけて使う必要はない
    • 有効期限は持てない
    • StorageEstimate APIでキャッシュ使用状況がわかる
    • グローバルにcachesという変数がある

Cache API

  • caches.open()の引数を別にすることで複数のキャッシュを持つことができる
  • メソッド(更新系)
    • put(request, response)
  • 追加系
    • add(request)
  • 取得系
    • match(request, options)
      • options
        • ignoreSearch: クエリーを無視する
        • ignoreMethod: メソッドを無視する
    • matchAll(request, options)
  • 削除系
    • delete(request, options)
  • その他
    • keys

プロダクトでの使い方

  1. 一覧の詳細で必要な静的リソースを読み込む
  2. 古いバージョンを消して新しいキャッシュを作る

まとめ

  • swではなくcache APIによってキャッシュされる
  • LSと使い方似ているAPI
  • 使いこなすとかなり強力
  • ~ネットワークにアクセスしたら負け~

RoRをVueJS + Nuxt PWAで置き換えてみた by 天野たけしさん@devMeTokyo

moksahero.github.io

みんなが普段使っているサービスは、世界最速のサービス

  • PWA対応済み
  • ユーザの期待値は高くなっている
  • 常にオリンピックを見ているのでそれ以外は県大会レベルに見える
  • 少しでもオリンピックに近づけないといけない

PWA化で実現すること

  • サイトパフォーマンスが上がる
  • PWA StatsはPWAの成功事例がまとまっている

ITのプロジェクト

  • 何か新しいことをやらないといけない?
  • 今あるサイトを改良するとKPIや売り上げが上がる
  • 既存のビジネスモデルを変える必要がない

PWAへ置き換えをした

  • JAM STACK

    • JavaScript -> Vue, React
    • APIs -> GraphQL, REST
    • Markup(静的サイトジェネレーター) -> Nuxt, gatsby
  • 置き換え後の各レイヤー

    • レスポンシブ -> スマホファースト
    • 70-80%はスマホからのアクセス
    • スマホ版が先
    • スマホに特化したUIで作る
    • パソコン版は別で作る
    • SPAよりもパフォーマンスが出る
    • cssのライブラリはBuefyを使用
  • データ取得: RoR->Lambda

    • Lambdaでmodel諸々を置き換える
    • serverlessなのでアクセスに耐えられる
  • インフラ
    • EC2->S3+Cloudfront
    • EC2やめたのサーバー管理費が安くなった
  • ユーザ認証: 独自実装->Auth0

    • ログイン周りの実装がシンプルに
    • custom databaseを使って既存のユーザの移行可能
    • 日本語の対応それなりに必要
  • MySQL RDS

    • 唯一弄らなかったところ
  • 各KPIの改善など

    • リリース後にまたお伝えします

LT-1: 最大公約数的なServiceWorker制作から見るPWAの勘所 by 進藤龍之介さん@NPO法人日本Androidの会

  • wordpressプラグインを作っている方

  • みんなの環境にマッチしやすいPWA

  • PWAはキャッシュが命
    • Cache FirstとOnline First
  • キャッシュの除外
    • キャッシュされてはいけないものを除外する
    • 正規表現で柔軟にURLを指定
  • キャッシュの有効期限
    • 古いキャッシュを一定期間で捨てる
  • キャッシュする|しないの切り分けが大事

LT-2: Service Workerのcacheで色々問題が起きた話 by biga816さん

speakerdeck.com

  • 地下アイドルDAppsを作っていた
  • ionic3を利用
  • SW-Toolboxを利用(今はDeprecatedとなっている)

起こった問題

  • キャッシュの上限を超えた

    • 解決策
      • キャッシュの上限数を決めた
  • 開発環境のみ上限を超えた

    • AoTコンパイルが実行されていなかったのでそのファイルもキャッシュされていた
    • 解決策
      • 定期的にキャッシュ削除した
      • ローカルで開発するときはswをオフにする
  • キャッシュから動画が再生されない

    • safariでのみ問題が発生
    • Rangeリクエストに対しsafariではレスポンスコード200を受け取るとそれ以降そのファイルを読み込まない仕様になっていた
    • 解決策
  • キャッシュ対象はオフラインで最低限参照できるファイルに絞る方がいい

LT-3: Ionic PWA Toolkitについて by scrpgilさん

speakerdeck.com

  • Ionicについて
    • Ionic4 ReactやVueでもかける(Angularをすてた)
  • PWA Toolkitについて
    • デフォルトでworkboxが設定済み
    • などなど盛り込まれている
    • これからPWA始めるなら圧倒的敷居の低さ

Ionic Framework - Pwa Toolkit

感想とまとめ

  • PWA対応はwebアプリのUXを改善する為に行うもの
    • アプリのパフォーマンス改善こそがコンバージョン率などKPIの向上に繋がる
  • PWAのiOS対応はやはりどこも苦心されている様子だった
    • iOSの各バージョンがPWAにどこまで対応できているのかまとめとかないんだろうか
  • キャッシュ戦略考えるの楽しそうだけど、すでに動いているサービスのリソースを全部洗い出して適用させていくのはかなり骨が折れそう
    • 新規実装する場合は、初めからキャッシュ戦略を考えながら実装できると良さそう
  • PWAは関係ないけど、serverless framework勉強しようと思った
    • EC2の利用料下げれるの美味しい
  • Hasura GraphQL EngineというPostgreに対応したGraphQL Serverを構築できるエンジンがある
  • Ionic3以前は触って見たいと思わないが、Ionic4は良さそう
    • PWA Toolkitもかなり良さそう
  • PWA Night vol.4 ~PWAのミライや活用方法をみんなで考えよう~もすでに公開されていました
    • 1ヶ月後なのにもうトーク内容が決まってるのすごい

YAPC::Tokyo 2019に参加しました

2019/1/26(土)に開催されたYAPC::Tokyoに参加してきました。

YAPCの噂は昨年入社してから耳にこそしていましたが、参加したのは初めてでした。

Perlを軸としたカンファレンスとのことですが、いろんな技術の話が聞けてお昼に出た幕の内弁当のように楽しめるカンファレンスでした。

(今年は例年よりPerlの話が多かったそうです笑)

感じたことを忘れないうちにまとめておこうと思います。

yapcjapan.org

聞いたトーク

※軽く探して見つかった公開されているスライドだけ載せています。

載せていないスライドで公開されていないものがあれば教えていただけると助かります。

チームが前に進み続けるために僕たちが考えたこと

チームが前に進み続けるために僕たちが考えたこと / YAPC::Tokyo 2019 - Speaker Deck

スクラムを参考にしつつ、自分達にとって最適な開発フローを模索していったという話。

  • 業務・開発フローは「変えることは無条件に正しい」くらいに思って良いと思っています
  • 変化に対応し続けないといけない
  • 手を動かしたものだけが世界を変える

実例を元にした、「前に進み続けるため」の考え方についての内容は非常に説得力がありました。

チーム開発の難しさは入社当時に感じ、いまだに感じ続けていることですが、変化を起こさないことには何も変わらないことを再認識させられました。

結局物理カンバンを使うようになったという話は、最近ポストイットを使って便利さを感じたので共感できました。

(デジタル上の方がいつでも参照できて、永続的に残るので便利だと思ってたのですが、なぜでしょう)

私とOSS活動とPerl

私とOSS活動とPerl

世界はOSS開発者に優しいという言葉はとても実感がこもっていて、素敵な話でした。

自分が必要なものを作ったら、それを他の人にも使ってもらえたというのはたまらないだろうなと感じました。

IntelliJ IDEAのPerl pluginであるPerl5-IDEAは気になりです。

GitHub - Camelcade/Perl5-IDEA: Perl5 plugins for IntelliJ IDEA

Perl to Go

GoでWebアプリケーションを書く流れをPerlを普段書いている人がざっくり掴める話。

Perl MongerがGolangを始める時にはまったところの話では、GoにはCPANのようなライブラリの中央集権的サーバーがないことなど、Goを始める上で前提として知っておくべきことを聞けてとても参考になりました。

(バージョン管理されているライブラリがまだ少なく、管理が難しい、管理ツールがまだ二転三転しているなど)

ライブラリの管理が容易になったらGoでWebアプリケーション書いてみたくなりました。

(Perlから今はGoを書いているという人も多い印象ですよね)

ランチスポンサーセッション

Garudaというサービスについてのトークと20歳で新卒入社してPerlを書き始めた人のトークがありました。

今はPerlで書かれたプロジェクトをGoで書き直しているということでやはりWebアプリケーションをGoによって書くことはメリットが大きいようです。

Perl on Rails(GUEST: 大仲 能史)

PerlのプロジェクトにじわじわとRailsのソリューションを取り入れていっているお話。

自分も最近副業でRailsを書いているのですが、Webアプリケーションを作る上で必要で役立つ機能全部盛りな感じに感動しています。

どんなWAFでも必ずいつかは下火にはなるのでしょうが、今使っているWAFから次の開発に活かせるものを頭の隅に残しておけると良いのかなと感じました。

自前運用のZabbixからマネージド監視サービスMackerelへ - ソーシャルゲームタイトルのサーバ監視の移行事例

サーバ監視をZabbixをやめてMackerelに以降した話。

監視ルールや設定値などを例を元に話されていたのですが、自分で監視サービスを設定したことがないためかあまり理解できず・・・。

普段はメトリックを眺めるだけですが、どんなメトリックが必要か考えて設定していく力も必要だなと感じました。

ログにやさしいDB設計

ログのDB設計についての話。

ログは、

  • データ分析
  • 問い合わせの事実確認
  • 障害の原因究明
  • 障害の自動検知

のために必要で、そのための要件は、

  • 整合性
  • 網羅性
  • 追跡容易性

ログはなぜ必要なのか、そしてユースケースはどんな時か考えて、それを満たすために必要な要件を考えるというのは、ログを取る上でまず考えるべきことだというのは非常に腹落ちしました。

CPAN Module Hacks

CPAN Module Hacks - Speaker Deck

CPANへのアップ方法やプライベートCPANの作り方などのお話。

meta::cpanはauthorにフォーカスしていて、ダウンロード数などは表示されていないといった話は、ライブラリに対する各言語の思想などが伺えて面白い見方でした。

そして、CPAN TestersのモジュールをいろんなPerlのバージョンや実行環境で実行可能かテストする機構はすごい!

CPAN Testers Reports: Index

Dive into MySQL Error

Dive into MySQL Error (YAPC::Tokyoバージョン) - Speaker Deck

MySQLのエラーの仕組みを考えるお話。

エラーコードの1000, 3000番台はサーバーサイドエラー、2000番台はクライアントサイドエラーなど、エラーコードを見るだけでエラーの原因の切り分けができるというのはとても参考になりました。

レプリケーションスレーブはマスターから見るとクライアントと言えるというのもエラーコードによる切り分けに役立つ考え方でした。

エラーフォーマットやエラーログについての内部実装まで踏み込んだ話もユーモアを交えつつでとても面白かったです。

ここまでMySQLに強い人というのもなかなかいないのではないでしょうか・・・?

Lightning Talks

5分という時間に圧倒的に密度でした。

Perl6の正規表現の問題、npmでPerlのライブラリのインストール、Amazon LambdaでPerlのランタイムを動かす、Perl1をGoで書き直す、Perl入学式のコミュニティの話などPerlの話をこの密度で聞けたのは初めてで、楽しかったです。

Keynote: 松野 徳大

tokuhiromさんがこれまで歩んできたエンジニア人生の一端。

いろんな人を巻き込んで、不満のあるライブラリを作り直してAmon2などを作っていったという話はもちろんすごいのですが、それ以上にエンジニアとしての最高に楽しそうなところが何よりすごい、と感じました。

自分は今の所OSSの開発にはあまり興味はないのですが、後から振り返ってあの時は楽しかったと言えるエンジニア人生を送ろうと思うことができました。

最後に

自分は普段Unityの勉強会に参加することが多いのですが、YAPCは幅広い年代のエンジニアが集っている印象を受けました。

技術的な話だけでなく、いろんな開発者の歩んできた道の一端を聞くことができる貴重な機会だったと思います。

次の開催地は募集中だそうですが、ぜひRubyの総本山のShimaneで開催して欲しいです笑

その時はまたトークのsubmitをさせていただきます!

最後になりますが、運営の方々素敵なYAPCを本当にありがとうございましたm(_ _)m