Regarding "time to respond".
SPI is best suited for asynchronous payloads, by that I mean the data flowing in opposite directions have no time relation to each other. This rules out classic command - response mindset. For example: setpoints run the other way, measurements the other.
If and when you need command - response functionality (for example: "command: read register 123", "response: value of register 123 is 42"), which SPI really isn't the best for, there are two classic ways to achieve this:
1) Quick data generation in the middle SCK clock cycles. Example: first byte as transmitted on MOSI defines a command, for example 0x85 means "read register 5". MISO bits during this first byte are meaningless and ignored. After 8 SCLK cycles, slave quickly accesses register 5 and outputs it during the rest of the SCK cycles.
2) Response is to the previous command. When master generates SCK cycles, the slave immediately responds with data. But this response is to the previous command. While slave responds, master gives bits of the new command. Once the transmission is complete (e.g., nCS goes inactive, or just right amount of cycles), slave can process the command so that the response will be ready for the next transaction.
With 1), datasheet has to specify maximum SCLK frequency so that data generation can fit in that tiny time slot available after fully receiving the command bytes. There is extra overhead for having to transmit dummy bits on MISO. A variation to give more time is to add dummy bits; for example, make the command fully defined with 6 first bits, and then you have 2 bit time slots to process the command before the reply has to start.
With 2), datasheet has to specify minimum nCS inactive period. 2 allows more time to process the command, and incurs less overhead if readout is going on all the time, in predictable pattern. On the other hand, if one does random accesses every now and then but needs the reply "immediately", then each read requires two full transactions.
But whenever possible, try if you can use the "data not related in time" pattern. I think this could work with an UI. If the UI processor itself chooses what data to show, then you surely just supply all possible data to it, so data does not change when buttons are pressed.