GameWith Developer Blog

GameWith のエンジニア、デザイナーが技術について日々発信していきます。

iOSのViewが画面上に表示されたことを判定する実装方法 #GameWith #TechWith

こんにちは、iOSエンジニアの chuymaster です!

最近とある案件で、ユーザーが特定のViewを見たかどうかを計測しました。iOSエンジニア向けに、その実装方法について紹介したいと思います。

目次

背景

弊社は、設置したバナーの効果測定のため、ユーザーが何人バナーを見て、何人クリックしたかというデータを集計しています。

広告用語でいうと、クリック率(CTR)に当たる数字を集計して、分析しています。

それに基づいて、どういうバナーが効果が良いのかの実験が日々行われていますが、iOSアプリではそのようなことができませんでした。

要件

元々各バナーのクリックイベントは記録していますが、インプレッション(表示)イベントを記録していなかったので、CTRを測定できませんでした。

今回はインプレッションを記録する実装を下記の「統合トップ」画面で行いました。

f:id:gwchai:20200526150111p:plain:w300
統合トップ画面

インプレッションの定義は様々ですが、Googleアドマネージャーの定義に従いました。

Google アド マネージャーでは、業界基準に沿った方法でモバイルアプリ インプレッションがカウントされます。つまり、デバイスの画面に広告クリエイティブが 1 ピクセル以上表示されると、モバイルアプリ インプレッションが 1 回カウントされるという仕組みです。

実装要件に置き換えると、対象Viewが画面上に1pxでも表示されればインプレッションイベントを送ることになります。

実装

下記が対象画面の構成になります。

f:id:gwchai:20200526183630p:plain
インプレッションを判定したい箇所

見ての通り、インプレッションを判定したい箇所は3種類あって、かなり深い層にあります。 インプレッションログ送信の実装要件はこのようになります。

  1. UIScrollViewの中のUIViewが画面内に表示された際
  2. スクロールが無効なUICollectionViewの中にある、UICollectionViewCellが画面内に表示された際
  3. 横スクロールが有効なUICollectionViewの中にある、UICollectionViewCellが画面内に表示された際

基本的な実装コード

stackoverflow.com

上記のスレを参考に、scrollViewDidScroll(_:) 時に、スクロールして見える bounds と対象の UIViewboundsintersects(_:) したら、インプレッションログを送信します。

しかし、Viewが複数階層でネストされている対象画面では、そのまま UIViewboundsUIView が交差しているかどうかを判定すると、ローカル座標が返されて間違った判定になってしまいます。そこで登場するのが convert(_:to:) 関数です。

view.convert(bounds, to: UIScreen.main.coordinateSpace)

これで画面上の空間での座標に変換できます。詳しくはこちらを読んでみてください。 https://developer.apple.com/documentation/uikit/uicoordinatespacedeveloper.apple.com

①UIViewが画面上に表示されたことを判定するコード

完成したコードがこちらです。

func detectImpressions(scrollView: UIScrollView, view: UIView) {

        // スクロールした位置で見えているフレームの位置を計算する
        let currentVisibleFrame = CGRect(x: scrollView.contentOffset.x,
                                         y: scrollView.contentOffset.y,
                                         width: scrollView.frame.size.width,
                                         height: scrollView.frame.size.height)

        // 見えているフレームの位置を、画面上の位置に変換する
        let currentVisibleFrameInMainSpace = scrollView.convert(currentVisibleFrame, to: UIScreen.main.coordinateSpace)

        // Imp計測対象Viewのフレームの位置を、画面上の位置に変換する
        let viewFrameInMainSpace = view.convert(view.bounds, to: UIScreen.main.coordinateSpace)

        // 重なりを判定する
        if viewFrameInMainSpace.intersects(currentVisibleFrameInMainSpace)
         {
            // インプレッションログを送信する
         }
    }

スクロールして見えたフレームと、対象Viewのフレームを UIScreen.main.coordinateSpace 空間の座標に変換して、画面上に見えているかどうかを判定します。 あとは scrollViewDidScroll(_:) で呼び出せば良いです。

これで、要件①UIScrollViewの中のUIViewが画面内に表示された際の判定処理が実現できました。

②UICollectionViewのUICollectionViewCellが表示されたことを判定するコード

