What I have in mind is the following:
1. Every time Emacs processes :eval construct it (a) measures the time
taken; (b) caches return value.
The total mode line render time is also recorded.
2. If the total render time exceeds configurable threshold, processing
the most time-consuming :eval constructs will be suspended until
"debounce" time since the last full processing.
By "suspended", I mean that cached :eval value is reused instead of
invoking :eval again. Possibly, not reused verbatim, but by replacing
the cached value with some kind of placeholder that has the same
total height/width as the cached value.
For example, consider :eval segment invoking external git command and
producing branch name: "⛬ master".
If that command takes too long, Emacs will display
"⏳ " instead of
"⛬ master", until the mode-line redisplay that is some fixed time
ahead.
3. After "debounce" time since the last "suspend", all the :eval are
processed in full again, generating up-to-date mode-line.