You can use update=false and batch update them.
A generation is a monotonically increasing number which is stored in every watch and marks when it was last updated. You can then do some comparisons to see if this watch has been updated in this update request. This won't be very reliable probably.
Another option is probably requestion updates per window, which will probably be faster, if there are tabs and some windows behind other windows.
So every debug window will have some unique id and every element (watch in this case) in it is associated with this id, so when an update request is made, this id is passed to it and only elements matching the id are updated.
Unfortunately this prevents showing the same element in multiple different views. But I'm not sure if this is something which will be useful.
Or I guess we could add a field in the event object which designates what is the reason for the update.
For watches it makes sense to show differences only if the reason for the update is a change in "active frame".
If the user requests an update using the context menu or because it has just added the watch then I'm not sure it makes sense to show the diff.
Hm, lots of options, probably the last one seems most useful...
p.s. the address of the current frame could be stored in the watch object, too, so it might be used to do comparisons.
p.p.s. I guess I could think of more variants to solve this the more I think about it

p.p.p.s. You don't need to store the watches in the event object, you could store it in the debugger plugin and provide an API. Something like GetListOfLastUpdatedWatches()...