UICollectionView の場合は、中のセルのフレームを見て判定する必要があります。

stackoverflow.com

上記の回答を参考に、今見えているセルの indexPath.row を返す関数を実装しました。

   func getVisibleRows(currentVisibleFrameInMainSpace: CGRect, collectionView: UICollectionView) -> [Int] {
        var visibleRows = [Int]()

        let visibleIndexPaths: [IndexPath] = collectionView.indexPathsForVisibleItems
        for indexPath in visibleIndexPaths {
            guard let cell = collectionView.cellForItem(at: indexPath) else { continue }

            // 画面描画位置の重ねで表示されたかどうかを判定する
            let cellRect = cell.contentView.convert(cell.contentView.bounds, to: UIScreen.main.coordinateSpace)
            if currentVisibleFrameInMainSpace.intersects(cellRect) {
                visibleRows.append(indexPath.row)
            }
        }
        return visibleRows
    }

引数に①の関数で取得した画面上のフレーム座標を渡して、各セルの座標と比較して画面上に見えているかどうかを判定します。

collectionView.indexPathsForVisibleItems がそのまま使えない理由は、今回の実装では、全てのセルを最初から展開して描画させているため、すべてのセルの indexPath が返却されるからです。

これにより、要件②スクロールが無効なUICollectionViewの中にある、UICollectionViewCellが画面内に表示された際の判定処理が可能になります。

要件③横スクロールが有効なUICollectionViewの中にある、UICollectionViewCellが画面内に表示された際のも同じコードでできますが、scrollViewDidScroll(_:)delegateUICollectionView に変える必要があるので、ご注意ください。

スクロールが有効なUICollectionViewなので、 collectionView:willDisplayCell:forItemAtIndexPath: は一見使えるように見えますが、実際はユーザーが見えない場所で呼び出されることがあるので、使わない方が良いです。

注意点

初回表示時の判定

scrollViewDidScroll(_:) で判定処理を入れているので、画面ロード後、ユーザーの操作なしだと判定処理が走りません。

そのため、画面ロード後に明示的に判定する必要があります。

GameWithアプリでは RxSwift を使っているので、scrollView.rx.contentOffsetSubscribe して初期状態でも判定させることができました。

判定タイミング

この方法は、画面上の描画後の座標を元に、2つのフレームが交差したかどうかを判定しています。

そのため、描画完了前に判定してしまうと正しい座標になりません。

判定がおかしいなぁと思ったら

  1. view.layoutIfNeeded() で描画させる
  2. DispatchQueue.main.async 内で判定処理を呼ぶ

のどちらかを試してみてください

重複除外

scrollViewDidScroll(_:) で表示判定をしているので、イベントが何回も送られます。 一度送ったイベントを送らないように除外する必要があります。

最後に

この実装でかなり時間がかかったので、同じ課題に当たるiOSエンジニアの方に少しでも役に立ったら幸いです!

GameWithのDeveloper向けTwitterアカウントがあります。

ブログの更新情報などを発信するので良かったらフォローしてください!!

twitter.com

サスティナブルな社内LT #GameWith #TechWith

サスティナブルな社内LT

こんにちは! コミュニティではごーと呼ばれている只野です。

前回社内LTを続けるコツについて、ブログに書きました!

tech.gamewith.co.jp

今回はオフィスで開催していた社内LTをオンライン開催に変更をしていった経緯について書いていきたいと思います!

サスティナブルな社内 LT とは

私たちは、社内 LT を GamWith の開発組織における文化形成の手段として行ってきました。LT を行う機会が増えると、個性を共有できるようになり、個性の集まりが GameWith 特有の文化として根付いていくことが期待できます。 この取組みが長いスパンで行われることを sustain(持続する)とable(〜できる)からなる言葉と重ねて、「サスティナブルな社内LT」 と考えています。

社内LTの変化

1. オフィスで開催していた時期

以前書いたブログにもある通り、毎週金曜日の19:15 ~ 19:45 に社内 LT を開催していました!

この時期については上記のブログに詳しく書いてありますので、そちらをご参照ください。

2. 出社組とリモート組が混ざっていた時期

LTの発表は出社組が zoom でオフィスから社内LTを配信しリモートしているメンバーも視聴していました。

