What I'm doing
I'm working on an algorithm reactive diffusion which requires per pixel manipulation on canvas. Following the coding train instructional video:
A few changes
Instead of following to the letter I am making a few changes such as either to reduce jank or to speed up time to render, after all this canvas will be surrounded by UI eventually.
- Not using P5.js (I want to learn)
- OffscreenCanvas worker
- Disabled transparency in 2D context
- Using Parallel.js for inline workers.
- Creating the image data directly with ImageData constructor
- Convert image data to Unit32Array as described https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/
My (un?)realistic requirements
As you can see this is an excersize in performance as well as a pretty animation.
I know that I would love the ability to render full size of the screen of up to 27 inches without much of a wait, sub 1 second would be outstanding. Even a little flash would be fine.
The rules
- No fancy ES6 array methods (perf reasons)
- use ye olde for loop
- keep optimizing
- Use workers to take strain off main thread
- post processing may be an option (CSS)
Getting started
So I know I need a multidimensional array representing X and Y axis, each item in the Y axis will likely be an Object literal with contains information on how to transform the px that it represents, 450,255=red
you get the idea.
So I figured, might as well use a Map of Maps instead of arrays, that's probably going to result in understandable code. They are apparently faster than arrays too, so each map is a 0 indexed wrapper containing objects.
This is actually pretty slow to create (WxH)n Maps so I thought, let's get this into a worker and figure out what to do from here... > 10 seconds to run using Parallel.js 😱, it seems much faster in the main thread < 2s so I'm a bit stuck, what am I doing wrong, is newing up a map that expensive?!
From here
Your comments will be really helpful!
I'm also going to look into using wasm for this bit as have had some fun before with emscripten.
Also, am I mad doing this in 2D context should I just go webgl, learn it and stop moaning?
Should I tile the canvas somehow or even use CSS box reflect and render just half the size?
Tell me what you think, and share your tips on intensive jobs in JavaScript. 🥳