More work to investigate and optimize.

Try generating DOM via string manipulation instead of node
manipulation: no change since this isn't bottleneck, still 250~ ms.
Try pure JavaScript code for just substring filtering: 100~ ms.
Try pure JavaScript code for just substring filtering with string
array: 10~ ms.
Use preprocessed structs instead of DOM nodes in Go version.

Go back to slower strings.Contains rather than indexOf, but still go
from 250-350 ms to 80-100 ms iteration time.
Try full experience performance with latest change.

Startup time suffers (can be factored out), but after that it's much
better and quite usable.