function
function3mo ago

Stream a Sharp object / Node Readable with Deno.serve()

This works but isn't quite as fast as piping to the response object of node:http's createServer. Can i somehow pipe the Sharp object directly to the response without writing my own ReadableStream?
import sharp from "npm:sharp";

Deno.serve(() => {
const thing = sharp("img.png").webp(); // 'thing' implements node:streams/Duplex

const body = new ReadableStream({
start(controller) {
thing.on("data", (chunk) => controller.enqueue(chunk));
thing.on("end", () => controller.close());
},
});

return new Response(body);
});
import sharp from "npm:sharp";

Deno.serve(() => {
const thing = sharp("img.png").webp(); // 'thing' implements node:streams/Duplex

const body = new ReadableStream({
start(controller) {
thing.on("data", (chunk) => controller.enqueue(chunk));
thing.on("end", () => controller.close());
},
});

return new Response(body);
});
(Note: cancel() and headers omitted for brevity)
2 Replies
function
functionOP3mo ago
This also sort of works but is actually crazy slow, like ~3x (always loading a 20MB image on purpose to exaggerate performance differences):
import { Readable } from "node:stream";
import sharp from "npm:sharp";

Deno.serve(() => {
const thing = sharp("img.png").webp();

return new Response(Readable.toWeb(thing));
});
import { Readable } from "node:stream";
import sharp from "npm:sharp";

Deno.serve(() => {
const thing = sharp("img.png").webp();

return new Response(Readable.toWeb(thing));
});
toWeb was added in Node v17 and is still marked as experimental
bartlomieju
bartlomieju3mo ago
Opening an issue on GitHub would be useful to see if we can squeeze more performance.

Did you find this page helpful?