I was inspired by this to create my own a few months ago. It uses a quadtree to optimize nearest neighbor lookup to ideally reduce complexity from n^2 to nlogn on each tick.
http://jrhdoty.github.io/SwarmJS/
I had run in to some performance issues, the initial few ticks are quiet slow even now, esp. on a phone.
This one uses a kdtree instead. I'll have to try quadtree and benchmark. Thanks.
If what you actually want to do is to have each boid be affected by each boid in a fixed-size neighbourhood, the best acceleration structure is actually just fixed-size bins.
All of a boid's "close enough" neighbours will be found in the 8-neighbourhood of its block.
Feels a good idea. Have to try it to know for sure.
Also instead of a square shaped range you can get a hexagonal range by dividing corner boxes diagonally to two and then checking which half of square the boid is. :)