LoginSignup
2
0

More than 3 years have passed since last update.

VueCLI + javascript環境で、WebWorkerを使用する

Posted at

web workerでの記事は、webpack環境(nuxt.js環境)や、typescriptでの記事が多く存在し、
所々詰まっていたので記事にします。
Web Worker の使用(MDN)
Vue.js で WebWorker を使う
laravel-mix + Vue.js (ES) + WebWorker (TS)
これらの記事を参考にしました。

今回作成したgitリポジトリ

導入

vue ui 等でvueを立ち上げたものとして、
プロジェクト直下で
npm install worker-loader
とし、worker-loaderを導入します。

そして、プロジェクト直下のvue.config.js(無ければ作成し)に、
下記の内容を記述します

vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('worker-loader')
      .test(/\.worker\.js$/)
      .use({
        loader: 'worker-loader',
        options: {
          inline: true
        }
      })
      .loader('worker-loader')
      .end()
  }
  //...
}

実行準備

次に、srcフォルダ直下に
workersというフォルダと、worker1というjsファイルを作成します。
(※名称はなんでも良いと思います。また、フォルダは存在していなくても良いと思います。)

src
 |-assets
 |-components
 |- ...
  |-workers
     |-worker1.js
 |-App.vue
 |-main.js

このような構成になるかと思います。
次に、worker1.jsの中身を

worker1.js
addEventListener('message', e => {
    const { data } = e
    if (data && typeof data == 'number') {
        return postMessage(data*data)
    } else {
        return postMessage(10)
    }
})

export default {}

としてみます。
workerに投げられた変数が、int型の場合、二乗を返し、
それ以外の場合10を返す関数です。

次に、実際にvueファイルでworkerを呼び出します。
試しに、vuecliで生成されるHome.vueに書いていきます。

Home.vue
<script>
import Worker1 from 'worker-loader!@/workers/worker1'
export default {
  name: 'Home',
  components: {
  },
  data () {
    return {
      reload: 0
    }
  },
  methods: {
    workerTest: function () {
      const worker = new Worker1()
      worker.onmeessage = e => {
        const { data } = e
        this.reload = data
        worker.terminate()
      }
      worker.postMessage(20)
    }
  }
}
</script>

このようにします。
import文に、worker-loader!をpath名の前に挿入することに気をつけ、また、
worker.onmessageで、workerの処理が終わった場合(つまりpostMessageが返った場合)の処理を記述します。
今回の場合は、処理が終わり次第、this.reloadに代入し他で参照できるようにします。
また処理を終えたあとにworkerが存在する意味はないので、terminateで削除します。
(※importがlintに怒られるかもしれないので、その場合はruleに記述しましょう...)

実行

Home.vue
<template>
  <div class="home">
    <button @click="workerTest()">worker!!</button>
    {{ this.reload }}
  </div>
</template>

実際に、このようにして試してみると...

スクリーンショット 2021-03-01 18.51.46.png

スクリーンショット 2021-03-01 18.51.23.png

実際に、workerを通して、値が変更されたのがわかります。
また、

Home.vue
workerTest: function () {
      const worker = new Worker1()
      worker.onmessage = e => {
        const { data } = e
        this.reload = data
      }
      worker.postMessage(20)
    }

とし、
開発者ツールのSourcesをみると
スクリーンショット 2021-03-01 18.53.44.png
実際にworkerが立っているのがわかります。

other

ループの中で実行

試しに

Home.vue
workerTestLoop: function () {
      for (let i = 0; i < 10; i++) {
        const worker = new Worker1()
        worker.onmessage = e => {
          const { data } = e
          this.reload += data
          worker.terminate()
        }
        worker.postMessage(20)
      }
    }

とし、先ほど同様に実行してみると、
実際に、先ほどの数字が4000(400 * 10)となっているのがわかります。
スクリーンショット 2021-03-01 18.59.49.png

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