From b9b6e57581d983ade4d21d2482b08f8c7ed22a24 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 13 May 2021 13:50:31 +0100 Subject: [PATCH] wasm-bindgen-rayon and new OMT plugin (#1007) * WIP: wasm-bindgen-rayon and new OMT plugin * Bump package-lock * Make OMT work again * Update year * Restore accidental change * Prevent minification of `nextDefineUri` * Delay loading external deps This gives inline `define` calls a chance to define dependencies for earlier `define` calls on the same page. * Add comment --- codecs/oxipng/Cargo.lock | 69 +++++++---- codecs/oxipng/Cargo.toml | 8 +- codecs/oxipng/build.sh | 2 - .../src/workerHelpers.js | 98 +++++++++++++++ .../oxipng/pkg-parallel/squoosh_oxipng.d.ts | 35 ++++-- codecs/oxipng/pkg-parallel/squoosh_oxipng.js | 111 +++++++++++------ .../pkg-parallel/squoosh_oxipng_bg.wasm | Bin 348541 -> 337895 bytes .../pkg-parallel/squoosh_oxipng_bg.wasm.d.ts | 10 +- codecs/oxipng/pkg/squoosh_oxipng.d.ts | 2 +- codecs/oxipng/pkg/squoosh_oxipng.js | 11 +- codecs/oxipng/pkg/squoosh_oxipng_bg.wasm | Bin 269114 -> 269140 bytes codecs/oxipng/pkg/squoosh_oxipng_bg.wasm.d.ts | 1 + codecs/oxipng/src/lib.rs | 6 +- codecs/oxipng/src/parallel.rs | 62 ---------- lib/client-bundle-plugin.js | 22 +++- lib/css-plugin.js | 2 +- lib/omt.ejs | 112 ++++++++---------- package-lock.json | 110 +++++++++++++++-- package.json | 2 +- rollup.config.js | 14 +-- .../encoders/oxiPNG/worker/oxipngEncode.ts | 43 +------ .../oxiPNG/worker/sub-worker/index.ts | 25 ---- src/sw/to-cache.ts | 3 +- worker-tsconfig.json | 1 - 24 files changed, 441 insertions(+), 308 deletions(-) create mode 100644 codecs/oxipng/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js delete mode 100644 codecs/oxipng/src/parallel.rs delete mode 100644 src/features/encoders/oxiPNG/worker/sub-worker/index.ts diff --git a/codecs/oxipng/Cargo.lock b/codecs/oxipng/Cargo.lock index 49428bb2..4f331186 100644 --- a/codecs/oxipng/Cargo.lock +++ b/codecs/oxipng/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "adler" version = "0.2.3" @@ -232,6 +234,15 @@ dependencies = [ "either", ] +[[package]] +name = "js-sys" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -350,12 +361,6 @@ dependencies = [ "libc", ] -[[package]] -name = "once_cell" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" - [[package]] name = "oxipng" version = "4.0.3" @@ -401,9 +406,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ "unicode-xid", ] @@ -484,24 +489,28 @@ dependencies = [ "pest", ] +[[package]] +name = "spmc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a8428da277a8e3a15271d79943e80ccc2ef254e78813a166a08d65e4c3ece5" + [[package]] name = "squoosh-oxipng" version = "0.1.0" dependencies = [ - "crossbeam-channel", "libdeflater", "log", - "once_cell", "oxipng", - "rayon", "wasm-bindgen", + "wasm-bindgen-rayon", ] [[package]] name = "syn" -version = "1.0.58" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" dependencies = [ "proc-macro2", "quote", @@ -522,9 +531,9 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "wasm-bindgen" -version = "0.2.69" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e" +checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -532,9 +541,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.69" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62" +checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" dependencies = [ "bumpalo", "lazy_static", @@ -547,9 +556,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.69" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084" +checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -557,9 +566,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.69" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549" +checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" dependencies = [ "proc-macro2", "quote", @@ -569,7 +578,19 @@ dependencies = [ ] [[package]] -name = "wasm-bindgen-shared" -version = "0.2.69" +name = "wasm-bindgen-rayon" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158" +checksum = "3069d2a42e7a7e3bfde668f84adb5fbc35701ca2b39b27a064cbd5ede4e78194" +dependencies = [ + "js-sys", + "rayon", + "spmc", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" diff --git a/codecs/oxipng/Cargo.toml b/codecs/oxipng/Cargo.toml index 6ab15d3a..b0b9a191 100644 --- a/codecs/oxipng/Cargo.toml +++ b/codecs/oxipng/Cargo.toml @@ -14,15 +14,13 @@ crate-type = ["cdylib"] [dependencies] oxipng = { version = "4.0.1", default-features = false, features = ["libdeflater"] } libdeflater = { version = "0.7.1", features = ["freestanding"] } -wasm-bindgen = "0.2.68" +wasm-bindgen = "0.2.73" log = { version = "0.4.11", features = ["release_max_level_off"] } -rayon = { version = "1.5.0", optional = true } -once_cell = { version = "1.5.2", optional = true } -crossbeam-channel = { version = "0.5.0", optional = true } +wasm-bindgen-rayon = { version = "1.0", optional = true } [profile.release] lto = true opt-level = "s" [features] -parallel = ["oxipng/parallel", "rayon", "crossbeam-channel", "once_cell"] +parallel = ["oxipng/parallel", "wasm-bindgen-rayon"] diff --git a/codecs/oxipng/build.sh b/codecs/oxipng/build.sh index 200481fb..ee3d2539 100755 --- a/codecs/oxipng/build.sh +++ b/codecs/oxipng/build.sh @@ -6,6 +6,4 @@ rm -rf pkg,{-parallel} export CFLAGS="${CFLAGS} -DUNALIGNED_ACCESS_IS_FAST=1" wasm-pack build -t web RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel -# Workaround https://github.com/rustwasm/wasm-bindgen/issues/2133: -sed -i "s|maybe_memory:|maybe_memory?:|" pkg-parallel/squoosh_oxipng.d.ts rm pkg{,-parallel}/.gitignore diff --git a/codecs/oxipng/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js b/codecs/oxipng/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js new file mode 100644 index 00000000..da13c772 --- /dev/null +++ b/codecs/oxipng/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js @@ -0,0 +1,98 @@ +/** + * Copyright 2021 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Note: we use `wasm_bindgen_worker_`-prefixed message types to make sure +// we can handle bundling into other files, which might happen to have their +// own `postMessage`/`onmessage` communication channels. +// +// If we didn't take that into the account, we could send much simpler signals +// like just `0` or whatever, but the code would be less resilient. + +function waitForMsgType(target, type) { + return new Promise(resolve => { + target.addEventListener('message', function onMsg({ data }) { + if (data == null || data.type !== type) return; + target.removeEventListener('message', onMsg); + resolve(data); + }); + }); +} + +waitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => { + // # Note 1 + // Our JS should have been generated in + // `[out-dir]/snippets/wasm-bindgen-rayon-[hash]/workerHelpers.js`, + // resolve the main module via `../../..`. + // + // This might need updating if the generated structure changes on wasm-bindgen + // side ever in the future, but works well with bundlers today. The whole + // point of this crate, after all, is to abstract away unstable features + // and temporary bugs so that you don't need to deal with them in your code. + // + // # Note 2 + // This could be a regular import, but then some bundlers complain about + // circular deps. + // + // Dynamic import could be cheap if this file was inlined into the parent, + // which would require us just using `../../..` in `new Worker` below, + // but that doesn't work because wasm-pack unconditionally adds + // "sideEffects":false (see below). + // + // OTOH, even though it can't be inlined, it should be still reasonably + // cheap since the requested file is already in cache (it was loaded by + // the main thread). + const pkg = await import('../../..'); + await pkg.default(data.module, data.memory); + postMessage({ type: 'wasm_bindgen_worker_ready' }); + pkg.wbg_rayon_start_worker(data.receiver); +}); + +export async function startWorkers(module, memory, builder) { + const workerInit = { + type: 'wasm_bindgen_worker_init', + module, + memory, + receiver: builder.receiver() + }; + + try { + await Promise.all( + Array.from({ length: builder.numThreads() }, () => { + // Self-spawn into a new Worker. + // + // TODO: while `new URL('...', import.meta.url) becomes a semi-standard + // way to get asset URLs relative to the module across various bundlers + // and browser, ideally we should switch to `import.meta.resolve` + // once it becomes a standard. + // + // Note: we could use `../../..` as the URL here to inline workerHelpers.js + // into the parent entry instead of creating another split point - + // this would be preferable from optimization perspective - + // however, Webpack then eliminates all message handler code + // because wasm-pack produces "sideEffects":false in package.json + // unconditionally. + // + // The only way to work around that is to have side effect code + // in an entry point such as Worker file itself. + const worker = new Worker(new URL('./workerHelpers.js', import.meta.url), { + type: 'module' + }); + worker.postMessage(workerInit); + return waitForMsgType(worker, 'wasm_bindgen_worker_ready'); + }) + ); + builder.build(); + } finally { + builder.free(); + } +} diff --git a/codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts b/codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts index 3ed1d157..8ca403de 100644 --- a/codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts +++ b/codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts @@ -7,25 +7,43 @@ */ export function optimise(data: Uint8Array, level: number): Uint8Array; /** -* @param {number} num -* @returns {any} +* @param {number} num_threads +* @returns {Promise} */ -export function worker_initializer(num: number): any; +export function initThreadPool(num_threads: number): Promise; +/** +* @param {number} receiver +*/ +export function wbg_rayon_start_worker(receiver: number): void; /** */ -export function start_main_thread(): void; +export class wbg_rayon_PoolBuilder { + free(): void; +/** +* @returns {number} +*/ + numThreads(): number; +/** +* @returns {number} +*/ + receiver(): number; /** */ -export function start_worker_thread(): void; + build(): void; +} export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; export interface InitOutput { readonly optimise: (a: number, b: number, c: number, d: number) => void; - readonly worker_initializer: (a: number) => number; - readonly start_main_thread: () => void; - readonly start_worker_thread: () => void; + readonly __wbg_wbg_rayon_poolbuilder_free: (a: number) => void; + readonly wbg_rayon_poolbuilder_numThreads: (a: number) => number; + readonly wbg_rayon_poolbuilder_receiver: (a: number) => number; + readonly wbg_rayon_poolbuilder_build: (a: number) => void; + readonly initThreadPool: (a: number) => number; + readonly wbg_rayon_start_worker: (a: number) => void; readonly __wbindgen_export_0: WebAssembly.Memory; + readonly __wbindgen_add_to_stack_pointer: (a: number) => number; readonly __wbindgen_malloc: (a: number) => number; readonly __wbindgen_free: (a: number, b: number) => void; readonly __wbindgen_start: () => void; @@ -41,4 +59,3 @@ export interface InitOutput { * @returns {Promise} */ export default function init (module_or_path?: InitInput | Promise, maybe_memory?: WebAssembly.Memory): Promise; - \ No newline at end of file diff --git a/codecs/oxipng/pkg-parallel/squoosh_oxipng.js b/codecs/oxipng/pkg-parallel/squoosh_oxipng.js index 1111760d..a1689a5f 100644 --- a/codecs/oxipng/pkg-parallel/squoosh_oxipng.js +++ b/codecs/oxipng/pkg-parallel/squoosh_oxipng.js @@ -1,21 +1,6 @@ +import { startWorkers } from './snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js'; let wasm; -let memory; - -const heap = new Array(32).fill(undefined); - -heap.push(undefined, null, true, false); - -let heap_next = heap.length; - -function addHeapObject(obj) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); @@ -33,6 +18,21 @@ function getStringFromWasm0(ptr, len) { return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len)); } +const heap = new Array(32).fill(undefined); + +heap.push(undefined, null, true, false); + +let heap_next = heap.length; + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + let WASM_VECTOR_LEN = 0; function passArray8ToWasm0(arg, malloc) { @@ -60,8 +60,7 @@ function getArrayU8FromWasm0(ptr, len) { */ export function optimise(data, level) { try { - const retptr = wasm.__wbindgen_export_1.value - 16; - wasm.__wbindgen_export_1.value = retptr; + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc); var len0 = WASM_VECTOR_LEN; wasm.optimise(retptr, ptr0, len0, level); @@ -71,7 +70,7 @@ export function optimise(data, level) { wasm.__wbindgen_free(r0, r1 * 1); return v1; } finally { - wasm.__wbindgen_export_1.value += 16; + wasm.__wbindgen_add_to_stack_pointer(16); } } @@ -89,29 +88,66 @@ function takeObject(idx) { return ret; } /** -* @param {number} num -* @returns {any} +* @param {number} num_threads +* @returns {Promise} */ -export function worker_initializer(num) { - var ret = wasm.worker_initializer(num); +export function initThreadPool(num_threads) { + var ret = wasm.initThreadPool(num_threads); return takeObject(ret); } /** +* @param {number} receiver */ -export function start_main_thread() { - wasm.start_main_thread(); +export function wbg_rayon_start_worker(receiver) { + wasm.wbg_rayon_start_worker(receiver); } /** */ -export function start_worker_thread() { - wasm.start_worker_thread(); +export class wbg_rayon_PoolBuilder { + + static __wrap(ptr) { + const obj = Object.create(wbg_rayon_PoolBuilder.prototype); + obj.ptr = ptr; + + return obj; + } + + __destroy_into_raw() { + const ptr = this.ptr; + this.ptr = 0; + + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wbg_rayon_poolbuilder_free(ptr); + } + /** + * @returns {number} + */ + numThreads() { + var ret = wasm.wbg_rayon_poolbuilder_numThreads(this.ptr); + return ret >>> 0; + } + /** + * @returns {number} + */ + receiver() { + var ret = wasm.wbg_rayon_poolbuilder_receiver(this.ptr); + return ret; + } + /** + */ + build() { + wasm.wbg_rayon_poolbuilder_build(this.ptr); + } } -async function load(module, imports, maybe_memory) { +async function load(module, imports) { if (typeof Response === 'function' && module instanceof Response) { - memory = imports.wbg.memory = new WebAssembly.Memory({initial:17,maximum:16384,shared:true}); if (typeof WebAssembly.instantiateStreaming === 'function') { try { return await WebAssembly.instantiateStreaming(module, imports); @@ -130,7 +166,6 @@ async function load(module, imports, maybe_memory) { return await WebAssembly.instantiate(bytes, imports); } else { - memory = imports.wbg.memory = maybe_memory; const instance = await WebAssembly.instantiate(module, imports); if (instance instanceof WebAssembly.Instance) { @@ -144,10 +179,13 @@ async function load(module, imports, maybe_memory) { async function init(input, maybe_memory) { if (typeof input === 'undefined') { - input = import.meta.url.replace(/\.js$/, '_bg.wasm'); + input = new URL('squoosh_oxipng_bg.wasm', import.meta.url); } const imports = {}; imports.wbg = {}; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; imports.wbg.__wbindgen_module = function() { var ret = init.__wbindgen_wasm_module; return addHeapObject(ret); @@ -156,19 +194,18 @@ async function init(input, maybe_memory) { var ret = wasm.__wbindgen_export_0; return addHeapObject(ret); }; - imports.wbg.__wbg_of_6510501edc06d65e = function(arg0, arg1) { - var ret = Array.of(takeObject(arg0), takeObject(arg1)); + imports.wbg.__wbg_startWorkers_914655bb4d5bb5e1 = function(arg0, arg1, arg2) { + var ret = startWorkers(takeObject(arg0), takeObject(arg1), wbg_rayon_PoolBuilder.__wrap(arg2)); return addHeapObject(ret); }; - imports.wbg.__wbindgen_throw = function(arg0, arg1) { - throw new Error(getStringFromWasm0(arg0, arg1)); - }; if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { input = fetch(input); } - const { instance, module } = await load(await input, imports, maybe_memory); + imports.wbg.memory = maybe_memory || new WebAssembly.Memory({initial:17,maximum:16384,shared:true}); + + const { instance, module } = await load(await input, imports); wasm = instance.exports; init.__wbindgen_wasm_module = module; diff --git a/codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm b/codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm index 49fe70f30c9b8f8d204c63f3af70a09ecccc5aae..6c0304924b4865043b261c5ab457e3691edc9904 100644 GIT binary patch delta 79078 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 Nq-A5u?Coyze*k%X1jhgX delta 90300 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 sj=B+QtJyab3Zsus4Os&_l18eQzK*;Znb~ void; + readonly __wbindgen_add_to_stack_pointer: (a: number) => number; readonly __wbindgen_malloc: (a: number) => number; readonly __wbindgen_free: (a: number, b: number) => void; } @@ -25,4 +26,3 @@ export interface InitOutput { * @returns {Promise} */ export default function init (module_or_path?: InitInput | Promise): Promise; - \ No newline at end of file diff --git a/codecs/oxipng/pkg/squoosh_oxipng.js b/codecs/oxipng/pkg/squoosh_oxipng.js index 74c98c89..ee7a699f 100644 --- a/codecs/oxipng/pkg/squoosh_oxipng.js +++ b/codecs/oxipng/pkg/squoosh_oxipng.js @@ -44,8 +44,7 @@ function getArrayU8FromWasm0(ptr, len) { */ export function optimise(data, level) { try { - const retptr = wasm.__wbindgen_export_0.value - 16; - wasm.__wbindgen_export_0.value = retptr; + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc); var len0 = WASM_VECTOR_LEN; wasm.optimise(retptr, ptr0, len0, level); @@ -55,13 +54,12 @@ export function optimise(data, level) { wasm.__wbindgen_free(r0, r1 * 1); return v1; } finally { - wasm.__wbindgen_export_0.value += 16; + wasm.__wbindgen_add_to_stack_pointer(16); } } async function load(module, imports) { if (typeof Response === 'function' && module instanceof Response) { - if (typeof WebAssembly.instantiateStreaming === 'function') { try { return await WebAssembly.instantiateStreaming(module, imports); @@ -80,7 +78,6 @@ async function load(module, imports) { return await WebAssembly.instantiate(bytes, imports); } else { - const instance = await WebAssembly.instantiate(module, imports); if (instance instanceof WebAssembly.Instance) { @@ -94,7 +91,7 @@ async function load(module, imports) { async function init(input) { if (typeof input === 'undefined') { - input = import.meta.url.replace(/\.js$/, '_bg.wasm'); + input = new URL('squoosh_oxipng_bg.wasm', import.meta.url); } const imports = {}; imports.wbg = {}; @@ -106,6 +103,8 @@ async function init(input) { input = fetch(input); } + + const { instance, module } = await load(await input, imports); wasm = instance.exports; diff --git a/codecs/oxipng/pkg/squoosh_oxipng_bg.wasm b/codecs/oxipng/pkg/squoosh_oxipng_bg.wasm index 97715f1ad9b9cb746d7989e4f6a5919bc6d1b017..97356d3766d8697e406284601275a2a43141b139 100644 GIT binary patch delta 1068 zcmZWnZEO@}5Z-y-y`^w>($J#_*N+WV%SX_9gi>oLy=ns{7E+|C{lnV39#FKs3q1oR z4M$0kgv7RHlWwArSP_x0!m-eWJNziU9<3I;d_@SqP?1C>8cB%Jnm7yk%OCU3J2TJB z^SnEo8p^#sl-rjTS79f|D~S|cpzMV=TuNJ{ExNT6Qcg4$Z*6Psh)7DYrfmzgwzq7G zv}?^REm}OPb;O&)Z)&kc;0d&#+UlaTM$B(kFcR3U!HlWMRjTl*Tb+@iiuJoc$>zxqN}G#b%Bn z%HlGYPGSISSJ~*N-KepVIK+TY@d2M_$ieN#&-4xB!avb!C$@2bYhSW`!Dezi&bHac zFo*B3+1SVvIG1I+#Af4TR@IA(2>eDLvWgKL!G7|2+%tCF_1d`dfS@Lnoh4Gxo^JMv z4w5sNFY9)2o~gP*b10)%l`l6_1r_x8dT>$Ezc)QpoP7)qmix_B>P>|*rdnFBOyddD zYUOI<*FNN%JxkIux2mOO=8nLKU`$nckDJ})-~~|T;J%l=k0uwHN9qgU^v?83s$L(+ zH@|zWkhxAbT=)FPQ=~s^)||klJEZZ@D9<)4Hx*BRL{X@3i#2iLN-X5YIE?1A@EO%z zlxsG1r8aQEcl%}?Wvu%PXhfztqT6;DuTq=ql$Rf8DHTMV+xI0lqZH~F!xBIDB<+ILQ&_i zE_+7Y;vE<>7YaXzix-OiST5(EyGV^lGH%XG;w_irY{5&$ zz#=?p4XhScn}w9UgycTMbjbg@}=s6 SrQyiNNFZDhFlPJZr~d)!=W2EU delta 1030 zcmZWnU2GI(6y1Bina#GlQ>tAM`{$&H1>~n`=r*mvvS0%V)LOA=cwxh~Yi(k?8(O3g zV(CW3m`GbEGDb^)@NbQ!8PiYNYAr*zT|oyDP_z$*1T^s{F#(N%K6s}fFFxG4bG~!# zz2|;2SBJAlhO>K9;tHIhbR`)IN|tX?y{)m<_>SH1_~MCfGF9bW+J+lu@m$)z!H|tEpLJ%uO#a-b`%e`kxX}Kc->! z-KHn4=Dj1^_^fE=dJWm~-V(AEO3CpR6F5iVY=HOWwo4|)`Vt5LpJ{Iy>XOMH*O|0?-d0DE~gic{k zrNbSt_bE_U6}xdp`&hYd`mjcUAYURgH9*L(8y0 zHU`9imoCV8IbtG{ZCoi3i@42S1)|1vu>L9W1Ai~GV5!JsSg}+be3bL$XT$-oI|bF6 z@^A{dQ_S{tVu&S+*NazG@BLxs;4&odtP+#-g47R z;vf89;+k)05NljV??*%}|5x%>R9y4ZlsVcaMi{;p7mY+y^2dbO%!XxgyO<#}YbTQ_ cncgY3p3p)S`jSvZ+3L{t(omzhDo Vec { let mut options = oxipng::Options::from_preset(level); diff --git a/codecs/oxipng/src/parallel.rs b/codecs/oxipng/src/parallel.rs deleted file mode 100644 index 90046659..00000000 --- a/codecs/oxipng/src/parallel.rs +++ /dev/null @@ -1,62 +0,0 @@ -use crossbeam_channel::{bounded, Receiver, Sender}; -use once_cell::sync::OnceCell; -use wasm_bindgen::prelude::*; -use wasm_bindgen::JsValue; - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = Array, js_name = of)] - fn array_of_2(a: JsValue, b: JsValue) -> JsValue; -} - -// This is one of the parts that work around Chromium incorrectly implementing postMessage: -// https://bugs.chromium.org/p/chromium/issues/detail?id=1075645 -// -// rayon::ThreadPoolBuilder (used below) executes spawn handler to populate the worker pool, -// and then blocks the current thread until each worker unblocks its (opaque) lock. -// -// Normally, we could use postMessage directly inside the spawn handler to -// post module + memory + threadPtr to each worker, and the block the current thread. -// -// However, that bug means that postMessage is currently delayed until the next event loop, -// which will never spin since we block the current thread, and so the other workers will -// never be able to unblock us. -// -// To work around this problem, we: -// 1) Expose `worker_initializer` that returns module + memory pair (without threadPtr) -// that workers can be initialised with to become native threads. -// JavaScript can postMessage this pair in advance, and asynchronously wait for workers -// to acknowledge the receipt. -// 2) Create a global communication channel on the Rust side using crossbeam. -// It will be used to send threadPtr to the pre-initialised workers -// instead of postMessage. -// 3) Provide a separate `start_main_thread` that expects all workers to be ready, -// and just uses the provided channel to send `threadPtr`s using the -// shared memory and blocks the current thread until they're all grabbed. -// 4) Provide a `worker_initializer` that is expected to be invoked from various workers, -// reads one `threadPtr` from the shared channel and starts running it. -static CHANNEL: OnceCell<(Sender, Receiver)> = - OnceCell::new(); - -#[wasm_bindgen] -pub fn worker_initializer(num: usize) -> JsValue { - CHANNEL.get_or_init(|| bounded(num)); - array_of_2(wasm_bindgen::module(), wasm_bindgen::memory()) -} - -#[wasm_bindgen] -pub fn start_main_thread() { - let (sender, _) = CHANNEL.get().unwrap(); - - rayon::ThreadPoolBuilder::new() - .num_threads(sender.capacity().unwrap()) - .spawn_handler(|thread| Ok(sender.send(thread).unwrap_throw())) - .build_global() - .unwrap_throw() -} - -#[wasm_bindgen] -pub fn start_worker_thread() { - let (_, receiver) = CHANNEL.get().unwrap(); - receiver.recv().unwrap_throw().run() -} diff --git a/lib/client-bundle-plugin.js b/lib/client-bundle-plugin.js index c65efd53..06b69615 100644 --- a/lib/client-bundle-plugin.js +++ b/lib/client-bundle-plugin.js @@ -137,10 +137,24 @@ export default function (inputOptions, outputOptions, resolveFileUrl) { const dependencies = getDependencies(clientOutput, clientEntry); if (property.startsWith(allSrcPlaceholder)) { - const depCodes = dependencies.map( - (name) => clientOutput.find((item) => item.fileName === name).code, - ); - return JSON.stringify([clientEntry.code, ...depCodes].join(';')); + const allModules = [ + clientEntry, + ...dependencies.map((name) => + clientOutput.find((item) => item.fileName === name), + ), + ]; + + const inlineDefines = [ + ...allModules.map( + (item) => + `self.nextDefineUri=location.origin+${resolveFileUrl(item)};${ + item.code + }`, + ), + 'self.nextDefineUri=""', + ]; + + return JSON.stringify(inlineDefines.join('')); } return ( diff --git a/lib/css-plugin.js b/lib/css-plugin.js index 43e040b3..ce1a8216 100644 --- a/lib/css-plugin.js +++ b/lib/css-plugin.js @@ -48,7 +48,7 @@ const appendCssSource = ` } `; -export default function (resolveFileUrl) { +export default function () { /** @type {string[]} */ let emittedCSSIds; /** @type {Map} */ diff --git a/lib/omt.ejs b/lib/omt.ejs index 2f2741ed..fabca564 100644 --- a/lib/omt.ejs +++ b/lib/omt.ejs @@ -1,5 +1,5 @@ /** - * Copyright 2020 Google Inc. All Rights Reserved. + * Copyright 2021 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,80 +13,64 @@ // If the loader is already loaded, just stop. if (!self.<%- amdFunctionName %>) { - const singleRequire = async name => { - if (name === 'require') return require; - let url; - if (name.startsWith(location.origin)) { - url = name.slice(location.origin.length); - } else { - url = name.slice(1) + '.js'; - } - if (!url.startsWith('/c/')) { - url = '/c' + url; - } - name = './static' + url; - if (registry[name]) return registry[name]; + let registry = {}; - if (!registry[name]) { + const singleRequire = (uri, parentUri) => { + let origURI = uri; + uri = new URL(uri + ".js", parentUri).href; + return registry[uri] || ( <% if (useEval) { %> - const text = await fetch(url).then(resp => resp.text()); - eval(text); + fetch(uri) + .then(resp => resp.text()) + .then(code => { + self.nextDefineUri = uri; + eval(code); + }) <% } else { %> - if ("document" in self) { - await new Promise(resolve => { + new Promise(resolve => { + if ("document" in self) { const script = document.createElement("script"); - script.src = url; - document.head.appendChild(script); + script.src = uri; script.onload = resolve; - }); - } else { - importScripts(url); - } + document.head.appendChild(script); + } else { + self.nextDefineUri = uri; + importScripts(uri); + resolve(); + } + }) <% } %> - } - if (!registry[name]) { - throw new Error(`Module ${name} didn’t register its module`); - } - return registry[name]; + .then(() => { + let promise = registry[uri]; + if (!promise) { + throw new Error(`Module ${uri} didn’t register its module`); + } + return promise; + }) + ); }; - const require = (names, resolve) => { - Promise.all(names.map(singleRequire)) - .then(modules => resolve(modules.length === 1 ? modules[0] : modules)); - }; - - const registry = { - require: Promise.resolve(require) - }; - - self.<%- amdFunctionName %> = (moduleName, depsNames, factory) => { - if (registry[moduleName]) { + self.<%- amdFunctionName %> = (depsNames, factory) => { + const uri = self.nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href; + if (registry[uri]) { // Module is already loading or loaded. return; } - registry[moduleName] = Promise.resolve().then(() => { - let exports = {}; - const module = { - uri: location.origin + moduleName.slice(1) - }; - return Promise.all( - depsNames.map(depName => { - switch(depName) { - case "exports": - return exports; - case "module": - return module; - default: - return singleRequire(depName); - } - }) - ).then(deps => { - const facValue = factory(...deps); - if (!exports.default) { - exports.default = facValue; - } - return exports; - }); + let exports = {}; + const require = depUri => singleRequire(depUri, uri); + const specialDeps = { + module: { uri }, + exports, + require + }; + // Note: Promise.resolve() is necessary to delay loading until all the + // `define`s on the current page had a chance to execute first. + // This allows to inline some deps on the main page. + registry[uri] = Promise.resolve().then(() => Promise.all(depsNames.map( + depName => specialDeps[depName] || require(depName) + ))).then(deps => { + factory(...deps); + return exports; }); }; } diff --git a/package-lock.json b/package-lock.json index a1fa60e3..04043b68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -179,13 +179,25 @@ } }, "@surma/rollup-plugin-off-main-thread": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz", - "integrity": "sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.1.tgz", + "integrity": "sha512-7OU8wfyv18YPWVmecg2/0Jh+pm3lQbvPhIWHd1YQpoxPKPW/vsDNGBaCnMKsZbz29RjgCoXKugAjyagPncgdEw==", "dev": true, "requires": { - "ejs": "^2.6.1", + "ejs": "^3.1.6", + "json5": "^2.2.0", "magic-string": "^0.25.0" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } } }, "@types/color-name": { @@ -405,6 +417,12 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1597,10 +1615,13 @@ } }, "ejs": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", - "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", - "dev": true + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "dev": true, + "requires": { + "jake": "^10.6.1" + } }, "electron-to-chromium": { "version": "1.3.538", @@ -1797,6 +1818,15 @@ "integrity": "sha512-na2cwntTVgMsR+BZ2YBr/XQk941DKDw2LJKbV7g6TRdGBQ3rx8V53oEviG8zPWoBOySwK9w/SlZ/gb/F/48I8A==", "dev": true }, + "filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2306,6 +2336,70 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "dev": true, + "requires": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "jest-worker": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", diff --git a/package.json b/package.json index ac4631a1..8d23cbc4 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-node-resolve": "^11.1.0", "@rollup/plugin-replace": "^2.3.4", - "@surma/rollup-plugin-off-main-thread": "^1.4.2", + "@surma/rollup-plugin-off-main-thread": "^2.2.1", "@types/dedent": "^0.7.0", "@types/mime-types": "^2.1.0", "@types/node": "^14.14.7", diff --git a/rollup.config.js b/rollup.config.js index 9d5026a0..37d3865b 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -37,13 +37,6 @@ function resolveFileUrl({ fileName }) { return JSON.stringify(fileName.replace(/^static\//, '/')); } -// With AMD output, Rollup always uses document.baseURI, which breaks in workers. -// This fixes it: -function resolveImportMeta(property, { chunkId }) { - if (property !== 'url') return; - return `new URL(${resolveFileUrl({ fileName: chunkId })}, location).href`; -} - const dir = '.tmp/build'; const staticPath = 'static/c/[name]-[hash][extname]'; const jsPath = staticPath.replace('[extname]', '.js'); @@ -62,6 +55,7 @@ export default async function ({ watch }) { path.join(__dirname, 'lib', 'omt.ejs'), 'utf-8', ); + await del('.tmp/build'); const isProduction = !watch; @@ -83,7 +77,7 @@ export default async function ({ watch }) { ]), urlPlugin(), dataURLPlugin(), - cssPlugin(resolveFileUrl), + cssPlugin(), ]; return { @@ -105,12 +99,12 @@ export default async function ({ watch }) { }, preserveModules: true, plugins: [ - { resolveFileUrl, resolveImportMeta }, + { resolveFileUrl }, clientBundlePlugin( { external: ['worker_threads'], plugins: [ - { resolveFileUrl, resolveImportMeta }, + { resolveFileUrl }, OMT({ loader: await omtLoaderPromise }), serviceWorkerPlugin({ output: 'static/serviceworker.js', diff --git a/src/features/encoders/oxiPNG/worker/oxipngEncode.ts b/src/features/encoders/oxiPNG/worker/oxipngEncode.ts index 43807b48..c936c382 100644 --- a/src/features/encoders/oxiPNG/worker/oxipngEncode.ts +++ b/src/features/encoders/oxiPNG/worker/oxipngEncode.ts @@ -14,54 +14,17 @@ import initOxiWasmST, { optimise as optimiseST, } from 'codecs/oxipng/pkg/squoosh_oxipng'; import initOxiWasmMT, { - worker_initializer, - start_main_thread, + initThreadPool, optimise as optimiseMT, } from 'codecs/oxipng/pkg-parallel/squoosh_oxipng'; import oxiWasmUrlST from 'url:codecs/oxipng/pkg/squoosh_oxipng_bg.wasm'; import oxiWasmUrlMT from 'url:codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm'; import { EncodeOptions } from '../shared/meta'; import { threads } from 'wasm-feature-detect'; -import workerURL from 'omt:./sub-worker'; -import type { WorkerInit } from './sub-worker'; - -function initWorker(worker: Worker, workerInit: WorkerInit) { - return new Promise((resolve) => { - worker.postMessage(workerInit); - worker.addEventListener('message', () => resolve(), { once: true }); - }); -} async function initMT() { - const num = navigator.hardwareConcurrency; - - // First, let browser fetch and spawn Workers for our pool in the background. - // This is fairly expensive, so we want to start it as early as possible. - const workers = Array.from({ length: num }, () => new Worker(workerURL)); - - // Meanwhile, asynchronously compile, instantiate and initialise Wasm on our main thread. await initOxiWasmMT(oxiWasmUrlMT); - - // Get module+memory from the Wasm instance. - // - // Ideally we wouldn't go via Wasm bindings here, since both are just JS variables, but memory is - // currently not exposed on the Wasm instance correctly by wasm-bindgen. - const workerInit: WorkerInit = worker_initializer(num); - - // Once done, we want to send module+memory to each Worker so that they instantiate Wasm too. - // While doing so, we need to wait for Workers to acknowledge that they have received our message. - // Ideally this shouldn't be necessary, but Chromium currently doesn't conform to the spec: - // https://bugs.chromium.org/p/chromium/issues/detail?id=1075645 - // - // If we didn't do this ping-pong game, the `start_main_thread` below would block the current - // thread on an atomic before even *sending* the `postMessage` containing memory, - // so Workers would never be able to unblock us back. - await Promise.all(workers.map((worker) => initWorker(worker, workerInit))); - - // Finally, instantiate rayon pool - this will use shared Wasm memory to send tasks to the - // Workers and then block until they're all ready. - start_main_thread(); - + await initThreadPool(navigator.hardwareConcurrency); return optimiseMT; } @@ -77,7 +40,7 @@ export default async function encode( options: EncodeOptions, ): Promise { if (!wasmReady) { - wasmReady = (await threads()) ? initMT() : initST(); + wasmReady = threads().then((hasThreads: boolean) => hasThreads ? initMT() : initST()); } const optimise = await wasmReady; diff --git a/src/features/encoders/oxiPNG/worker/sub-worker/index.ts b/src/features/encoders/oxiPNG/worker/sub-worker/index.ts deleted file mode 100644 index 212e81b9..00000000 --- a/src/features/encoders/oxiPNG/worker/sub-worker/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import initOxiPNG, { - start_worker_thread, -} from 'codecs/oxipng/pkg-parallel/squoosh_oxipng'; - -export type WorkerInit = [WebAssembly.Module, WebAssembly.Memory]; - -addEventListener( - 'message', - async (event) => { - // Tell the "main" thread that we've received the message. - // - // At this point, the "main" thread can run Wasm that - // will synchronously block waiting on other atomics. - // - // Note that we don't need to wait for Wasm instantiation here - it's - // better to start main thread as early as possible, and then it blocks - // on a shared atomic anyway until Worker is fully ready. - // @ts-ignore - postMessage(null); - - await initOxiPNG(...(event.data as WorkerInit)); - start_worker_thread(); - }, - { once: true }, -); diff --git a/src/sw/to-cache.ts b/src/sw/to-cache.ts index 72adfc2f..cbc922f5 100644 --- a/src/sw/to-cache.ts +++ b/src/sw/to-cache.ts @@ -85,7 +85,6 @@ import jxlEncWasm from 'url:codecs/jxl/enc/jxl_enc.wasm'; import * as jxlEnc from 'entry-data:codecs/jxl/enc/jxl_enc'; // OXI -import * as oxiMtWorker from 'entry-data:features/encoders/oxiPNG/worker/sub-worker'; import oxiMtWasm from 'url:codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm'; import oxiWasm from 'url:codecs/oxipng/pkg/squoosh_oxipng_bg.wasm'; @@ -176,7 +175,7 @@ export const theRest = (async () => { // OXI if (supportsThreads) { - items.push(oxiMtWorker.main, ...oxiMtWorker.deps, oxiMtWasm); + items.push(oxiMtWasm); } else { items.push(oxiWasm); } diff --git a/worker-tsconfig.json b/worker-tsconfig.json index 1fdcc912..b605e757 100644 --- a/worker-tsconfig.json +++ b/worker-tsconfig.json @@ -5,7 +5,6 @@ }, "include": [ "src/features/**/worker/**/*", - "src/features/**/sub-worker/**/*", "src/features/**/shared/**/*", "src/features/worker-utils/**/*", "src/features-worker/**/*",