Limit And Cache Callback Targets
For convenience, PUN callbacks can be implemented in any MonoBehaviour, on any GameObject and without registering any. Often that's not a problem, as these callbacks are infrequent (except maybe Custom Property updates).
SendMessage is used to dispatch callbacks and that can affect your performance.
Probably even worse,
FindObjectsOfType() is needed to find the components, which may (or may not) implement the callbacks.
PhotonNetwork.SendMonoMessageTargets, you can define which GameObjects get called at all.
PhotonNetwork.CacheSendMonoMessageTargets(Type t), you can setup the SendMonoMessageTargets by defining which type of Component should be the target.
You can update the SendMonoMessageTargets as needed. Anything will be quicker than the default brute-force approach.
OnPhotonSerializeView And IPunObservable
When a PhotonView observes scripts,
OnPhotonSerializeView gets called multiple times per second.
By default, a PhotonView uses reflection and caching to find and Invoke the
OnPhotonSerializeView implementations on components.
You can optimize calls of
OnPhotonSerializeView by implementing the interface
IPunObservable with your MonoBehaviours.
Cache RPC Targets
In some cases, you might use a lot of RPCs in your game. Any Component on the target GameObject may implement RPCs, so PUN will use reflection to find the fitting methods. Of course, this is expensive and even wasteful, if the components don't change.
By default, PUN caches a MethodInfo list per Type of script. It does not cache which MonoBehaviours are on the GameObject as potential target.
You can set
PhotonNetwork.UseRpcMonoBehaviourCache = true, to cache the MonoBehaviours per PhotonView for RPCs.
This speeds up finding the components to call.
Should the scripts on a GameObject change, call
photonView.RefreshRpcMonoBehaviourCache() to update as needed.
Avoiding Local Lag For RaiseEvent
When you call RaiseEvent, the data is not written to the socket immediately but instead it's queued until
SendOutgoingCommands() gets called.
This way, Photon aggregates messages into fewer datagrams and saves traffic.
To avoid the local lag, simply make RaiseEvent into a trigger to call
SendOutgoingCommands() in a
Doing this on demand is fully OK.