3. フルリモートになった初期

2の時期は在宅勤務の推奨となっていましたが、3/30(月)に発表のあったとおり弊社はフルリモートへ移行しました。

gamewith.co.jp

フルリモートに移行して1ヶ月ほどは社内 LT を開催していませんでした。

フルリモートという環境の大きな変化もあり、社内 LT の開催方法などについて考える余裕があまりなかったのが正直なところです。

4. フルリモート後の復活

4/17(金)に社内 LT を復活させ、今日まで毎週開催しています。

全員がフルリモートの環境に徐々になれてきたため、復活させました。

全員フルリモートなので、逆に社内 LT はやりやすいのでは?と気づきました。

プロセス

時間帯は毎週金曜日の19:30 ~ 20:00に行っています!

以前までは2,3人が10分程度LTを行っていましたが、現在は4人が5分程度 LT を行っています。

人数と時間を変更した理由としては、以前までは質疑応答や感想を話したりとコミュニケーションの時間を取っていました。 しかし、オンラインで双方向のやり取りが難しいと思い、視聴者にはマイクをオフにしてもらい配信形式のような形にしました。 また、視聴者が飽きないように短い LT にして発表者の人数を増やしました。

オンラインになったので無音の時間ができるだけ無いように、テンポの良いファシリを心がけています。

オフィスで開催していたときは写真を撮っていましたが、オンライン開催では社内 LT の配信を録画し編集しています。 編集で無音をカットした動画は、テンポが良くとても見やすいです。

最初の方は録画した映像を iMovie を使い手動で編集していたが、とても大変でした😭 現在は vrew というツールを利用して自動で編集をしています!

vrew.voyagerx.com

オフィスで開催していたときより発表者の人数が増えた分、時間通り30分で終わらせるために多めにバッファを取っています。

視聴者は Slack のスレッドにコメントをしています。 最初は画面にコメントが流れるツールを使っていたが、準備が大変で今の形に落ち着きました。

LTが5分になり発表者の準備もそこまで時間がかからないので、発表者の準備が以前と比べて楽になりました。

告知は週の前半で1回お知らせをして、開催時間の少し前に再度お知らせをしています。

f:id:tiwu:20200521190555p:plain

全員参加しているチャンネルで告知をしているので、頻繁に @here をしないように告知の回数は最小限にしています。

効果

オンライン開催になったので席が少し遠かった人も発表をしたり、視聴者として参加するようになりました!

オンライン化により可能性が広がった事で、今後外部との合同 LT なども検討しています。 弊社と共に LT を開催したい場合などは、是非 @gamewith_dev まで気軽にご連絡ください!

フルリモートになり曜日の感覚が薄まっていったが、毎週金曜日の19:30に開催をしているので、少しずつ曜日の感覚を取り戻してきたのではないかと思います。

またフルリモートになって他チームの人の顔を見る機会が以前よりも減ったので、この社内 LT で他チームの人の顔が見れることもオンライン化のメリットだなと感じました。

オンラインになったので、作業中の BGM として社内 LT を聞くこともできますし、参加するスタイルはより自由になっています。

まとめ

以前のブログで社内 LT を続けるのに特に苦労はなかったと書いたのですが、上記の通りフルリモートになった際に一ヶ月ほど社内 LT の開催を停止してしまう時期がありました。

ですが、いざ再開してみると意外と問題なくオンライン社内 LT が実施できることがわかりました。

この数ヶ月で日々の MTG などの通常業務もフルリモート体制に移行したこともあり、自分達が思いの外オンライン環境に適応していたことがわかりました。

これからもサスティナブルな社内 LT をやっていきたいと思います!

最後に

GameWithのDeveloper向けTwitterアカウントも開設しました。

ブログの更新情報などを発信するので良かったらフォロー宜しくお願いします!

twitter.com

GameWithのリプレイスについて vol.2 ~Web Components を Vue で書いたら最高だった編~ #GameWith #TechWith

はじめに

こんにちは!Incremental Stream Team の@53able, @inosy22, @nog です!

前回のブログでは Gamewith で行っているリプレイスの概要について紹介しました。

tech.gamewith.co.jp

今回は Web Components を Vueで開発するための、システム( GameWithDesignSystem)を開発したので紹介したいと思います。

