581 Views
March 02, 21
スライド概要
2021/03/02 Ltech#14 「LIFULL HOME'S」のフロントエンドについて語り尽くします!
相馬 稜
LIFULL HOME'Sを運営する株式会社LIFULLのアカウントです。 LIFULLが主催するエンジニア向けイベント「Ltech」等で公開されたスライド等をこちらで共有しております。
LIFULL ppt template (2017.6) LIFULL HOME'S における フロントエンド開発環境の刷新 [email protected]
自己紹介 やったこと LIFULL ppt template (2017.6) 新卒 5 年目 所属:テクノロジー本部基盤開発ユニットアーキテクトグループ Soma Ryo 趣味:Browser を知ること 直近の活動記録: @lidqqq 9 年を超えて開発が続く LIFULL HOME'S の Web フロントエンド開発環境の改善 ←今日はコレらの話をします Node.js で Twig のプリプロセッサーを作って言語の機能拡張をしてみた話
はじめに やったこと LIFULL ppt template (2017.6) IE つらいんで transpiler いれていいすか? < IE つらいんで polyfill いれていいすか? < <script> の同期読み込み遅いしコスト高いんで defer にしていいすか? < LH(*1) 1 年間くらい開発してるけど色々とつれぇな〜 そや!コレ作ったミカン先輩に色々聞いてみよ! てか LH のフロントってイケてなくないすか? < いい感じにしていいすか? < いいよ 時は 2019 年、SEO 事業部に所属中 *1: LH = LIFULL HOME’S 何者かの力により現在の部署に異動(正規) Project として LH のフロントエンド改善に取り組めることに
刷新前は具体的に何がイケていなかったのか LIFULL ppt template (2017.6) 基本構成:PHP(Symfony + Twig) + CSS/JS ❖ Performance ➢ CSS/JS の minify/bundle は 初回の HTTP リクエスト時に PHP 側からランタイムで生成される ■ 初回リクエストのレスポンス速度大幅遅延 ❖ 開発効率 ➢ JS/CSS: 開発時のコードとクライアントサイドで実行されるコードが(ほぼ)同じ ■ API の Browser 互換性を開発者が逐一チェック, Vendor Prefix や Cache Buster 用の query parameter の手動付与 ➢ CSS/JS の依存関係の解決(ファイルの読み込み)は Twig 上で行なっており、JS などを単体で見た場合に依存関係が不 明 ■ ランタイムまで依存ファイルの読み込み忘れがあるかが分からない ● JS:ファイル間の依存解決は window オブジェクトを介していた ■ ファイル全体を module id(ファイル内で定義) で grep するしかない
刷新後の技術スタック LIFULL ppt template (2017.6) ● JS ○ Rollup/terser ○ Babel/TypeScript ● CSS ○ Sass(.scss) ○ autoprefixer ● その他もろもろの開発便利 npm packages
Before/After: JavaScript Bundle/Minify LIFULL ppt template (2017.6) After Before Twig には 依存する Bundle の id のみ記述 Twig に読み込みファイルをハードコーディング Syntax Syntax + ES Module import/export Timing Bundler/Minifier PHP(runtime) PHP(文字列結合) + UglifyJS(ES6 未対応) Timing Node.js(build) Bundler/Minifier Rollup + terser
Before/After: JavaScript Syntax LIFULL ppt template (2017.6) After Before IE11 に準拠(手動) ESNEXT(Babel/TypeScript) Class declaration 地獄の三項演算子 global scope を汚染しない 為のトップレベルの IIFE Optional chaining Arrow function / Destructuring assignment $.proxy(this.onXXX, this), def().as(), etc...
刷新後でもまだイケていないところ LIFULL ppt template (2017.6) ❖ Bundle ファイルが多すぎるため warmup に時間がかかりすぎる ➢ アプリケーションが巨大な為、現在 Entry Point となる JS が 349 個ある ■ Rollup によって 349 個の Bundle ファイルが生成される ➢ 開発時、watch ready になるまでに5 分以上を要している ■ 改善案:ESBuild を使ったランタイムによる高速ビルドを現在進行形で試みている(PR review 中) ● 適応後は watch ready まで 10 秒 + ランタイム(PHP から)で逐一ビルド(Rollup の 100 倍高速なので実用範囲内) ● 注意:esbuild はその名の通り ESM 向けのモジュールバンドラーであるため、context 関連で patch をかます必要がある ◆ global context の this が暗黙的に exports オブジェクトへと書き換えられてしまう ➢ ESBuild の plugin で解決 -> トップレベル IIFE をさらに上書き `(function () { [[program]] }).bind(window)();` ◆ UMD 形式で記述されている library 系統のコードが exports オフジェクトを解釈してしまう -> global object を拡張できない ➢ ● patch を当てたファイルを読み込むうようにしている リリースしたら Blog 書くので詳しくはそちらでお願いします
まとめ LIFULL ppt template (2017.6) 「フロントエンド開発環境の刷新」により ● ランタイム Bundle の撤退 ● Node.js で Bundle(Rollup)/Minify(terser) ● JS/TS の Syntax は基本的に ESNEXT ● CSS は Sass(.scss) へ ● 依存関係は JS/CSS それぞれの世界で完結 ● Twig はプリプロセッサーをかまして言語機能拡張 ● ※ Rollup の warm up に課題あり な感じに変わりました
LIFULL ppt template (2017.6) fin.
コレはこうした集 LIFULL ppt template (2017.6) ● 349 回も Twig ファイルから JS ファイルへの移行したの? ○ Twig の Parser を作って、それを使って AST から Twig/JS を自動生成する script 組みました ■ Node.js で Twig のプリプロセッサーを作って言語の機能拡張をしてみた話 ● 移行した時のテストどうしたの? ○ 移行前のファイルと、移行後のファイルを AST レベルで検証し文法上等位であることを確認する自動テストを行いました ○ 弊社の SETG が作成/メンテしている自動テストツールを使ってページランクの高いページは回帰テストで動作確認を行いました ■ 自動システムテストツール「Bucky」OSS化までの道のり ● なんで Rollup 選んだの? ○ Plugin による拡張性の高さ ○ module/nomodule を将来的にはやりたく、当時は対応状況的に Rollup しかなかったから ○ 今だったら ESBuild とか snowpack とかあるのでまた違った答えになるかもしれない ● Project メンバーは? ○ 基本私が設計/実装/テストで、 に review してもらってました