If awk reads all the input, it does not encounter the buffering issue. It can therefore selectively pipe everything after the header to sort via an awk pipe.
df | awk 'NR == 1 { print; next; } /^.dev/ { print | "sort"; }'
I don't have much shm, but I like to report my partitions in sequence, likewise ps output.
Wordy, but maybe worth declaring as a function in .bashrc.
In fact, bash reads lines without buffering, so something like this works too:
df | { read -r Hdr; printf '%s\n' "$Hdr"; grep '^.dev' | sort; }