GameWithDesignSystem とは?

Vue で実装したコンポーネントを Web Components として配布をし、どんなプロジェクトでも利用できるコンポーネントを提供するシステムです。

実際に GameWith では下記のスクショのようにカウントダウンをする広告をGameWithDesignSystemで開発しました。

f:id:tiwu:20200416194434p:plain

GDS の目指す世界

  1. どんなプロジェクトでも簡単に利用できるHTMLコンポーネントの提供

  2. 将来的にデザイナーも UI/UX 改善に利用できるようにしたい

  3. 将来的にエコシステムを OSS として公開したい

作った背景

課題

リプレイスでは、Nuxt.js (Vue.js) を採用しています。

現在は BFF(Backends For Frontends)で Nuxt.js を動かして、SSRのみ行っています。(クライアントで Nuxt.js が動いているわけではありません)

リプレイスは段階的に行う計画のため、上記の対応によって既存のJSは後ほどまとめてリプレイスする予定でした。

しかし、既存のJSの部分的リプレイスを実施する必要が出てきました。

既存コードと新規コードを共存させる場合は、jQuery による DOM 操作と Vue で扱う仮想 DOM との相性が良いとは言えず、部分的にクライアントで Vue を取り入れるのは難しい状態でした。

部分的リプレイスの要件

  • 既存の jQuery で書かれている JS をモダンに実装
  • 将来的には完全な形で BFF にリプレイスする見込み
  • 既存のJSを Nuxt.js + TypeScript で実装し、BFFへ移行時に再利用
  • 既存のJSからの仮想 DOM の破壊を防ぐ

解決案

  • 仮想 DOM を破壊しない、ShadowDOM を採用
  • ShadowDOM を利用するために、Web Components を採用
  • SFC(Single File Component)を実装したあとに、Web Components へビルドできる環境

これまでリプレイスの BFF は Nuxt.js + TypeScript で実装してきていたので、技術的に要求されるギャップはなかったです。

また、SFCで実装してあれば、将来的にBFF(Nuxt.js)で再利用も可能です。

さらに、リプレイスチームだけでなく他のチームでも利用できるようにするため、リプレイスチームのプロジェクトに依存しない構成にしました。

技術構成

利用技術

  • Vue
  • VueCLI
  • @vue/web-component-wrapper
  • TypeScript
  • Storybook

@vue/web-component-wrapper

Vue コンポーネント をカスタム要素(Web Components)としてラップして登録します。

Vue 公式のラッパーです。

Composition API や Props や Vueの Life cycle method などの基本的な機能は、 Web Components にビルド後に問題なく動作します。

不要な Web Components のカスタム要素を生成しないようにするために、コンポーネント名は、prefix に _ で対応しました。Scss の仕組みを参考にしました。

vue-cli-service build --modern --target wc-async --inline-vue --name gds --dest 'dist/public' 'src/components/**/[!_]*.vue'"

@vue/web-component-wrapper

Storybook とどう連携するか

初期は、Storybook を導入していませんでした。

作成した Vue コンポーネントは App.vue に追加し、VueCLI の serve 機能を利用してブラウザに表示して確認しデバッグを行っていました。

しかし、そのままだと手間がかかる上に、リリースして実際に利用される Web Components での動作を常時確認したいので、カスタム要素を Storybook 上で管理できるようにしました。

Storybook では、利用するときに SFC をビルドしたコードを import する必要があります。

最初は新しいコンポーネントを追加する都度、該当するコードの import 文を書き換えてましたが、手間がかかっていたので下記コードでカスタム要素をすべてインポートするように自動化しました。

const fs = require("fs");
const scriptPath = "./dist/private";

// ファイル一覧からimportの文を作る
const makeIndexContent = files => {
  let content = "";
  files.forEach(item => {
    if (!item.endsWith(".min.js")) return;
    content += `import "./${item}";\n`;
  });
  return content;
};

// 非公開も含む全コンポーネントのindex.jsを作成
fs.readdir(scriptPath, (err, files) => {
  if (err) throw err;
  const content = makeIndexContent(files);
  fs.writeFile(`${scriptPath}/index.js`, content, err => {
    // eslint-disable-next-line no-console
    if (err !== null) console.log(err);
  });
});

