見出し画像

大規模なWebの開発をする際に気をつけること

今回は、大規模なWebを開発するのに気をつけたいことをLTイベントでお話したのでそこらへんの知見をnoteでも共有したいと思ったので記事にします。(最近noteがスライド貼れるようになったので使いたかった)

現在、女性向け動画メディアのフロントエンドを担当しているのですが、その時にどんな構成でWebを作っていくか色々考えた結果大規模なWebの開発で気をつけたいことがちょくちょくあったので、2つ共有したいと思います。
技術としては流行りのReact(v16)を採用しました。


Reactのレンダリング方法

Reactを使ってWebを開発する際に、よくreact-routerを使ってSPAとしてWebを動かしていくのがあると思います。サーバーからは

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <div id="app"></div>
        <script src="bundle.js"></script>
    </body>
</html>

のようなHTMLが200 OKで返ってきてbundle.jsが読み込まれ、Reactが画面のレンダリングを行います。
その後、react-routerなどでSPAとしてページの遷移をしていきます。

この時のメリット・デメリットを考えてみます。よく言われてるものとして

メリット
- 高速なページ遷移が実現可能
- 通常のWebではできないようなUXを生める

デメリット
- SEOの面で不利になる(Googleのクローラーはみてくれるって見かけた覚えもありますが一応)
- 初回のロードが遅い(JavaScriptを読み込んでから実行して初めてページがレンダリングされるため)

などがあります。ここでサーバーサイドレンダリングで実装した場合のメリット・デメリットも確認しておきます。

メリット
- 初回のロードが早い

デメリット
- ページ遷移のたびにロードしないといけない
- SPAで出来たようなUXを実現するのは難しい

ここである偉い人は気づきました。

あれ。これ両方のいいとこ取ればよくね。

この両方のいいところをとったような構成がIsomorphicです。(話は簡略化してます)

Isomorphicは、サーバーでReactのコンポーネントをimportしてきて、react-domのrenderToStringと言うメソッドを使いサーバーから文字列としてHTMLを返します。これによりサーバーサイドレンダリングを実現します。ブラウザがこのHTMLを取得してからはSPAとして機能するので、先ほどの2つのメリットを得ることができました!


肥大化するbundle.js

isomorphicを実現できたのでめでたしめでたしではなく、今回はもう一つ、bundle.jsの肥大化についても少し共有したいと思います。

肥大化するbundle.jsを解決するにはwebpackのcode splittingというページをみてみると良いです。
今回はdynamic importsについての話なのでこちらをみると分かります。

dynamic importsは現在、stage-3の機能なんですがReactを使っているプロジェクトは多分トランスパイラーもはいっていると思うので、そこで対処してもらえるといいと思います。

実際にどこまでファイルサイズを抑えれるのかを試してみます。

import moment from "moment"

const getDate = () => {
  return moment().format("YYYY/MM/DD")
}

export default getDate

こんな感じの重めなファイルを用意します。

これを普通にimportするのと、dynamic importした時にベースのbundle.jsはどこまで差がでるでしょうか。

普通にimportします。

import heavy from "./heavy"

const main = () => {
  console.log("Today is...")
  console.log(heavy())
}

main()

このファイルをbundle化した場合のファイルサイズは619KBになりました。

dynamic importしたコードです。

const getDate = () => import(/* webpackChunkName: "heavy" */"./heavy")

const main = async () => {
  console.log("Today is...")
  const m = await getDate()
  console.log(m.default())
}
main()

これをbundle化すると7.9KBになりました!

78.4分の1になりました!

dynamic importのコードはkonojunya/dynamic-import-sampleにあげているのでみていただければと思います。

いいなと思ったら応援しよう!