feat(blurhash): Move blurhash decoding to web worker

This commit is contained in:
ferferga 2020-10-20 00:14:55 +02:00
parent 8b85a2b4b3
commit 4b25d109dd
7 changed files with 91 additions and 15 deletions

View File

@ -4,7 +4,8 @@
<script lang="ts">
import Vue from 'vue';
import { decode } from 'blurhash';
import Worker from 'worker-loader!./blurhash.worker';
const worker = new Worker();
export default Vue.extend({
props: {
@ -37,15 +38,23 @@ export default Vue.extend({
},
methods: {
draw() {
const pixels = decode(this.hash, this.width, this.height);
if (pixels) {
const ctx = (this.$refs.canvas as HTMLCanvasElement).getContext('2d');
const imageData = ctx?.createImageData(this.width, this.height);
if (imageData) {
imageData.data.set(pixels);
ctx?.putImageData(imageData, 0, 0);
const bhash_data = {
hash: this.hash,
width: this.width,
height: this.height
};
worker.postMessage(bhash_data);
worker.onmessage = ({ data }) => {
const pixels = data;
if (pixels) {
const ctx = (this.$refs.canvas as HTMLCanvasElement).getContext('2d');
const imageData = ctx?.createImageData(this.width, this.height);
if (imageData) {
imageData.data.set(pixels);
ctx?.putImageData(imageData, 0, 0);
}
}
}
};
}
}
});

View File

@ -0,0 +1,8 @@
import { decode } from 'blurhash';
const ctx: Worker = self as any;
ctx.addEventListener('message', event => {
const data = event.data;
const pixels = decode(data.hash, data.width, data.height);
ctx.postMessage({ pixels });
});

View File

@ -224,6 +224,16 @@ const config: NuxtConfig = {
]
];
}
},
extend(config, { isDev, isClient }) {
// Web Worker support
if (isClient) {
config.module.rules.push({
test: /\.worker\.js$/,
use: { loader: 'worker-loader' },
exclude: /(node_modules)/
})
}
}
},

View File

@ -76,7 +76,8 @@
"stylelint-config-standard": "^20.0.0",
"ts-jest": "^26.4.1",
"ts-loader": "^8.0.5",
"vue-jest": "^3.0.7"
"vue-jest": "^3.0.7",
"worker-loader": "^3.0.5"
},
"config": {
"commitizen": {

View File

@ -3,7 +3,12 @@
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "Node",
"lib": ["ESNext", "ESNext.AsyncIterable", "DOM"],
"lib": [
"ESNext",
"ESNext.AsyncIterable",
"DOM",
"webworker"
],
"esModuleInterop": true,
"allowJs": true,
"sourceMap": true,
@ -12,8 +17,12 @@
"experimentalDecorators": true,
"baseUrl": ".",
"paths": {
"~/*": ["./*"],
"@/*": ["./*"]
"~/*": [
"./*"
],
"@/*": [
"./*"
]
},
"types": [
"@types/node",
@ -25,5 +34,9 @@
"jest"
]
},
"exclude": ["node_modules", ".nuxt", "dist"]
"exclude": [
"node_modules",
".nuxt",
"dist"
]
}

8
vue-shims.d.ts vendored
View File

@ -3,3 +3,11 @@ declare module '*.vue' {
export default Vue;
}
declare module "worker-loader!*" {
class WebpackWorker extends Worker {
constructor();
}
export default WebpackWorker;
}

View File

@ -2087,7 +2087,7 @@
jest-diff "^25.2.1"
pretty-format "^25.2.1"
"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5":
"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
version "7.0.6"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
@ -2718,6 +2718,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
alphanum-sort@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
@ -11094,6 +11104,15 @@ schema-utils@^2.0.0, schema-utils@^2.5.0, schema-utils@^2.6.1, schema-utils@^2.6
ajv "^6.12.4"
ajv-keywords "^3.5.2"
schema-utils@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef"
integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==
dependencies:
"@types/json-schema" "^7.0.6"
ajv "^6.12.5"
ajv-keywords "^3.5.2"
scrollparent@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/scrollparent/-/scrollparent-2.0.1.tgz#715d5b9cc57760fb22bdccc3befb5bfe06b1a317"
@ -13084,6 +13103,14 @@ worker-farm@^1.7.0:
dependencies:
errno "~0.1.7"
worker-loader@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-3.0.5.tgz#6e13a583c4120ba419eece8e4f2e098b014311bf"
integrity sha512-cOh4UqTtvT8eHpyuuTK2C66Fg/G5Pb7g11bwtKm7uyD0vj2hCGY1APlSzVD75V9ciYZt44VPbFPiSFTSLxkQ+w==
dependencies:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
wrap-ansi@^6.0.0, wrap-ansi@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"