Skip to content

Performance: Prefetch repository metadata and blob contents from search results (Experimental)

Warren Gifford requested to merge tr/prefetch-from-search into main

Created by: umpox

Note This PR is only partially complete. This is an experimental change that I have put together after thinking about this. Mainly looking for reviews on this as a concept!

Description

This PR adds preloading support to the search results pages:

Preload 1: Repository + revision metadata on scroll into view

With this change, we would preload this metadata when a result file|commit|repo is scrolled into view in the search results.

Why?: This query is required before we render anything on the repo/file pages. It typically takes 150ms minimum (generally all our GQL queries do), and noticeably slows down performance.

Risks of overfetching?:

  • Generally I would expect that most searches will return a smaller set of repository + revisions than actual results, which would be typical of an actual customer deployment (many results, fewer repositories).
  • We only fetch when the result is scrolled into view, so we wouldn't expect too many queries at once here.
  • We would likely see a larger volume of revision fetches on diff search, but I still wouldn't expect this to cause other performance issues, due to the reasons above and the fact that this query is generally quite small and fast.
  • Clicking a result will reuse the memoized observables even if they haven't resolved yet, so we wouldn't ever end up in a situation where we fetch the same data twice.

Preload 2: Plaintext file blob on hover of FileMatchChildren

With this change, we would preload a plaintext blob whenever this component is hovered.

Why?: This is the final query that takes a noticeable amount of time before a user actually gets to see the result of their intended action (clicking a file result). The requests can typically range from 150ms-1000ms.

Risks of overfetching?:

  • We only start fetching when a user hovers over the actual file match example in the results. We immediately stop fetching when a user hovers away from the specific result.
  • We only fetch plaintext blob information here, to mitigate any risks of fetching data that we won't need. Syntax highlighting is skipped, and only loaded when a file is actually clicked on.
  • Clicking a result will reuse the memoized observables even if they haven't resolved yet, so we wouldn't ever end up in a situation where we fetch the same data twice.

Demo

Before (Note how 2 and 3 results are quicker as the repo + revision fetch has already loaded)

https://user-images.githubusercontent.com/9516420/183442946-1e1a4a4a-6f45-4e56-80a3-1e6840e4ecdb.mp4

After

https://user-images.githubusercontent.com/9516420/183443742-9b460008-abe3-4de5-ab06-be00a5d8f1aa.mp4

Test plan

Still WIP, only happy path tested currently. Still need to test edge cases.

App preview:

Check out the client app preview documentation to learn more.

Merge request reports

Loading