LoginSignup
23
15

More than 3 years have passed since last update.

Nuxtのページ表示速度が遅かったので、色々改善方法のメモ

Posted at

はじめに

Nuxt, TypeScriptで速度とかを深く考えず実装を進めていったら、
ページ表示速度が著しく遅かったので色々と勉強したメモ。

前提

Nuxt 2.11.0
TypeScript導入済み
Nuxt generateして運用

速度改善

どこが遅いのか、とかを色々しらべると
- 画像が多い画面なので画像の読み込みに時間がかかる。
- node moduleが重い
- componentsのimportが無駄なものがあったり、importの仕方がまずい
とかが原因と思われました。
ちなみに改善する前のGoogle のpagespeed insights で測ったら真っ赤っかでした。

画像の読み込み改善

画像の遅延読み込みの実装

vue-lazyloadを使います。

yarn add vue-lazyload

nuxtで使えるようにしていきます。

~/plugins/vue-lazyload.ts
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload, {
  preLoad: 1.1,
  attempt: 1,
  observer: true,

  observerOptions: {
    rootMargin: '0px',
    threshold: 0.1
  }
})

オプションは、vue-lazyloadのドキュメントを読んでください。たぶん、このまま使って大丈夫です。
pluginをnuxt.config.tsで読み込みます。

nuxt.config.ts
  plugins: [
    { src: '~plugins/vue-lazyload', ssr: false }
  ]

vue用に作られたmodulesをnuxtで使う場合pluginを書いて、configで読み込んだらだいたい使える気がします。
これでlazyloadの準備ができました。

実際componentsなどで使う場合

hoge.vue
<template lang="pug">
div
  img(v-lazy='hoge.jpg', alt='')
</template>

とう感じに、src の代わりに v-lazy を使ってください。
これでlazyloadが実装できました。
これだけで画像関連は十分ですが、せっかくなのでwebpも使える様にします。

Webpと通常の画像の出し分け

lazyloadの実装に使ったvue-lazyloadを使ったらいい感じにwebpの出し分けも実装できました。
pluginを書き直しましょう。

~/plugins/vue-lazyload.ts
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload, {
  preLoad: 1.1,
  attempt: 1,
  observer: true,

  observerOptions: {
    rootMargin: '0px',
    threshold: 0.1
  },
  filter: {
    webp(listener: any, options: any) {
      if (!options.supportWebp) return
      listener.src = 'hoge.webp'
    }
  }
})

filterを追加します。
ここで、ブラウザがwebpに対応していればwebpのパスを返す処理を追加しています。
もしくはパスの最後にパラメータを追加すると、変換して返してくれるような機能があればこんな感じで。
これはcontentfulです。

~/plugins/vue-lazyload.ts

  filter: {
    webp(listener: any, options: any) {
      if (!options.supportWebp) return
      listener.src += '?fm=webp'
    }
  }

以上で、画像はlazyloadとwebpが実装できました。

ここまでやったら、多分だいたいOKなんじゃないかと思いますが、次へ。

componentsのdynamic import

Nuxt,vueでcomponentをimportする場合


import fuga from '~/components/fuga.vue'

だいたい、こうしますが。

const fuga = () => import('~/components/fuga.vue')

こうすると、dynamic importになってbundleサイズが軽くなって速度が改善されます。
これをしてエラーが出ないcomponentならこうやったほうがいいですが、
たまにエラーが出るので、その場合は臨機応変に、従来通りのimportするかエラーを直すか。

webpackのbundleの設定

nuxt でwebpackのbundleを分割するように設定します。

nuxt.config.ts
const nuxtConfig = {
  splitChunks: {
    layouts: true,
    pages: true,
    commons: {
      test: /[\\/]node_modules[\\/]/,
      name: 'vendor',
      chunks: 'initial'
    }
  }

spliChunksの部分の設定をしてやると、よかったです。
おわり。

おわり 

おわり

参考

https://webpack.js.org/guides/lazy-loading/
https://crieit.net/posts/Nuxt-Vue-dynamic-import-sed

23
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
15