フロントエンド定例 2022/4/22

tanifumiya|2022年04月25日
フロントエンド

ランサーズのフロントエンドエンジニアの谷(@high_g_engineer)です。
今回は、フロントエンド定例の内容をエンジニアブログに掲載していこうと思います。

前回の記事(ランサーズのフロントエンドチームが取り組んでいること)でお伝えしたのですが、
ランサーズのフロントエンドチームは、毎週金曜日にフロントエンド定例を開催しており、
実際の業務で取り組んでいることや気になった技術情報等をシェアしあう会になっています。

毎週、各メンバーが話した内容を記載していきたいと思います。

以下、今週の内容です。

@syo_igarashi

Storybook上でのテスト

Storybook上で開発を進めていく方針の流れにしていこうかなと思っている。

理由を述べると

  • ビジュアルリグレッションテスト導入のしやすさのため
    • Storybookをスクリーンショットした差分検知の仕組みがREG SUIT にある
    • 最初は厳密なPropsの検証とかなくてもいいのでとにかくビジュアルリグレッションテストのためにStoryを書く姿勢からスタートしていきたい
  • Component Story Format 3.0 によるUnit Test実行が可能なため
    • モック系ライブラリも Jest.mockMSW などを使用することによりライブラリやAPIサーバの依存もテストコード上でモックにすることで進められるため
    • testing-libraryを使用したイベント発火系のテストも可能
      • Storybook Test Runner と組み合わせれば、ブラウザとも連携してテスト実行も可能なのでE2E的にテストコード保証することも可能だからというのが大きい
  • それぞれのホスティング先の静的ファイル置き場に依存することなくStorybook上のホットリロードによる開発が可能だから
    • 例えば別のアプリケーションサーバがあるような開発環境でもWebフロントエンドのリソースをビルドして都度静的ファイル置き場に置いて検証する必要がなく、Storybook上で実装することが可能なので

といったメリットが見えてきたのでしばらくはStorybook駆動開発をする。

テスト観点についてちょっとバズってた記事についても少し話をした。

https://zenn.dev/koki_tech/articles/a96e58695540a7

とはいえビジュアルリグレッションテストあればいいとこもあり、フロントエンドのテストといってもイベント以前以後の変更、innerTextで雑にどう変更したか検知できるようなテスト書いておけばよいというのは若干思うこと。

@high_g_engineer

Partytownについて

メインスレッドをコード専用にして、サードパーティスクリプトをWorkerに割り当てることで、サイト高速化を支援することを目的としている。

そもそもWorkerとは

  • スクリプトをバックグラウンドスレッドで実行するためのシンプルな手段
  • Worker スレッドは、UIを妨げることなくタスクを実行できる
  • ただし、メインスレッドにあるDOMの操作等は出来ない(別途方法が必要)

Workerにより以下が望める

  • Webパフォーマンス向上
  • ブロッキング低減

Workerを利用したSandboxの可能性

  • Sandboxとは、隔離された領域でプログラムを実行し、問題発生時においてもほかのプログラムに影響を及ぼさないようにする仕組みのこと
  • 古典的には、iframe + postMessage

↓以下 postMessageの例

送信元.html

// iframeのwindowオブジェクトを取得
var ifrm = document.getElementById('ifrm').contentWindow;

// 外部サイトにメッセージを投げる
ifrm.postMessage("HELLO!", 'http://外部サイト.com');

// メッセージ受信イベント
window.addEventListener('message', function(event) {
  alert(event.data); // 'WORLD!' が表示される
}, false);

外部サイト.html

 // メッセージ受信イベント
 window.addEventListener('message', function(event) {
     // メッセージ送信元のサイトに返答する
     event.source.postMessage('WORLD!', event.origin);
 }, false);

JavaScript Sandboxの選択肢

  • Web Worker
    • ほとんどのブラウザで動作する
    • iframeほど古典ではないが、案外歴史はある
    • Sandboxとしてというよりいわゆる”Off the main thread”
  • ShadowRealm
    • JavaScriptの実行環境内に分離されたグローバル環境を用意するための標準仕様
    • tc39にて議論中で、2022年4月現在でstage 3(https://tc39.es/proposal-shadowrealm/
    • 本質的に安全ではないSandboxで、標準仕様に含めて大丈夫なのかという意見もある
  • Wasm
    • jsに限らずどんな言語でもコンパイルさればブラウザ上で動作できる
    • Wasm上でjsを動かすこともできる

問題点

  • 全てにおいてSandboxとメインスレッド間の通信は、postMessage頼み
  • DOMが取り扱いにくい(document.◯◯的なものがWorkerからは得られない。postMessageでメインスレッドから非同期的に取得)
  • 上記の点でコールバックやPromiseに変換する必要あり
  • 同期DOMを前提としている各種ライブラリは、非同期前提のSandobox環境下では、そのまま動かすことが出来ない

Partytownはちょっとしたハックでこれらをクリアしている

  • 同期的なXMLHttpRequest呼び出し&Service Worker
  • document.body.clientWidth的なものがWorker上で取得できる
  • 要は WebWorker + DOMで、サードパーティスクリプトを安全に隔離するもの

まだまだアルファバージョンのプロジェクト
似たようなものとしてworker-domがあるが、Partytown とworker-domの一番の違いは、worker-dom は DOM API をすべて mock 化して実装してその操作を転送する。その上で取得する操作は非同期APIとして実装される。

const style = await window.getComputedStyle(element)

Partytown は非同期操作を隠蔽する。

const style = window.getComputedStyle(element)

参考

今Partytownがヤバい。JavaScript Sandboxの未来はどっちだ?
https://zenn.dev/stomita/articles/2c16a53223f3c9

Partytown の Worker からの同期的メインスレッド操作を実装してみる
https://zenn.dev/mizchi/articles/my-partytown

遅延読み込みライブラリ「Partytown 0.0.5」がリリース
https://codezine.jp/article/detail/14943

【JavaScript】PostMessageを使ったクロスドメインでのデータ通信
https://launchcart.jp/blog/%E3%80%90javascript%E3%80%91postmessageを使ったクロスドメインでのデータ通/

JavaScript postMessageでクロスドメインメッセージ通信
https://qiita.com/yasumodev/items/d339a875b4b9bf65d156

重い処理にはWebWorkerを使う
https://developers.10antz.co.jp/archives/1147

off-the-main-thread の時代
https://mizchi.hatenablog.com/entry/2018/10/02/093750

 

次回の更新予定は、5/13(金)になります!
13日の金曜日・・・次回もお楽しみに!