Just to take a step back and look at the "big picture" here, all of the problems you're likely to face are from the hardware running much too fast, rather than not fast enough. I know this may seem strange if you're coming from the world of ordinary 8 bit AVR & Arduino, but we see it over and over on this forum. With Teensy at 180 or 600 MHz, too much speed becomes the common problem. These problems are especially troublesome when people connect a lot of buttons in a row-column matrix and roll their own code rather than using the Keypad library, or connect lots of analog inputs through analog mux chips. Code running at this speed can easily outpace the electrical requirements.
All of these ways are so much faster than humans can pretty and release a button. Even I2C at only 100 kHz is more than enough.
If your code will sit and wait for the I/O, then SPI is the way to go, not because you need this speed to avoid missing anything, but because it will minimize the "wasted" time waiting which you could use for other things (or go into idle mode to save power). On Teensy 4, both bitbang and hardware SPI are capable of speeds which are (probably) much too fast for the sort of wiring you're likely to use for connecting several shift register chips. Really high frequencies, like over 15 MHz, require careful attention to wiring and grounding if the wires are long. Probably the best way is shiftIn(), and use pinMode() to configure the pins so they get the default slew rate limiting. It slows the signal by only nanoseconds, but that makes a huge improvement in the high frequency noise effects you can get with high speed SPI over long wires!
The other very common problem is mechanical chatter. Normally the Bounce library is used with buttons connected directly to pins. If your code scans the shift register very rapidly, you will need to do something similar to the Bounce library.