コンポーネント開発をストレスなくやるために

  • stylelint-config-rational-order をStylelint に組み込んで、css プロパティの並び順を一律自動整形しています。

  • SFC を新規実装するときに、コマンドによってテンプレートからファイルを生成するようにして最低限必要なコードが揃っている状態から実装始められるようにしています。

リリースフロー

ビルドされたJSファイルをS3にアップロードします。

アップロード先は package.json の version を元にパスを切ることで、ブラウザキャシュのバグを防ぎ、カナリアリリースを実現させています。

利用したいバージョンのパスを指定して <script> タグで読み込むことによって、定義された Web Components のカスタム要素を利用できます。

利用する Web Components のJSだけが部分ロードされるので、コンポーネントの量が増えても問題ありません。

f:id:tiwu:20200416194503j:plain

苦労した点

  • ShadowRoot 内で document.* が使えずクッキーなどが取得できませんでした。

  • ビルドの監視や、 hot reload など行いたかったが、まだ対応できてないです。毎回全てのSFCをビルドしているので、確認まで数秒時間がかかってしまいますし、ビルド実行を自動化できてないです。

感想

SFC から Web Components へビルドし、利用できる方になるまでの過程で煩雑な作業をひとつひとつ解決してきており、 コンポーネント実装以外の工程は、設けているコマンドを実行することでまかなえるようしています。

初めてGDSを触る人にも易しい構成になっていきています。

独立したシステムで SFC を開発とテストすることは、配備される環境で考慮することが少なくて済むので、コアロジックに集中ができます。

しかし、SFC は Vue.js を前提に実装できることから容易にたくさんの仕様を詰め込んでしまうことが可能です。

コンポーネントの粒度は考慮する必要があります。

ただし、粒度が大きいコンポーネントを作ってしまっても、今回は TypeScript で実装しているので、後で分割するときにコードの整合性はコントロールしやすいと感じました。

レガシーな環境でも、モダンなコードで実装されたコンポーネントを追加できるので、今後は開発するのに継続的な効果が期待できそうです!

最後に

GDS の開発環境は、将来的には公開して利用できる様にしていきたいと考えているのでご期待下さい。

また、GameWith にイケてるコンポーネントがこれからたくさん作られていくので、ぜひ探してみてください!

GameWithのDeveloper向けTwitterアカウントも開設しました。
もくもく会の告知やブログの更新情報などを発信するので良かったらフォロー宜しくお願いします!

twitter.com

GameWith iOS もくもく会 #20 開催しました #GameWith #TechWith #gamewith_moku2

こんにちは!
GameWithのiOSエンジニアのkyamです。
2月20日(木)にGameWith主催で第20回目のもくもく会を開催しました!

GameWith iOS もくもく会 #20

https://gamewith.connpass.com/event/166701/

前回のiOSの開催が9月だったので5ヶ月振りの開催となりました。
今回は社内1人、社外2人の計3人が集まってくれました!

当日の流れ

f:id:keeetaka:20190930141449p:plain

最初にお知らせ、次に自己紹介と今日の作業内容を発表して、軽食を挟みながら2時間程もくもくし、最後に進捗の発表という流れで開催しました!

進捗発表

以下がメンバーの取り組んだ内容です。

  • 個人アプリの開発環境整備
  • 個人アプリ(日記アプリ)のUIPageViewを使ったUIの実装
  • 個人アプリにFirebaseを使ったPush通知の実装

といった風に全員が個人アプリに関する取り組みでした!
今回は人数も少なかったため開発中のアプリについての雑談や知見共有など密なコミュニケーションも終了後に行われました。

以下はお知らせになります!

お知らせ1

GameWith iOSもくもく会参加者用のslackワークスペースを作成しました!

作業中に気軽に質問などを投げることができ、誰でも返答できるようにし、参加者にとって勉強会自体の効率をよりあげたり、勉強会前後のコミュニケーションを高めたいという意図からです。 またちょっとした事務連絡などもSlackで行えるようにしました。

既に6人の方が参加してくれました!

お知らせ2

GameWithのDeveloper向けTwitterアカウントを開設しています。
もくもく会の告知やブログの更新情報などを発信しているので良かったらフォロー宜しくお願いします!

twitter.com

最後に

