Bottom line is:
you don't want your system to swap at all. A system that constantly needs swap has too little RAM for its workload. Swap is designed to mitigate rare and temporary situations of memory pressure without having to kill processes immediately.
The major problem with swapping has always been the abysmal performance. Of course, this is
much better on modern NVMe drives (to the extent of providing acceptable performance depending on the workload), but even with them, there's a remarkable slowdown compared to direct RAM access. This is also the reason why having too much swap might be bad. In a situation when every memory access will trigger a page fault, the system might become too slow to be usable at all, so the OOM killer suddenly looks nicer
Now, imagine you were running out of memory without any swap: The OOM killer would have to pick some process to kill, so your system will be unstable. Swap avoids that. Do you really want to slow that down, just to protect yourself from the unlikely case of some error that could corrupt the temporarily swapped pages? Even pages in physical RAM
can become corrupted. ECC RAM is a way to (somewhat) protect against that.
There's also a technical reason to avoid any additional software layers below your swap areas: If this code has to dynamically allocate memory, you could run into a deadlock (halting the whole system immediately) when there's too little physical RAM available to satisfy that allocation. I learned this can even happen with GELI, so on my server, I disabled GELI for swap after running into a deadlock (for a
very few times). It's discouraged to place swap on top of ZFS for such reasons.
---
Disclaimer: There are very specific workloads for which what I wrote isn't true. One example is a heavy multiuser system with many interactive tasks (of different users) that are idle most of the time. For such a system, it makes sense to use a lot of swap for storing the working set of the idle tasks. Another example would be running an application that is itself optimized for swap usage.