Just some random ideas in case further optimization of the list view code is needed. I'm sure you've likely considered many of these, but spitballing in case there's anything new.
In generally, when retreiving a large list, it would be common to do lazy/progressive reads rather than reading the entire list into memory. The user can only see the first 'X' records (songs in this case) so pulling the rest of the list into memory can be wasteful and delay disaplying the initial view of the list.
The problem I can see with that approach here is that people will then want to find a song in their list by using filters, so you need a way to have that work right from the outset. You can't have filters only working on a subset of the Songs list, and returning a subset (i.e. inaccurate) of matches.
Can we choose to not read ALL of the Song's attributes (e.g. Notes to me would be a big one, but also anything else that is costly on read time/CPU?). This might be more effective if the discussed toggles on what Song attirbutes are visible in the Songs list (I think you said a max. of 3?). Then you could choose to not read the other attirbutes UNLESS a search is done on one of the non-default displayed fields?
As I said, just throwing ideas out there in case anything helps!