参加していただいた皆様ありがとうございました!
3月以降も基本的に毎月開催していく予定なので、興味のある方は是非参加してください。

GameWith フロントエンド もくもく会 #19 開催しました #GameWith #TechWith #gamewith_moku2

GameWith のエンジニアの tiwu です。

1月30日(木)にGameWith主催で2020年最初の第19回目のもくもく会を開催しました!

GameWith フロントエンド もくもく会 #19

gamewith.connpass.com

新年1発目のテーマは僕自身が関心を高く持っているフロントエンドを採用しました。

もくもく会は社内1人、社外5人の合計6人で開催しました!

f:id:tiwu:20190329134140p:plain

もくもく会は最初にお知らせ、次に自己紹介と今日のもくもく内容を発表して、もくもくし、最後に進捗発表という流れで開催しました!

2時間ほどもくもくしたら本日の進捗の発表をしました!

  • web components で作られた 格闘ゲーム便利ツールにフレーム比較機能を追加
  • Chart.js を利用したグラフの表示
  • python + django で作られた Web アプリのコードリーディング
  • Udemy で Vue.js の勉強
  • gulp + jQuery で作られたポートフォリオを Vue.js に置き換え&Netlify で公開
  • Vue.js + TS で Web アプリを作成

といった様々なテーマの取り組みのもくもく会でした!

最後に

参加していただいた皆様ありがとうございました!

今年もよろしくおねがいします!!

GameWithのDeveloper向けTwitterアカウントを開設しました。

もくもく会の告知やブログの更新情報などを発信するので良かったらフォロー宜しくお願いします!

twitter.com

PHPerKaigi 2020 にスポンサーとして協賛します #GameWith #TechWith #phperkaigi

こんにちは。GameWith のエンジニアの tiwu です。

この度、2/09, 10, 11 に開催されるPHPerKaigi 2020 に協賛をさせていただきます!!!

PHPerKaigi 2020

phperkaigi.jp

PHPerKaigi は去年も開催されており、弊社は去年の PHPerKaigi も協賛させていただきました!

tech.gamewith.co.jp

今年もとても楽しみにしています!

PHPer チャレンジ

去年も開催された PHPer チャレンジが今年も開催されます!

blog.phperkaigi.jp

PHPerチャレンジとは

PHPerチャレンジは会場内外に隠された「PHPerトークン」を探しだし、イベントサイトに入力して得られたスコアを競う企画です。 PHPerトークンは「記号の# + 任意の文字列」の形をしています。

PHPer トークン

弊社もこの PHPer チャレンジに参加しており、このブログのどこかに、 PHPer トークンを仕込みました!!!!

頑張って見つけてみてください🙏

最後に

GameWith では一緒に働く仲間を募集中です!

毎月もくもく会なども開催しているので、気軽に連絡ください!

recruit.gamewith.co.jp

ツイッターアカウントを開設しました!

ブログ更新情報や、イベントの開催など告知していきます!

twitter.com

社内 LT を8ヶ月続けてみて気づいた15個の続けるコツ #GameWith #TechWith

はじめに

こんにちは!

コミュニティでは、ごーと呼ばれていますが、社内では本名で呼ばれています。

只野です。

今回は GameWith で毎週開催している社内 LT について書いていきたいと思います!

社内 LT の紹介

毎週金曜日の19:15 ~ 19:45 の30分開催しています!

登壇者はエンジニア・デザイナーだけでなく、ディレクターや管理部の方、技術顧問など社外の方にも登壇していただきました!

登壇の内容はとても幅広く、GameWith のコードの話や、最新の技術、チームマネジメントの話や、サウナの趣味話など多岐に渡っています!

毎回の登壇者は立候補制ではなく、スタッフが勧誘し調整を行っています。

運営スタッフは自分を含めて3人です。

場所は会議室ではなく、執務エリアに近いオープンスペースで開催しています!

f:id:tiwu:20200117150959p:plain

飲み物として、レッドブルとノンアルコールビールを用意し乾杯しています!

タイムテーブル

登壇は一人15分(内5分の質問タイム)です。

19:10 ~ 19:15 前座

19:15 ~ 19:30 一人目

19:30 ~ 19:45 二人目

数字で見る社内 LT

最初の開催は2019年5月24日で、今までに合計25回開催しました!

