There are many. Most do not apply here since you have low FPS which lowers the data rate. I2C enables clock stretching and addressing. Buffers could be used for I2C to enable length. I have seen 1.5M I2C in college. However that was with either 100/400kHz I2C.
I would recommend create packets, one for data and one for switch. However this may be better served with I2C address. Basically you would want to send data to each node. Then send a global command if possible for the buffer switch. Since the data updates could be slow you would want to make the update as smooth as possible.
Double buffering would enable this. SmartMatrix is memory mapped controller retrofitted onto non memory mapped panels. It should support a front and back buffer. Draw slowly into the back buffer then quickly switch all 30 SmartMatrix controllers instantly. Doing this in parallel via global command would be ideal. I2C general call may work. However I do not know much about the I2C hardware used in Teensy 3.2.
For higher FPS and broader support there is more to consider. I figured out that there are a few fundamental types of protocol. Each with there own ups and downs. I2C is not the fastest but should still work for very low FPS.
Here is an unfinished work which attempted to handle this: daveythacher/LED_Matrix_Controller (github.com). It was created to try to abstract LED Controllers whether on MCU, Pi, FPGA, etc. The notable features I was trying to add are support for PWM/MM LED drivers, different interfaces (CAN, Ethernet, I2C, SPI, UART, Bit bang, etc.), abstracting memory operations, and considering processor IO acceleration integration. Overall should provide large amount of flexibility for different levels of performance to cost. However some aspects are very simple while others are very complex.
So for reference this may be useful. However a lot of the design choices are a little hidden. I would not recommend using this for your application. Mostly cause it is not finished or tested. My version does not support global command/address. It would be easy to add. Addressing works differently with this as it assumes ring. Which would be strange for some protocols. This is useful for certain cases which do not apply for I2C.
Unless you use multiple I2C buses per controller. This could in theory limit the number of buffers required. However I am not sure about that. However if you lower the clock speed significantly maybe.