0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

アプリ初回読み込み時に画像データを並列処理で読み込む

Last updated at Posted at 2023-04-30

サンプルアプリを作成している中で50枚ほどの画像を動的に表示する必要があり、その都度読み込んでいては遅いのでアプリの初回読み込み時に並列処理でVuexに持たせておくことにしました。

画像の並列処理と、このサンプルアプリ作成で初めてVuexを使用したので、そのアウトプットも兼ねて書いていきます。

環境

Vue 3.2.47
vuex 4.0.2
vite 4.2.0
node 16.13.0

App.vueでactionsを呼び出す

onMountedでvuexのactionsを呼び出します。

App.vue
<script setup lang="ts">
import { onMounted } from 'vue';
import { useStore } from 'vuex';

onMounted(async () => {
  const store = useStore();
  await store.dispatch('initializeCardImageList');
});
</script>

Vuexの実装

vuexはこのようになりました。
cardImageListというのが画像データを保持する変数になります。
actionsでinitializeCardImagesメソッドを呼び出し、戻り値をmutationに渡しています。

store/index.js
import { createStore } from 'vuex';
import { initializeCardImages } from '../utils/index';

type State = {
  cardImageList: Record<number, string>; // 画像データが入る
};

const store = createStore<State>({
  state: {
    cardImageList: {},
  },
  mutations: {
    setCardImageList(state, data) {
      state.cardImageList = data; // stateに格納
    },
  },
  actions: {
    initializeCardImageList({ commit }) {
      const cardImageList = initializeCardImages(); // このメソッド内で画像を並列処理で読み込む
      commit('setCardImageList', cardImageList); // mutationを呼び出す
    },
  },
  getters: {
    getCardImageList(state) {
      return state.cardImageList;
    },
  },
});

export default store;

画像を並列処理で読み込む

本題の並列処理になります。

utils/index.js
export const initializeCardImages = (): Record<string, HTMLImageElement> => {
  // cardImageListにはオブジェクト形式でインポートした画像データが入っている
  // { 1: image1, 2: image2, 3: image3 ... }
  const promises = Object.values(cardImageList).map((url) => {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => resolve(img);
      img.onerror = () => reject(new Error(`Failed to load image ${url}`));
      img.src = url;
    });
  });

  const imageCache: Record<string, HTMLImageElement> = {};
  Promise.all(promises).then((images) => {
    images.forEach((img, i) => (imageCache[i] = img as HTMLImageElement));
  });
  return imageCache;
};

まとめ

今回はアプリの初回読み込み時に画像データを並列処理で読み込む方法をまとめました。

現状の実装では最初にまとめて行っているだけで、読み込み処理自体の長さはそこまで改善されていないので、画像を圧縮させたりして読み込み時間の短縮もいずれ行おうと思います。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?