こんにちは、”はふぃ”です。
Vueアプリケーションを作っているとmiddlewareやplugins、fetchやafterEachなどいろんなタイミングで実行される処理が出てきて混乱しませんか?
さらにサーバーサイドレンダリング(SSR)も導入していると、SSRの時とCSR(クライアントサイドレンダリング)の時を考慮しなければいけないのでさらに混乱しますよね…。
同じ Vue コンポーネントをサーバ上の HTML 文字列に描画し、ブラウザに直接送信し、最終的に静的なマークアップとしてクライアント上の完全なインタラクティブアプリケーションに “ハイドレート (hydrate)” することもできます。
サーバサイドレンダリング (SSR) とは何か?
そこで、今回はいろいろなタイミングで実行される処理がSSRとCSRも考慮してどのタイミングで実行されるのかを検証してみたいと思います!
検証する処理一覧
今回検証する処理はNuxt.jsの処理とVue.jsの処理で以下の通りです。
これらをSSRとCSRの場合で検証します。
- Nuxt.js
- Vue Router
- beforeEach
- afterEach
- Vue.js
※ Vue.jsの処理でcreatedやbeforeMountなどもありますが、beforeCreateがVueのライフサイクルの中で一番早く実行されるので代表とします。
検証用のコード
上記の処理の順番を検証するためにそれぞれの処理を使ってconsole.log()を出力する処理を実装します。
この時、process.server
を使ってSSRかCSRかの判定、Date.now()
で正確な処理の順番を判断します。
middleware
< middleware/middlewareTest.js >
export default function (context) { if (process.server) { console.log(`---------middleware(SSR)_${Date.now()}----------`) } else { console.log(`---------middleware(CSR)_${Date.now()}----------`) } }
< nuxt.config.js >
module.exports = { … router: { middleware: ['middlewareTest'] }, … }
plugins
< plugins/pluginsTest.js >
export default function (context) { if (process.server) { console.log(`---------plugins(SSR)_${Date.now()}----------`) } else { console.log(`---------plugins(CSR)_${Date.now()}----------`) } }
< nuxt.config.js >
module.exports = { … plugins: [ … '~/plugins/pluginsTest' ], … }
beforeEach, afterEach
< plugins/router.js >
function befreEach (context, to, from, next) { if (process.server) { console.log(`---------beforeEach(SSR)_${Date.now()}----------`) } else { console.log(`---------beforeEach(CSR)_${Date.now()}----------`) } next() } function afterEach (context, to, from) { if (process.server) { console.log(`---------afterEach(SSR)_${Date.now()}----------`) } else { console.log(`---------afterEach(CSR)_${Date.now()}----------`) } context.store.commit('sample/afterEachDefault/setDefaultVal', 'Hello World!!') } export default (context) => { context.app.router.beforeEach(befreEach.bind(null, context)) context.app.router.afterEach(afterEach.bind(null, context)) }
< nuxt.config.js >
module.exports = { … plugins: [ … { src: '~/plugins/router', ssr: false } ], … }
fetch, beforeCreate
< pages/index.vue >
<template> <h1>TEST</h1> </template> <script> export default { fetch () { if (process.server) { console.log(`---------fetch(SSR)_${Date.now()}----------`) } else { console.log(`---------fetch(CSR)_${Date.now()}----------`) } }, beforeCreate () { if (process.server) { console.log(`---------beforeCreate(SSR)_${Date.now()}----------`) } else { console.log(`---------beforeCreate(CSR)_${Date.now()}----------`) } } } </script> <style></style>
その他
CSRの検証用にトップページへの遷移用のランディングページも作成しておきます。
< pages/link.vue >
<template> <nuxt-link to="/">トップへ</nuxt-link> </template> <script> export default {} </script> <style></style>
検証結果
直アクセスとlinkページのnuxt-link
を経由してアクセスしたところ、以下のような結果となりました。
直アクセス
.png)
.png)
nuxt-linkを使ってアクセス
※ サーバーのコンソールには出力なし
.png)
まとめ
SSRありとなしそれぞれで以下のような処理の順番だということがわかりました。
SSRあり
- plugins (SSR)
- middleware (SSR)
- fetch (SSR)
- beforeCreate (SSR)
- plugins (CSR)
- beforeEach (CSR)
- afterEach (CSR)
- beforeCreate (CSR)
SSRなし
- beforeEach (CSR)
- middleware (CSR)
- fetch (CSR)
- afterEach (CSR)
- beforeCreate (CSR)