2.1K Views
July 13, 23
スライド概要
ユーザーが何を考えながらどう操作したのか?操作ログをそのまま読んで理解しようとするエンジニアは多いですが、ログを読み取って頭の中でイメージするのは大変じゃないでしょうか?
コーディングテストサービス HireRoo では、テスト受験者の思考プロセスを理解できるように、コーディングしている様子をリプレイ再生できる「プレイバック機能」を開発、機能提供をしています。こちらの機能ではフロントエンド技術を活用し、軽量な操作ログからリプレイ再生が可能になるため、重い動画データのやり取りも不要になっています。
本登壇では、操作ログからリプレイ動画を作成し、履歴を確認するためにどのような開発を行なったか裏側も含めてご紹介します。
「操作ログからリプレイ 動画の作成」を支える フロントエンド技術 @Himenon 1
イントロダクション 自己紹介 姫野 滉盛 @Himenon SNS ● ● ● GitHub: Himenon Twitter: himenoglyph BlueSky: Himenon エンジニアリング領域 ● Webフロントエンド(メイン) ● 開発支援ツールを作るのが趣味 前職 ● 株式会社ドワンゴ 代表的なOSS ● Himenon/openapi-typescript-code-generator © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 2
Agenda 1 リプレイ動画について 操作ログからの復元 2 どのように実装されているか? リプレイの原理 3 実装を支える周辺技術 リプレイ技術を支える周辺技術 4 まとめ
01 リプレイ動画について
リプレイ動画について どんな機能か? サービス内での呼び方: プレイバック機能 © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 5
どのように実装されているか? プレイバック機能のUI 実際のエディタ上で再現 するため、クリック可能 時間軸:イベントの発生 ヒント機能を利用した履歴が 時刻単位で進行する 表示される © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 6
02 どのように実装されているか?
どのように実装されているか? ざっくりしたアーキテクチャ 記録 再生 DB DB Web Socket 操作ログ Browser © HireRoo, Inc. Web Socket 操作ログ Browser 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 8
どのように実装されているか? Text OperationとOperational Transformation 記録時 Text Operation ● ● OT上で送信されるペイロード ドキュメント上で行われる具体的な操作 ○ テキストの挿入・削除・置換など 再生時 DB DB TextOperation TextOperation Browser Browser Operational Transformation(OT) ● ● 複数のユーザーがリアルタイムで同時にテキスト編集 を整合性のある方法で同期・管理するためのアルゴリ ズム。 参考)OSSの原理を理解しスクラッチで開発できるエ ンジニア文化とは 記録時のアルゴリズムに OTが利用されている © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 9
どのように実装されているか?
Text Operation:カーソルの移動と文字列の挿入
type: “move”
[{"type":"move","cursor":10},{"type":"insert","value":"e"],
●
カーソルの移動
[{"type":"move","cursor":11},{"type":"insert","value":"x"],
[{"type":"move","cursor":12},{"type":"insert","value":"p"],
type: “insert”
[{"type":"move","cursor":13},{"type":"insert","value":"o"],
[{"type":"move","cursor":14},{"type":"insert","value":"r"],
●
文字列の挿入
[{"type":"move","cursor":15},{"type":"insert","value":"t"],
[{"type":"move","cursor":16},{"type":"insert","value":" "],
[{"type":"move","cursor":17},{"type":"insert","value":"c"],
[{"type":"move","cursor":18},{"type":"insert","value":"on"],
[{"type":"move","cursor":20},{"type":"insert","value":"s"],
[{"type":"move","cursor":21},{"type":"insert","value":"t"],
[{"type":"move","cursor":22},{"type":"insert","value":" "],
[{"type":"move","cursor":23},{"type":"insert","value":"m"],
export const main = () =>
[{"type":"move","cursor":24},{"type":"insert","value":"a"],
[{"type":"move","cursor":25},{"type":"insert","value":"i"],
[{"type":"move","cursor":26},{"type":"insert","value":"n"],
[{"type":"move","cursor":27},{"type":"insert","value":" "],
[{"type":"move","cursor":28},{"type":"insert","value":"="],
[{"type":"move","cursor":29},{"type":"insert","value":" "],
[{"type":"move","cursor":30},{"type":"insert","value":"()"],
© HireRoo, Inc.
「操作ログからリプレイ動画の作成」を支えるフロントエンド技術
10
どのように実装されているか?
Text Operation:文字列の削除
type: “delete”
●
文字列の削除
col 17
[{"type":"move","cursor":26},{"type":"delete","from":{"line":2,"col":17}],
export const main = () =>
export const sample = () =>
© HireRoo, Inc.
[{"type":"move","cursor":25},{"type":"delete","from":{"line":2,"col":16}],
[{"type":"move","cursor":24},{"type":"delete","from":{"line":2,"col":15}],
[{"type":"move","cursor":23},{"type":"delete","from":{"line":2,"col":14}],
「操作ログからリプレイ動画の作成」を支えるフロントエンド技術
11
どのように実装されているか? 実際のTextOperation ● ● 実際に保存されているTextOperationは最小限のデータで構成されている。 UIで利用する直前に機能するデータ型に変換している DataBase Convert UI [ {"type":"move","cursor":10}, {"type":"insert", "value":"e", [10, "e"] "from":{"line":2,"col":1}, "to":{"line":2,"col":1} 実際のTextOperation } ] UIに渡す直前のTextOperation 連続するTextOperationから計算される © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 12
実装を支える周辺技術 まとめ:どのように実装されているか? プレイバック機能の実装 記録時 ● TextOperationというイベントを送信している [10, "e"] 再生時 ● TextOperationから記録を復元している → フルスクラッチで実装されている! © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 13
03 実装を支える周辺技術
実装を支える周辺技術 実装を支える周辺技術とは? プレイバック機能をフルスクラッチで実装されている ↓ 実現可能な機能がたくさん出てくる © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 15
実装を支える周辺技術 例えば.... コピー&ペーストした領域を表示したい ユーザーがどの位置にカーソルを置いてい るのか表示したい 他のユーザーと比較したい ホバーしたときにサムネイルを表示したい ユーザーが書いている場所をわかりやすく するためにスライダーを分割したい © HireRoo, Inc. ユーザーが再度アクティブなった時間を表 示したい 複数人で操作している場合にスライダーを 複数表示したい 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 16
実装を支える周辺技術 実装を支える周辺技術とは? プレイバック機能をフルスクラッチで実装されている ↓ 実現可能な機能がたくさん出てくる ↓ 実装が複雑化・肥大化する恐れがある。 ↓ 複雑なコードのオーナーシップをどのように実現するかという課題に直面する この課題をどのように支えているのか、技術的な観点から紹介する © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 17
実装を支える周辺技術 課題:実装の肥大化とオーナーが複雑化 このファイルのオーナーは誰? 機能7 コピー&ペーストした領域を表示したい 機能1 他のユーザーと比較したい 機能2 ユーザーが書いている場所をわかりやす くするためにスライダーを分割したい Playback.tsx 機能3 複数人で操作している場合にスライダー を複数表示したい 機能5 ユーザーが再度アクティブなった 時間を表示したい 機能4 ホバーしたときにサムネイルを表 示したい © HireRoo, Inc. 機能6 ユーザーがどの位置にカーソルを 置いているのか表示したい → どのように解決するか? 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 18
実装を支える周辺技術 解決方針:責務の分離 コピー&ペーストした領域を表示する機能の中身 Backend For Frontend データの集約の責務担当 Container ビジネスロジックの責務担当 Presentation UIの責務担当 プレイバック機能 エディター機能 コピー&ペーストした領域を表示す るのに必要な情報 © HireRoo, Inc. Container.tsx テキストをハイライトする 機能 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 19
実装を支える周辺技術 分割された責務の役割 フロントエンドのアプリケーションで導入した対策 Backend For Frontendの導入 ● あらゆるシステムと柔軟に連携するためにフロントエンドのためのデータ集約基盤を整備 Presentation層 + Container層の導入 ● ● Presentation層 ○ UIに対する責務のみ Container層 ○ ビジネスロジックの責務 ○ API(HTTP, WebSocket) ○ BFFとデータのやり取りをする ○ Presentation層に対してデータを渡す © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 20
実装を支える周辺技術 Before: 関心の分離前 右図のComponent状態 1. 2. 変更したい対象が常にComponent この影響をビジネスロジック・Presentation両方に行く ビジネスロジックとPresentationがComponentの 中で共存する 他方の変更が他方にも影響する状態 Component (実体) レビュー範囲 ● 影響を受ける場所が想定できない 関心の方向 変更の方向 関心の方向 新機能追加時 ● Componentに関心を持つ別の責務が デグレしていないか確認する必要がある © HireRoo, Inc. ビジネスロジック Presentation 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 21
実装を支える周辺技術 After: 関心の分離後 レビュー範囲 ● ● 変更の方向が明らかなのでレビュー負荷が下がる 不用意な変更も見抜くことが容易い Propsの変更 = 新しいデータがPresentationで 必要なケースのみ発生する Props インターフェース 新機能追加時 ● ● デグレリスクが下がる 実装場所が人によってほとんどブレない 関心の方向 関心の方向 変更の方向 Container Presentation CALL ビジネスロジックの変更 はContainer層で閉じる © HireRoo, Inc. 見た目のだけの変更は Presentation層に閉じる 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 22
04 まとめ
実装を支える周辺技術 新機能開発と開発の安定性のまとめ プレイバック機能 ● ● Text OperationをペイロードとしてOperational Transformationのアルゴリズムを用いて送受信を行う これをフルスクラッチで開発 フルスクラッチで構築された機能であるため、拡張性が非常に高くアプリケーションの機能を追加することが できる反面、アプリケーションの複雑度が増す 実装を支える周辺技術 ● 拡張性と保守性を手に入れるために関心の分離 総まとめ ● ● フルスクラッチの実装は新機能の追加を促進 関心の分離によって実装の拡張性と安定性が得られる © HireRoo, Inc. 「操作ログからリプレイ動画の作成」を支えるフロントエンド技術 24