こんにちは、”はふぃ”です。

Vueアプリケーションを作っているとmiddlewarepluginsfetchafterEachなどいろんなタイミングで実行される処理が出てきて混乱しませんか?

さらにサーバーサイドレンダリング(SSR)も導入していると、SSRの時とCSR(クライアントサイドレンダリング)の時を考慮しなければいけないのでさらに混乱しますよね…。

同じ Vue コンポーネントをサーバ上の HTML 文字列に描画し、ブラウザに直接送信し、最終的に静的なマークアップとしてクライアント上の完全なインタラクティブアプリケーションに “ハイドレート (hydrate)” することもできます。

サーバサイドレンダリング (SSR) とは何か?

そこで、今回はいろいろなタイミングで実行される処理がSSRとCSRも考慮してどのタイミングで実行されるのかを検証してみたいと思います!

検証する処理一覧

今回検証する処理はNuxt.jsの処理とVue.jsの処理で以下の通りです。

これらをSSRCSRの場合で検証します。

※ 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を経由してアクセスしたところ、以下のような結果となりました。

直アクセス

↑ サーバーのコンソール
↑ ブラウザのコンソール

nuxt-linkを使ってアクセス

※ サーバーのコンソールには出力なし

↑ ブラウザのコンソール

まとめ

SSRありとなしそれぞれで以下のような処理の順番だということがわかりました。

SSRあり

  1. plugins (SSR)
  2. middleware (SSR)
  3. fetch (SSR)
  4. beforeCreate (SSR)
  5. plugins (CSR)
  6. beforeEach (CSR)
  7. afterEach (CSR)
  8. beforeCreate (CSR)

SSRなし

  1. beforeEach (CSR)
  2. middleware (CSR)
  3. fetch (CSR)
  4. afterEach (CSR)
  5. beforeCreate (CSR)

投稿者: はふぃ

若手のWEBフロントエンジニア。最近はバレーボールにハマってます!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA