Skip to content

Commit 8c6ff65

Browse files
committed
Optimize asset loading & caching
only fetch each resource from the network once, and only compile each wasm module once
1 parent ad0162f commit 8c6ff65

File tree

3 files changed

+46
-24
lines changed

3 files changed

+46
-24
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "faust-loader",
3-
"version": "1.1.1",
3+
"version": "1.2.0",
44
"main": "dist/faustLoader.js",
55
"types": "dist/faustLoader.d.ts",
66
"scripts": {

src/loadProcessor.ts

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,39 @@ function heap2Str(buf: Uint8Array) {
1010
return str;
1111
}
1212

13-
const loadedProcessors: string[] = [];
13+
const processorModules: Record<string, Promise<void>> = {};
14+
async function loadProcessorModule(context: IAudioContext, url: string) {
15+
if (!context.audioWorklet) {
16+
console.error(
17+
"Error loading FaustAudioProcessorNode: standardized-audio-context AudioWorklet isn't supported in this environment."
18+
);
19+
return null;
20+
}
21+
22+
const existing = processorModules[url];
23+
24+
if (existing) {
25+
return existing;
26+
}
27+
28+
processorModules[url] = context.audioWorklet.addModule(url);
29+
return processorModules[url];
30+
}
31+
32+
const wasmModules: Record<string, Promise<WebAssembly.Module>> = {};
33+
async function getWasmModule(url: string) {
34+
const existing = wasmModules[url];
35+
36+
if (existing) {
37+
return existing;
38+
}
39+
40+
wasmModules[url] = fetch(url)
41+
.then((response) => response.arrayBuffer())
42+
.then((dspBuffer) => WebAssembly.compile(dspBuffer));
43+
return wasmModules[url];
44+
}
45+
1446
const importObject = {
1547
env: {
1648
memoryBase: 0,
@@ -81,32 +113,19 @@ export default async function loadProcessor(
81113
baseURL: string
82114
) {
83115
const cleanedBaseURL = baseURL.endsWith("/") ? baseURL : `${baseURL}/`;
84-
// Load DSP wasm
85-
const dspFile = await fetch(`${cleanedBaseURL}${name}.wasm`);
86-
const dspBuffer = await dspFile.arrayBuffer();
87-
const dspModule = await WebAssembly.compile(dspBuffer);
116+
117+
const [dspModule] = await Promise.all([
118+
getWasmModule(`${cleanedBaseURL}${name}.wasm`),
119+
loadProcessorModule(context, `${cleanedBaseURL}${name}-processor.js`),
120+
]);
121+
88122
const dspInstance = await WebAssembly.instantiate(dspModule, importObject);
89123

90124
const HEAPU8 = new Uint8Array(dspInstance.exports.memory.buffer);
91125
const json = heap2Str(HEAPU8);
92126
const json_object = JSON.parse(json);
93127
const processorOptions = { wasm_module: dspModule, json: json };
94128

95-
if (!context.audioWorklet) {
96-
console.error(
97-
"Error loading FaustAudioProcessorNode: standardized-audio-context AudioWorklet isn't supported in this environment."
98-
);
99-
return null;
100-
}
101-
102-
// Load processor script, if necessary
103-
if (!loadedProcessors.includes(name)) {
104-
await context.audioWorklet.addModule(
105-
`${cleanedBaseURL}${name}-processor.js`
106-
);
107-
loadedProcessors.push(name);
108-
}
109-
110129
const nodeOptions = {
111130
numberOfInputs: parseInt(json_object.inputs) > 0 ? 1 : 0,
112131
numberOfOutputs: parseInt(json_object.outputs) > 0 ? 1 : 0,

test/index.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { AudioContext } from "standardized-audio-context";
22
import createCompressor from "./Compressor.dsp";
33

44
const ctx = new AudioContext();
5-
createCompressor(ctx).then((node) => {
6-
console.log(node);
7-
console.log(node.getParams());
5+
Promise.all([
6+
createCompressor(ctx),
7+
createCompressor(ctx),
8+
createCompressor(ctx),
9+
]).then((nodes) => {
10+
console.log(nodes);
811
});

0 commit comments

Comments
 (0)