現在までに、約40名ほどいるサービス開発部メンバーの9割の方に登壇していただきました!

社内 LT の開催のきっかけ・始め方

最初の LT 会の開催は、自分が Roppongi.vue で登壇予定でその練習をするため、自ら社内 LT を行いました。

こちらが実際に登壇をした Roppongi.vue です。

roppongi-vue.connpass.com

LT 開催後に部長から他にも LT をできる社員がいると共有を受け、それならばと毎週開催することにしました。

また、丁度この時期に他の社員が外で登壇をしており、その登壇内容を社内で話す機会がないのはもったいないと思ったのも理由の1つです。

始めは自分が所属していた web の開発チーム内で社内 LT 会を開催しました。

徐々に巻き込む人数を増やして、今はサービス開発部全体を巻き込んでいます。

社内 LT を続ける15個のコツ

1. LT のテーマを絞らない

慣れてきたらテーマを絞っても良いかもしれませんが、導入時はどんなテーマでも良いことを強調します。

登壇のハードルを低くし、誰でも登壇できるメリットがあります。

2. 写真を撮る

振り返りやすく、LT についてまとめているドキュメントが文字だけにならず豪華になる!

サッカーの試合前に撮影するみたいな感じです。

f:id:tiwu:20200117151501p:plain

3. 始めはスモールスタート

一番初めは1人で登壇をし、次に同じチームのメンバーを巻き込みスタートしました。

当初は3回程度開催したら止めようと思っていましたが、登壇者の調整などが順調に進み、ここで止めるのはもったいないと思い続けました😎

少ない人数で何度か開催することで、GameWith に合った社内 LT 会の形を模索することができ、サービス開発部全体にスケールがしやすかったです。

4. 開催する日時は固定する

毎週金曜日の 19:15 から 19:45 と固定することで、予定を確保しやすくしました。

5. 日中ではなく夜に設定する

金曜日の夜なので仕事が一段落している人が多く、参加しやすいです!

6. 前座を設ける

19:15 スタートですが最初は参加者がまばらなので、場を暖める役割として前座の方が5分ほど喋るシステムにしました。

始まっている感が出て、人が集まりやすくなるメリットがあると思います。

7. 登壇者の勧誘は直接会話し依頼する

テキストより直接会話したほうが主旨の説明がしやすく、また熱意を伝えやすいです!

8. 登壇者が決まらなかったらスタッフが登壇する

「今日は登壇者がいないので中止にします」というのは絶対にしないように考えており、決まらなかったときはスタッフが登壇しています。

9. 飲み物を用意する

社内 LT 会はレッドブルとノンアルコールビールを用意しています!

飲み物があることで、それっぽい良い雰囲気になります!

週末ですしね。

10. タイムラプスの撮影

社内 LT 会の様子を iPhone で定点撮影しています。撮影は後で見やすいようにタイムラプスで撮影しています。

社内 LT 会を知らない方に雰囲気を伝えやすいです!

11. 活動報告をしっかりする

社内 LT 会の様子を毎回 Slack で周知し、次の登壇者の紹介をして次回の社内 LT 会のエンゲージメントを高めています。

12. 登壇者へのリマインド

登壇日が決まった後、その日まで放置するのではなく、リマインドを兼ねて次の登壇者の紹介をしています。

13. 社内 LT 会の目標を共有する

サービス開発部の8割の方に登壇経験を持ってもらうのを目標としており、毎月のサービス開発部の共有会で進捗報告などを行っています。

14. 登壇者の予定をできるだけ先まで埋める

自分たちは1ヶ月先くらいまでの登壇予定を埋めています。

15. どこまでも前向きに

いろいろコツを書いてきましたが、最終的には前向きな気持が大切だと思います!

終わりに

特に苦労することなく8ヶ月続けることが出来ました😉

いろいろなテーマで LT 登壇をしていただいたので、続けて良かったと思いました。

部内みんなのプレゼンスが上がったと感じます。

他の社内 LT 会などで取り組みのコツなど知りたいので、やってみて良かったことを教えてほしいです!

GameWithのDeveloper向けTwitterアカウントを開設しました。

もくもく会の告知やブログの更新情報などを発信するので良かったらフォロー宜しくお願いします!

twitter.com