Swiperを最適化してページ表示速度を改善してみた

Swiperを最適化してページ表示速度を改善してみた

「Swiperを使っているけれど、もっと表示速度を速くしたい!」と感じたことはありませんか?

今回は、Swiperの読み込みを効率化し、できるだけ軽量化することでページ表示速度を向上させた方法をご紹介します。

試行錯誤を重ねた結果、自分なりに満足できる形に仕上がったので、行った最適化のポイントをまとめてみました。

なお、基本的な使い方については割愛し、最適化にフォーカスして解説していきます。

目次

アセットをダウンロード

SwiperはCDNではなく、アセットをダウンロードしてローカルファイルから読み込ませます

高速化だけに目を向ければCDNの方が有利だったりもするのですが、CDNのサーバーに不具合があると読み込めないといったリスクがあります。

過去に複数回、原因不明の表示崩れが起きたのですが、CDN側のサーバーエラー(稼働停止)によるものでした。

一時的に読み込めなくても大きな問題にならない場合はCDN、ファーストビューや重要なコンテンツに利用している場合はローカルから読み込むのがベストだと思います。

アセットは、https://www.jsdelivr.com/package/npm/swiper?tab=files&version=8.4.7から、以下2つのファイルをダウンロードします。

  • swiper-bundle.min.js
  • swiper.min.css

CSSファイルは、swiper-bundle.min.cssという最初から装飾が含まれているバージョンもありますが、その分容量が多くなっているので、軽量にこだわるならswiper.min.cssがおすすめです。

Swiperのバージョンは、バグの少ない8系を好んで使用していますが、必要に応じて変更してください。

初期化専用JSファイルを作成

Swiperの初期化やオプション設定は、共通のJSファイルではなく、専用のJSファイルを作成して記述します。

これをSwiperを使用しているページだけに読み込ませることで、Swiperを使わないページでは余計なコードが読み込まれず、サイト全体が軽くなります。

専用ファイルは、例えばswiper-setup.jsのように、何をしているファイルなのかがすぐにわかる名前をつけておくと便利です。

以下は簡単な記述例。

const swiper = new Swiper('.swiper', {
  // Optional parameters
  loop: true,
  speed: 1500,
  autoplay: {
    delay: 5000,
    disableOnInteraction: false,
  },

  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },

  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
});

ここで指定するのはあくまでアニメーション設定です。

slidesPerViewspaceBetweenなどのレイアウト設定は、ここでは指定しません。

理由は、JavaScriptが無効になっている場合や、通信環境が悪いなどの場合は、スタイルが適用されず、レイアウトシフトや表示崩れを起こしてしまうためです。

少々面倒ですが、CSSでレイアウトの大きさを指定します。

※CSSで指定しておけば、仮にCDNを利用をしていてサーバーエラーになったとしても表示崩れは防ぐことができます。

CSSを記述

Swiperを最適化

デザイン要件:「サイト幅1280pxの時、幅305pxの画像を20px間隔で横並び」

このデザインカンプを再現するためのCSSパターンをいくつかご紹介します。

固定レイアウトの場合

.swiper-slide {
  width: 305px;
  margin-right: 20px;
}

こちらは最も簡単な指定方法ですが、サイト幅に対して画像の大きさは変化しません。

レスポンシブ対応させるには、細かくメディアクエリを指定する必要があり、柔軟性に欠けます。

可変レイアウトの場合

可変させる場合は、( 対象要素 / サイト幅 ) * 100%で算出できます。

サイト幅1280pxの時、画像幅が305px、間隔が20pxであれば、以下のように記述できます。

.swiper-slide {
  width: calc(305 / 1280 * 100%);
  margin-right: calc(20 / 1280 * 100%);
}

計算結果

  • 画像幅 = (305 / 1280) * 100% = 23.828125%
  • 間隔 = (20 / 1280) * 100% = 1.5625%

計算も簡単で導入しやすいレイアウトです。

画像可変、間隔固定の場合①

このパターンは、SwiperオプションslidesPerViewspaceBetweenを指定した時と同じレイアウトです。

表示枚数は保ちつつ、間隔は固定値にしたい場合は、こちらを採用します。

備考
  • slidesPerView:表示するスライド数
  • spaceBetween:スライド間の余白(px)

デザイン要件:「サイト幅1280pxの時、幅305pxの画像を20px間隔で横並び」

画像1枚あたりの占有幅 = 305 + 20 = 325px

次に、サイト幅1280pxに何枚並ぶかを計算します。

枚数 = (1280 + 20) / 325 = 4

