Programming and Software Development

How GitHub Rebuilt the Massive Pull Request Review Interface

GitHub explains how it rebuilt the pull request interface in the GitHub Copilot application to handle diffs exceeding one million lines and more than 400 inline comments. The solution separated the layout of predetermined code lines from dynamic comment blocks, using incremental measurement and correction that preserves the user’s position.

2026-09-23
6 min read
40 views
certi.news Editorial Team
How GitHub Rebuilt the Massive Pull Request Review Interface

GitHub rebuilt the pull request viewing interface in the GitHub Copilot application to handle an extreme case: a pull request containing 2,200 files, more than one million changed lines, and over 400 inline review comments. The goal was not merely to speed up rendering a large diff, but to keep scrolling and reviewing usable after the conversation itself adds variable dimensions to the document.

The traditional interface for large diffs relies on virtualization, meaning that only elements near the viewport are kept, while DOM elements are reused during scrolling. This model works relatively easily when every element is a code line with a known height. Comments, however, do not have this property; their height changes depending on Markdown wrapping, opening <details> sections, the appearance of the reply editor, images, suggested changes, and different interaction states.

Two Layout Systems Instead of One Height Table

GitHub kept a fixed layout for code lines, using precomputed position and height calculations and not rebuilding them when a comment changes. In contrast, it placed comments, reply editors, and dynamic blocks in a separate index. Each block has a stable key associated with the file, line, and side, in addition to a content fingerprint, the state of open sections, and the width from the latest measurement.

The measured height is used when measurements are valid, or a cached value when the fingerprint and width remain compatible; otherwise, the interface uses a temporary estimate. Thus, one comment expanding does not cause the layout of millions of lines to be recalculated.

Measurement Outside the Scrolling Path

GitHub abandoned an initial design that relied on an independent ResizeObserver for every block and wrote the measurement directly into the layout. This pattern can create a feedback loop, because changing the layout triggers observation again, and its cost also increases with the number of mounted blocks.

The design the company shipped uses a single measurement cycle tied to idle periods and the end of scrolling. Normally, only blocks within approximately 2,400 pixels of the viewport are measured, while distant blocks retain their estimates until they get closer. Measurements of visible elements are read in a batch to avoid repeated reflows.

The observers remain in place to detect changes such as an image loading or typing in the reply editor, but they mark the block so that the next measurement cycle reads it again, rather than modifying its height directly. The exception is a user-caused change in a visible block, such as opening a section or a reply editor; in that case, one synchronous correction can be applied in the same frame, preventing a visible step between the comment expanding and the code below it moving.

Correcting the Layout Without Losing the Reading Position

When the actual height differs from the estimate, the interface does not correct the position based on the number of pixels alone. It preserves the identity of the element the user is reading, whether a line or a comment block, and determines the offset within it, then applies the height differences and recalculates the position of that same element. This keeps the anchored element in approximately the same place.

Corrections are generally not made while the user is scrolling or during momentum scrolling, and changes resulting from content below the screen are not used to move the view. The team encountered a bug when programmatic scrolling caused by changing the panel width was treated as user scrolling, which caused the correction to be lost and the file being read to drift. This was addressed by separating user interaction from changes caused by the interface itself.

Data Pipeline and Automated Tests

Responsiveness does not rely on virtualization alone. The diff structure and file data are sent first so that the file tree and metadata can appear while the rest of the document loads, while tasks such as syntax highlighting and detailed Markdown construction are deferred until elements approach the viewport. The interface also temporarily retains the last few diffs used, evicting anything beyond that to reduce memory consumption.

To detect defects that appear only during deep scrolling, GitHub added permanent instrumentation and automated tests that monitor the number of mounted rows and blocks, frame time, the size of scroll corrections, observer leaks, and the presence of unfilled gaps. The team ran automated flows on the desktop application and under the actual rendering engine, with cases such as opening sections, activating reply editors, resizing the window, and navigating within a large file list.

Why Does This Design Matter?

The stated result is that a pull request with one million lines and hundreds of comments behaves like a normal pull request: comments are displayed in full instead of being clipped inside a nested scrollbar, expanding a section moves the code below it without random jumps, and returning to a pull request preserves the reading position. The most important engineering value is that GitHub did not try to make all content uniform; instead, it kept the deterministic portion fast and separated it from content whose size cannot be known before rendering.

Nevertheless, the material does not claim that all large pull requests have become easy to review in terms of comprehension or risk management. What it addressed was the performance and behavior of the viewing interface during measurement and change. The results are also tied to the GitHub Copilot application and its internal design, and do not provide independent figures for memory consumption or performance metrics across different devices and engines.

News source
c
Author

certi.news Editorial Team

In the same category

You may also like

View all news