Timeago setup and rendering causes performance issues on large MRs

One of the stated intents of the jquery timeago library we use is: "As time passes, the timestamps will automatically update." This, in addition to timeago element setup, is causing performance problems for pages with large number of timeago elements.

For example, on a large discussion MR's initial render, we do the following:

Stage 1 (timeago element setup):

  • Select and Jquery-ize ($(el)) 549 elements
  • Iterate over all 549 with $.filter
  • Iterate over all 549 again with $.each
  • Call $.tooltip on all 549 (which Jquery-izes each of them again)

Stage 2 (timeago element rendering):

  • Call gl.utils.renderTimeago($el) on all 549 elements

    • this instantiates a new timeago object and executes its render function
      • this defines a function doRender
        • this renders the timeago value and sets a timeout to call doRender in a period of time relative to the actual timeago value
      • eventually, the timeout calls doRender again, which sets another timeout....
      • ... infinite loop of timeago rendering
  • After this, Stage 1 is run again, for 800+ elements

  • After this, Stage 1 is sometimes run again, for 200+ elements

  • Stage 1 is re-run anytime a new comment is created, for 800+ elements

It's difficult to tell whether Stage 1 or Stage 2 is the bigger performance drain, although Stage 2 is what keeps the drain alive. We can get away with this on smaller MRs/Issues because the timeout values (in ms) can often be large. I don't have a plan to address this yet -- just wanted to document what I've found before I sign off for the day 😅