I'm certain it's not a soldering issue. It's looking like my tests were massively swayed by using my development Pi 3 rather than a Zero.
Testing the same SD card across the Pi 3, Model B+, Model A+ and Pi Zero W reveals that, in my VLC Radio setup at least, only the Pi 3 can keep up with station changes and successfully switch from one audio source to another without a really obnoxious cracking sound.
This seems to be related to CPU- since the Pi 3 is a great deal faster than the other Pi's, and VLCs average CPU usage is quite significantly lower. These tests were conducted with the same SD card, the same board (pHAT BEAT in this case), the same speaker, and the same power supply. Invariably the Pi 3 fared much, much better.
I'm not entirely sure why a loaded/slower CPU causes a pop/crack, but I suspect it's something to do with the DAC being spun up before any audio data is prepared. It could also be a minor difference between the regular and the -v7+ kernels/modules but I doubt it.
Using Pulse seems to be the only tenable solution. It even sort-of fixes my VLC setup on the Pi Zero W, but introduces a slew of problems of its own, since the poor old Pi Zero just can't keep up with the CPU demand of both VLC and Pulse Audio. sigh (although I'm making inroads with some careful tuning of both VLC and Pulse Audios config files)
But, I digress, the problem is that the Pi Zero is just too weedy to keep up with whatever the audio stack is doing when it spins up/down. Of course, this would suggest a real software fix is possible, because ALSA sure as heck shouldn't be spinning up the i2s clock without some real data ready to output.
For now, Pulse Audio is my canonical solution where there's enough CPU overhead for it to run properly, but I do appreciate it can vary from ~4% to ~50% with conservative settings on a Pi Zero.
In my experience Pulse seems to start/stop itself gracefully- all my tests have been conducted headless, connecting via SSH. I'm guessing your problems might stem from running audio services that use their own user context, and cause chaos when their own local Pulse instance is fired up?
It looks like the TCP setup should do the trick in this regard, although it only adds to the configuration headache this stuff already is.
I think our default asound.conf, with Pi VU Meter stuff removed, would look like this:
But it wont prevent popping, since as explained above I was barking up the wrong (Pi 3) tree :(