Pre-fetch anticipated file based on user interaction in MR file-by-file mode
Context
We expect to ship a lower-bandwidth, network- and CPU-friendly enhancement to merge request file-by-file mode very soon.
In this mode, only the single file that needs to display will be loaded.
Problem
While this is quite fast (much faster than loading - potentially - many batches of files until the proper one is included), it still means that every time a user clicks (or uses the keyboard to trigger) the next or previous buttons or interacts with the file tree a short load interrupts them.
Proposal
Since it's only one file (or potentially 2, based on implementation), it would be a nice UX improvement to pre-load files before a click / keyboard activation.
Detail
There are multiple instances when we could pre-load files:
- A user hovers the (non-disabled) "Next" button in File-by-file mode
- A user hovers the (non-disabled) "Previous" button in File-by-file mode
- A user hovers over an entry (file name) in the file tree
- A user uses keyboard navigation to focus any of those elements
- This may be exceptionally difficult for the file tree, since it doesn't appear to have keyboard navigation enabled, and even if it did, the "typical" interaction would likely be to cycle focus through each element - listening for a reader to announce the file title - and then moving on. Pre-loading on focus would then load every single file for keyboard users of the file tree.
Caveats
When pre-loading files, there is a new intermediate state to be concerned with.
In the current setup, a fetch doesn't occur until the user has clearly indicated they want it (they are on a URL that requires that file). If we begin pre-loading, we'll need to add a state indicator to the data representation of the file (diffFilesMeta
) that indicates it is actively being loaded, so that the eventual navigation to the full URL doesn't trigger a second eager fetch.
However, this also means that UI loading states will need to be based on the network load status of the file when the page displays (versus when the Vuex action is triggered, as it works now).
That is, a pre-loading file can't replace the UI with spinners, but the current implementation does that (because the user has already landed on the page, but the file isn't there).
However, if the user navigates to the the item they're hovering over, the already running pre-load should cause spinners to appear as if a load just started.
Availability and Testing
Regression testing, please make sure MR-related E2E tests in e2e:package-and-test
job are passing. To ensure this job is triggered please add the pipeline:run-all-e2e label to the MR.