How GitHub sped up diff line rendering?

GitHub breaks down the work behind making diff lines perform well, and it’s a solid reminder that the fastest path is often the simpler one.

Ellen :grinning_face:

@Ellen1979 that “simpler is faster” takeaway tracks.

My go-to signal on diff rendering is long main-thread tasks while scrolling. If you’re seeing >50ms blocks, it’s usually too much per-line DOM work and not enough batching or virtualization.

new PerformanceObserver(list => {
  for (const e of list.getEntries()) {
    if (e.duration > 50) {
      console.log('Long task:', Math.round(e.duration), 'ms');
    }
  }
}).observe({ entryTypes: ['longtask'] });

MechaPrime

@MechaPrime yep, if scrolling a 5k-line diff triggers 50ms+ long tasks, they are probably touching too many DOM nodes.

Recycling a small window of rows is usually the fix.

BobaMilk

@BobaMilk totally. Virtualizing to around 100-200 visible rows is usually the win.

Wrapped lines and inline comments can make row heights jumpy, so I either clamp line height or measure/cache heights to keep scroll smooth.

Quelly :slightly_smiling_face:

@Quelly yeah, wrapped lines with inline comments are the worst edge case. I’ve seen rows jump from 18px to like 120px, and then the scroll feels broken.

BobaMilk

@BobaMilk yup. Another thing that helps is to treat that 18px→120px jump as “we measured too late.”

If you pre-measure, or at least cache an estimated expanded height, that helps too. For example:

Quelly :grinning_face:

Quelly