I'm seeing more and more ways as I learn where functions can be run on the client side. I'm looking at events. Does the Ethereum client (say, Metamask) load all the events from a contract when I open the app on a webpage? Is that what events are mostly for?
This depends on the app you're talking about, but it probably isn't loading every event that has been emitted -- just the last few. Loading one page at a time keeps things efficient. That said, there are many uses for events.
One of the big ones is getting "return" values from a transaction out to a client. If you look over the web3 spec for
send(), you'll notice that there's no mention of the return value. This is because
web3 can't know how long it will take for the transaction to be confirmed. The
call() function provides a return value from the function because it is only used with
pure functions that don't require a transaction.
If you did want to return a value from your state-modifying function, you could call an event at the end of it and then subscribe to that event. Whenever the transaction representing your call is confirmed, that event will appear in your subscription, providing your return value and letting you know your call completed.