prerenderについて
なぜprerender?
ブラウザーがSPAのindex.htmlをダウンロードし解析した後からCSSファイルとJavaScriptファイルダウンロードと解析完了まで時間差があります。
特にcode-splitやっていないSPAのJavaScriptファイルのダウンロードはもっと時間かかります。
もしユーザーさんは3Gを使うと、ダウンロード時間がもっと長くなり、数十秒の空白画面が表示されてしまう場合があります。
これにより離脱する可能性があります。
prerenderはwebpackでHTML、CSS、JavaScript、画像をコンバイるした後、Headless Browserを立ち上げて、実際のページを解析し、JavaScriptが実行した後の結果(CSSコードやJavaScriptに よって作成されたDOMなど)をHTMLファイルに追加する過程です。
prerenderの前のHTML
<!doctype html> <html> <head> <link href="/bundle.css" ref="stylesheet" /> </head> <body> <div id="main"></div> <script type="text/javascript" src="/bundle.js"></script> </body> </html>
prerenderの後のHTML
<!doctype html> <html> <head> <style> <!-- 具体的なCSSコード --> </style> <link href="/bundle.css" ref="stylesheet" /> </head> <body> <div id="main"> <div data-reactroot> <span> <!-- 具体的なJavaScriptにより作成されたDOM --> </span> </div> </div> <script type="text/javascript" src="/bundle.js"></script> </body> </html>
これでよりCSSとJavaScriptファイルをダウロードする間、ある程度整ってるページが表示され、ユーザーさんが寂しくないです。
使うライバリー
prerender-spa-plugin
https://github.com/chrisvfritz/prerender-spa-plugin
webpack.config.js
const path = require('path') const PrerenderSPAPlugin = require('prerender-spa-plugin') module.exports = { plugins: [ ... new PrerenderSPAPlugin({ // webpackのアウトプット staticDir: path.join(__dirname, 'dist'), // prerenderが必要なページ routes: [ '/', '/about', '/some/deep/nested/route' ], }) ] }
どんなページがprerender必須?
rootページ
特にprerender指定しない時、全部のpathに対するリクエストはrootページのHTMLファイルを返しています。
react-helmetによってOGP情報を変えたページ
だいたい全部SNSサイトのクローラーはJavaScript実行していません。
正しいOGP情報を出し分けるためprerenderが必要です。
いい感じにprerenderできるため
prerender-spa-plugin
は1つの素晴らしい特性があります。
prerenderする時、ページのwindow
オブジェクトに”prerenderですよ”を示す変数を入れることができます。
webpack.config.js
const path = require('path') const PrerenderSPAPlugin = require('prerender-spa-plugin') const Renderer = PrerenderSPAPlugin.PuppeteerRenderer; module.exports = { plugins: [ ... new PrerenderSPAPlugin({ ... // window.__PRERENDER_INJECTED && window.__PRERENDER_INJECTED.isPrerendering // によってprerender中かどうかを判断できる renderer: new Renderer({ injectProperty: "__PRERENDER_INJECTED", inject: { isPrerendering: true, }, }) }) ] }
これにより、prerenderの時ローディングUIなどをだすことが可能となります。
まとめ
SPAは膨大のCSSとJavaScriptファイルのダウンロードによって長い時間でブラウザーを空白にすることがあります。
prerenderによってコードを最初ダウンロードされるHTMLファイルを埋めることができます。
これで空白が解消できます。
JavaScriptでOGP情報を出し分ける時、prerenderが必須です。
prerender-spa-plugin
によっていい感じにprerenderができます。