I have a project that uses 2 MCP23017 chips over I2C (for a total of 32 extra GPIOs). They are used for both input and output and I make use of the interrupt pins for input alerts (rather than constant polling). That same project also has 32 8-bit shift registers controlled through some of the MCP23017 pins.
They have worked flawlessly for me with a Photon. In fact, the thing has been running a simulation for about 5 months now that involves sending around 40,000 bits per second down the shift register chain and have had no issues.
On a side note, you can get the chips cheaper from an electronics distributor, for example: http://www.mouser.com/Search/ProductDetail.aspx?R=MCP23017-E%2FSPvirtualkey57940000virtualkey579-MCP23017-E%2FSP
One thing I’d be wary of is using over I2C is make sure you don’t have any other I2C devices that require a slower I2C bus (at first I had an I2C LED that was supposed to work at 100k, but had to slow the I2C bus down to 70k for it to be reliable). I ended up throwing that thing away and writing my own LED driver with the MCP23017 pins which eliminated the I2C bus speed bottleneck (your I2C bus speed is global, not a per device basis, so you have to set it to the speed of the slowest device on the bus). So now I have I2C running at 400k.