I don’t have the answer to your question, so I apologize if this is going off on a tangent.
The most efficient way to renders large amounts of geometry is to bypass p5 or Processing and go direct to webgl / opengl using shaders. As an example, https://infinitefunspace.com/p5/ball/ animates 100,000 spheres without storing or passing any data between the CPU and GPU. Each sphere is ray-traced by the fragment shader onto a single triangle whose position and size are computed deterministically in the vertex shader based on the gl_VertexID. You can see the source at https://infinitefunspace.com/p5/ball/p5Ball.js.
If you need to position the geometry explicitly computed on the CPU, typically in opengl/webgl, you would pass positions to the GPU using vertex buffer objects which are a bit of pain to set up and can conflict with p5 or Processing. An alternative is to pass data to the GPU through textures. p5 makes this a bit easier using floating-point framebuffers. I have several p5 examples at https://openprocessing.org/user/465377?view=sketches that also use shaders to compute the positions of the particles.