From 3a9b906a1117043f83dcf93fe1f7ac832dece7a3 Mon Sep 17 00:00:00 2001 From: Stanislav Lashmanov Date: Thu, 7 Dec 2023 23:46:19 +0400 Subject: [PATCH 1/2] Outline New Diffs SSR approach --- .../blueprints/new_diffs/index.md | 68 ++++++++++++++++--- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/doc/architecture/blueprints/new_diffs/index.md b/doc/architecture/blueprints/new_diffs/index.md index d9dab14e683188..5e62cf30bc025b 100644 --- a/doc/architecture/blueprints/new_diffs/index.md +++ b/doc/architecture/blueprints/new_diffs/index.md @@ -1,7 +1,7 @@ --- status: proposed creation-date: "2023-10-10" -authors: [ "@thomasrandolph", "@patrickbajao", "@igor.drozdov", "@jerasmus", "@iamphill" ] +authors: [ "@thomasrandolph", "@patrickbajao", "@igor.drozdov", "@jerasmus", "@iamphill", "@slashmanov" ] coach: [ "@ntepluhina" ] approvers: [ ] owning-stage: "~devops::create" @@ -55,16 +55,30 @@ In essence, we'll strive to meet every goal at each decision but prioritise the ## Proposal - +New diffs introduce a paradigm shift in our approach to rendering diffs. + +Previously we had two different approaches to rendering diffs: + +1. Merge requests heavily utilized client-side rendering +1. All other pages used server-side rendering with sprinkles of JavaScript + +In merge requests most of the rendering work was done on the client: +backend would only generate a JSON response with diffs data and the client would be responsible for both drawing the diffs and reacting to user input. +This led to us adopting a [virtualized scrolling solution](https://github.com/Akryum/vue-virtual-scroller/tree/v1/packages/vue-virtual-scroller) +for client-side rendering, which sped up drawing large diff file lists significantly. + +Unfortunately this came with downsides of a very high maintenance cost and +[constant bugs](https://gitlab.com/gitlab-org/gitlab/-/issues/427155#note_1607184794). +The user experience also suffered because we couldn't show diffs right away when you visited a page and had to wait for the JSON response first. +Lastly, this approach went completely parallel to the server-rendered diffs used on other pages, +which resulted in two completely separate codebases for the diffs. + +The New diffs approach changes that by doing the following: + +1. Stop using virtualized scrolling for rendering diffs +1. Move most of the rendering work to the server +1. Enhance server-rendered HTML on the client +1. Unify diffs codebase across merge requests and other pages ### Accessibility @@ -122,6 +136,38 @@ To measure our success, we need to set meaningful metrics. These metrics should --- 1: [The Performance Inequality Gap, 2023](https://infrequently.org/2022/12/performance-baseline-2023/) +### New architecture overview + +New diffs introduce a change in responsibilities for both frontend and backend. + +Backend will: + +1. Prepare diffs data +1. Highlight diff lines +1. Render diffs as HTML +1. Embed diffs metadata into the final response + +Frontend will: + +1. Enhance existing and future diffs HTML +1. Fetch and render additional diffs HTML that didn't fit into the page document + +#### Static and dynamic separation + +In order to achieve that separation of concerns we should distinguish between static and dynamic UI on the page. +Everything that is static should always be rendered on the server, everything dynamic – enhanced on the client. +As an example: a highlighted diff line doesn't change with user input, so we should consider rendering it on the server. + +#### Performance optimizations + +To improve the perceived performance of the page we should implement the following techniques: + +1. Limit the amount of diffs rendered on the page at first +1. Utilize [HTML streaming](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/101) to render the rest of the diffs + 1. Use Web Components in order to hook into diff files appearing on the page +1. Apply `content-visibility` whenever possible to reduce redraw overhead +1. Render diff discussions asynchronously + ### Front end #### High-level implementation -- GitLab From dda189914fde8c4e20750582870382dcb090a6e9 Mon Sep 17 00:00:00 2001 From: Amy Qualls Date: Thu, 7 Dec 2023 13:42:35 -0800 Subject: [PATCH 2/2] Light tone and style edits Punctuation. Line breaks. Smoothing a few words here and there. Files in this folder get a light edit from TWs, so I didn't go into deep detail. --- .../blueprints/new_diffs/index.md | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/doc/architecture/blueprints/new_diffs/index.md b/doc/architecture/blueprints/new_diffs/index.md index 5e62cf30bc025b..4a1554dbcd4e14 100644 --- a/doc/architecture/blueprints/new_diffs/index.md +++ b/doc/architecture/blueprints/new_diffs/index.md @@ -56,29 +56,33 @@ In essence, we'll strive to meet every goal at each decision but prioritise the ## Proposal New diffs introduce a paradigm shift in our approach to rendering diffs. +Previously, we had two different approaches to rendering diffs: -Previously we had two different approaches to rendering diffs: +1. Merge requests heavily utilized client-side rendering. +1. All other pages used server-side rendering with sprinkles of JavaScript. -1. Merge requests heavily utilized client-side rendering -1. All other pages used server-side rendering with sprinkles of JavaScript +In merge requests, most of the rendering work was done on the client: -In merge requests most of the rendering work was done on the client: -backend would only generate a JSON response with diffs data and the client would be responsible for both drawing the diffs and reacting to user input. -This led to us adopting a [virtualized scrolling solution](https://github.com/Akryum/vue-virtual-scroller/tree/v1/packages/vue-virtual-scroller) +- The backend would only generate a JSON response with diffs data. +- The client would be responsible for both drawing the diffs and reacting to user input. + +This led to us adopting a +[virtualized scrolling solution](https://github.com/Akryum/vue-virtual-scroller/tree/v1/packages/vue-virtual-scroller) for client-side rendering, which sped up drawing large diff file lists significantly. -Unfortunately this came with downsides of a very high maintenance cost and +Unfortunately, this came with downsides of a very high maintenance cost and [constant bugs](https://gitlab.com/gitlab-org/gitlab/-/issues/427155#note_1607184794). -The user experience also suffered because we couldn't show diffs right away when you visited a page and had to wait for the JSON response first. +The user experience also suffered because we couldn't show diffs right away +when you visited a page, and had to wait for the JSON response first. Lastly, this approach went completely parallel to the server-rendered diffs used on other pages, which resulted in two completely separate codebases for the diffs. -The New diffs approach changes that by doing the following: +The new-diffs approach changes that by doing the following: -1. Stop using virtualized scrolling for rendering diffs -1. Move most of the rendering work to the server -1. Enhance server-rendered HTML on the client -1. Unify diffs codebase across merge requests and other pages +1. Stop using virtualized scrolling for rendering diffs. +1. Move most of the rendering work to the server. +1. Enhance server-rendered HTML on the client. +1. Unify diffs codebase across merge requests and other pages. ### Accessibility @@ -140,33 +144,37 @@ To measure our success, we need to set meaningful metrics. These metrics should New diffs introduce a change in responsibilities for both frontend and backend. -Backend will: +The backend will: -1. Prepare diffs data -1. Highlight diff lines -1. Render diffs as HTML -1. Embed diffs metadata into the final response +1. Prepare diffs data. +1. Highlight diff lines. +1. Render diffs as HTML. +1. Embed diffs metadata into the final response. -Frontend will: +The frontend will: -1. Enhance existing and future diffs HTML -1. Fetch and render additional diffs HTML that didn't fit into the page document +1. Enhance existing and future diffs HTML. +1. Fetch and render additional diffs HTML that didn't fit into the page document. #### Static and dynamic separation -In order to achieve that separation of concerns we should distinguish between static and dynamic UI on the page. -Everything that is static should always be rendered on the server, everything dynamic – enhanced on the client. +To achieve the separation of concerns, we should distinguish between static and dynamic UI on the page: + +- Everything that is static should always be rendered on the server. +- Everything dynamic should be enhanced on the client. + As an example: a highlighted diff line doesn't change with user input, so we should consider rendering it on the server. #### Performance optimizations To improve the perceived performance of the page we should implement the following techniques: -1. Limit the amount of diffs rendered on the page at first -1. Utilize [HTML streaming](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/101) to render the rest of the diffs - 1. Use Web Components in order to hook into diff files appearing on the page -1. Apply `content-visibility` whenever possible to reduce redraw overhead -1. Render diff discussions asynchronously +1. Limit the number of diffs rendered on the page at first. +1. Use [HTML streaming](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/101) + to render the rest of the diffs. + 1. Use Web Components to hook into diff files appearing on the page. +1. Apply `content-visibility` whenever possible to reduce redraw overhead. +1. Render diff discussions asynchronously. ### Front end -- GitLab