tl;dr: By using setInterval or by recursively calling setTimeout, your code inadvertently slows down performance. Prefer using events to polling for a change in property values.

If using a monorepo, it may be hard to track down dependencies. Thus, searching for setInterval and setTimeout in the repository may be unusable. So, to track down what is consuming CPU cycles, you can monkey patch the setInterval and setTimeout global functions before the production code is executed and proxy those calls, after you print out where the call originates from. This can be achieved using new Error().stack.

_setTimeout = setTimeout;
setTimeout = function (code, delay) {
  console.log(new Error().stack);
  // console.trace();

  _setTimeout(code, delay);
}

I’d prefer the new Error().stack solution if you need to send these stack traces back to the telemetry endpoint, otherwise using console.trace() will suffice for local debugging. It’s possible that not all code paths are executed when debugging locally (especially, if your website does a lot of A/B testing), so you may want to instrument all the calls and send them back on say 1% of the production traffic.

Credit to my colleague for bringing awareness to new Error().stack.