🚔

Vuetify3でマテリアルアイコン(mdi)を使う際のベストプラクティス

2022/06/13に公開

現在、ベータ版のVuetify3でMaterial Design Icon(MDI)で必要なアイコンだけ読み込ませるベストプラクティスをメモに残しておきます。
(Laravel Mixの環境ですがvue-cliやNuxtでも同様です)

@mdi/fontは重すぎる!

「アイコンフォントは重すぎる!!!」某米倉◯子さんに読んでいただきたいですね。
MDIやFontawesomeなどのアイコンフォントは300KB程度。更に追加でフォントファイルも読み込まれるため非常に読み込み遅延の阻害になりPageSpeed Insightsのモバイルスコアがガタ落ちします。
しかも使うアイコンの数は多くて10個程度だしもったいなすぎる。

そこで、@mdi/fontsパッケージから @mdi/js パッケージに切り替え、必要なアイコンSVGのみバンドルする手法を活用します。
https://www.npmjs.com/package/@mdi/js

Vuetify3で必要なアイコンだけ読み込む手順

とても簡単だが、ベータ版のVuetify3では従来と使い方が若干変わってるので注意。

  1. @mdi/jsをインストール
npm i -D @mdi/js
  1. app.ts(js)でインポート
/resources/js/app.ts
import { createVuetify } from 'vuetify';
- import { aliases, mdi } from 'vuetify/iconsets/mdi';
+ import { aliases, mdi } from 'vuetify/iconsets/mdi-svg';

const vuetify = createVuetify({
    icons: {
        defaultSet: 'mdi',
        aliases,
        sets: {
            mdi,
        },
    },
});
//    ︙
  1. 各コンポーネントで読み込む
    各コンポーネント内で使いたいアイコンをインポートして、data内で定義します。
  import { mdiAccount } from '@mdi/js'

  export default {
    data: () => ({
      mdiAccount
    }),
  }
  1. Template内で使う
    あとは、iconクラスにv-bindディレクティブを付与して先程設定したアイコン変数を入れたら表示されます。因みに<v-app-bar-nav-icon>はそのまま使えます。
<v-icon :icon="mdiAccount" />

結果

本来数百KBものリソースを消費するMDIが以下のように容量が激減します。

※開発ビルドでは全てのアイコンSVGを読み込むので一時的にJSファイルが膨大になりますが、ちゃんとProductionビルド時にはインポートしてない物はバンドルしないようになるのでご安心を。

https://next.vuetifyjs.com/en/features/icon-fonts/

Discussion