+ 20はなぜ?

1280に20pxを足しているのは、最後の間隔を除くためです。理由は、間隔は画像の間にのみ必要で、最後の画像の右側には不要だからです。そのため、間隔の数は「画像の枚数 – 1」になります。

まとめると、slidesPerViewの計算式は次の通り。

slidesPerView = (screenWidth + gap) / (imageWidth + gap)  
              = (1280 + 20) / (305 + 20)  
              = 4

つまり、画像4枚+間隔でちょうど収まるので、JavaScriptでは以下の指定になります。

slidesPerView: 4,
spaceBetween: 20,

これをCSSで再現するには、画像幅を次の計算式で求めます

.swiper-slide {
  // ①(screenWidth + gap) / (imageWidth + gap) = n
  // ②calc((100% - (gap * (n - 1))) / n);
  width: calc((100% - (20px * 3)) / 4);
  margin-right: 20px;
}
  1. slidesPerView = nの計算 → 画面幅に何枚入るかを算出。
  2. 画像幅を計算 → calc関数で、間隔を引いた幅を割り算する。

サイト幅から全体の間隔を引いて、画像の枚数分で割ると、1枚あたりの幅が算出できるというわけです。

これでJavaScriptを使わずに同じ横並びレイアウトを実現できます。

画像可変、間隔固定の場合②

Swiperを最適化

デザイン要件(スマホ):「サイト幅375pxの時、幅200pxの画像を10px間隔で横並び」

計算方法は全く同じです。

slidesPerView = (screenWidth + gap) / (imageWidth + gap)
              = (375 + 10) / (200 + 10)
              ≈ 1.8333...

1.8333…枚の画像が並ぶため、JavaScriptでは以下の指定になります。

slidesPerView: 1.83333,
spaceBetween: 10,

これをCSSで再現すると次の計算式になります。

.swiper-slide {
  // ①(screenWidth + gap) / (imageWidth + gap) = n
  // ②calc((100% - (gap * (n - 1))) / n);
  width: calc((100% - (10px * ((385 / 210) - 1))) / (385 / 210));
  margin-right: 10px;
}

少し混乱しそうですが、最初の計算式nをそのままcalc()の中に代入してあるだけです。

この計算式をコンパイルすると、以下の数値になっていました。

width: calc((100% - 8.3333333333px) / 1.8333333333);

試しに100%を375pxに置き換えて計算するとwidthは200pxとなり、計算式が正しいことがわかります。

こちらを実装したデモサイト

ユーザー名:demo
パスワード:demo

各ファイルを読み込ませる

最初にダウンロードしたアセットや初期化専用JSファイルは、Swiperを適用するページにだけ読み込ませます。

Swiperに限らずですが、必要のないページで不要なファイルを読み込ませないようにすることが、軽量化の基本です。

以下は、WordPressで読み込ませる例です。

// Swiper適用ページ
if (is_front_page() || is_page('staff')) {
  wp_enqueue_style('swiper', get_template_directory_uri() . '/libs/swiper/swiper.min.css', array(), '8.4.7', 'all');
  wp_enqueue_script('swiper', get_template_directory_uri() . '/libs/swiper/swiper-bundle.min.js', array(), '8.4.7', array('strategy' => 'defer'));
  wp_enqueue_script('swiper-setup', get_template_directory_uri() . '/js/swiper-setup.js', array('swiper'), filemtime(get_theme_file_path('js/swiper-setup.js')), array('strategy' => 'defer'));
}

上から順に

  1. swiper.min.cssの読み込み
  2. swiper-bundle.min.jsの読み込み
  3. swiper-setup.jsの読み込み

この後に、サイトに必要なCSSやJSファイルを読み込ませます。

Safariでソースマップ読み込みエラーが出る

swiper-bundle.min.jsの最後にある以下の行を削除

//# sourceMappingURL=swiper-bundle.min.js.map

何の影響もないエラーなので、気にならなければそのままでも良いですが、私は気になるので削除します。

まとめ

以上の施策で、Swiperの最適化が完了です。

検証の際には、PageSpeed Insightsの数値だけでなく、実機やChromeの低速シミュレーションなどで確認しながら細かい調整を行なってください。

おすすめWEBスクール

WEB制作やWEBデザインを学びたいなら、SNSでも話題の「デイトラ」がおすすめ!
どのコースも10万円前後と業界最安値で、副業や転職に向けて十分なスキルを身につけることができます。

役に立ったら他の方にシェア

お気軽にコメントどうぞ

コメントする

目次