サービスの動作が遅かった
最近,アーチャー伝説ってスマホアプリ専用の【マルチ募集掲示板サービス】をリリースしました.
技術としては,Node.js/React/TypeScript/Express/Webpackを使用しました.このサービス,募集スレッドのリアルタイム更新をアピールしてるんですが,その肝心のbundle.jsが動き出すのが遅いんですよね.
そこでSSR(Server Side Rendering)について調べてたらこんなサイトが出てきて,めっちゃわかりやすいやんけ!と.要するにNode.jsってすごいし早いけど,やっぱSSRしない方が動作は早いよねと.でもSEOの観点とUX考慮するとまあSSRした方がいいよねと.
そこで重要になるのがjsの読み込み速度.今回Webpackを使ってるのでここをなんとかせねば!Webpackってjs全部ひとまとめにしてくれてめちゃくちゃ便利な反面,そのbundleされたjsファイルに対して何もしなかったらかなり重いんです.
bundle.jsを小さくするために!
今回ReactのMaterial-UI使ってたり,Express.js使ってたりと,小さく出来そうなとこはいろいろありそうでした.サイズ小さくするために,ちょっとめんどくさい書き方になったりしますが,これはユーザビリティ考えると致し方ありませんね.ちなみに下の画像がなーんにも手を加えずbundleしてた時のサイズ.1.29Mbもあります.(BundleAnalyzerPluginって神様)ちなみにこれjs読み終わるのに10秒くらいかかってました....
で,この中でも,Material-UIが997Kb...これだけでbundle.js全体の8割弱占めてる...Material-UI使う時は必ず注意すべきですね
ささ,bundleサイズ小さくしていきましょうか.
Express.js
importcompressionfrom'compression';app.use(compression());
これだけでbundle.jsをgzipで圧縮してくれるんです.便利すぎて笑
Material-UI
//GoodimportAppBarfrom'@material-ui/core/AppBar';//Badimport{AppBar}from'@material-ui/core';
上のように書き換えます.それだけです.僕の場合は多い時は1コンポーネントに10個ほどモジュールをimportしてたので,かなりめんどくさい...下の書き方だったら一行でほとんどimportできますから.
で,なぜ下はダメなのか.これ直接node_modulesディレクトリから探せば一目瞭然ですが,下の場合だと@material-ui/core全部インストールしてきてそっからAppBarを探すんですよね.そりゃ容量食いますね.
CSS
constsheets=newServerStyleSheets();renderToString(sheets.collect(React.createElement(component)));constcss=(sheets.toString()).replace(/\s+/g,"");
僕の場合はMaterial-UIで使われるcssもSSRでテンプレートエンジン(pug)に渡す必要があったので,cssを文字列で渡すんですよね.で,cssとかjsの読み込みに空白とか改行,コメントが入ってたらそれまた遅くなります.なのでここではスペースを全て削除することでcssを圧縮しました.
bundleサイズのビフォーアフター
bundleサイズ438Kb!
Material-UIも258Kbに!
結果,800Kb以上圧縮できましたね!6.5割程削減できたのかな?
【マルチ募集掲示板サービス】の読み込みもだいぶ早くなりました!ストレスは感じないですね!Lighthouseで測定したら,Performanceが60点台から96点になりました!!
アクセシビリティも改善したいのですが,サードパーティコードの影響を削減ってよくわからなくてわからないです....このサイトによるとNode.jsってサーバのメインループをブロックするらしくて,そのことかなと思うのですが...誰か教えていただけると幸いです!
まとめ
Webpackとかでbundleしたり,いろんなモジュール使うならサイズ小さくしようってことです!