-
由 Thomas Randolph 创作于由 Thomas Randolph 创作于
status: proposed
creation-date: "2023-10-10"
authors: [ "@thomasrandolph", "@patrickbajao", "@igor.drozdov", "@jerasmus", "@iamphill", "@slashmanov", "@psjakubowska" ]
coach: [ "@ntepluhina" ]
approvers: [ ]
owning-stage: "~devops::create"
participating-stages: []
Reusable Rapid Diffs (RRD)
Summary
Diffs at GitLab are spread across several places with each area using their own method. We are aiming to develop a single, performant way for diffs to be rendered across the application. Our aim here is to improve all areas of diff rendering, from the backend creation of diffs to the frontend rendering the diffs.
All the diffs features related to this document are listed on a dedicated page.
Motivation
Goals
- improved perceived performance
- improved maintainability
- consistent coverage of all scenarios
Non-Goals
This effort will not:
- Identify improvements for the current implementation of diffs both in Merge Requests or in the Repository Commits
Priority of Goals
In an effort to provide guidance on which goals are more important than others to assist in making consistent choices, despite all goals being important, we defined the following order.
Perceived performance is above improved maintainability is above consistent coverage.
Examples:
- a proposal improves maintainability at the cost of perceived performance:
❌ we should consider an alternative. - a proposal removes a feature from certain contexts, hurting coverage, and has no impact on perceived performance or maintainability:
❌ we should re-consider. - a proposal improves perceived performance but removes features from certain contexts of usage:
✅ it's valid and should be discussed with Product/UX. - a proposal guarantees consistent coverage and has no impact on perceived performance or maintainability:
✅ it's valid.
In essence, we'll strive to meet every goal at each decision but prioritise the higher ones.
Process
Workspace & Artifacts
- We will store implementation details like metrics, budgets, and development & architectural patterns here in the docs
- We will store large bodies of research, the results of audits, etc. in the wiki of the RRD project
- We will store audio & video recordings on the public YouTube channel in the Code Review / RRD playlist
- We will store drafts, meeting notes, and other temporary documents in public Google docs
Proposal
The new approach proposed here changes what we have done in the past by doing the following:
- Stop using virtualized scrolling for rendering diffs.
- Move most of the rendering work to the server.
- Enhance server-rendered HTML on the client.
- Unify diffs codebase across all pages rendering diffs (merge request, repository commits, compare revisions and any other).
Definitions
Maintainability
Maintainable projects are simple projects.
Simplicity is the opposite of complexity. This uses a definition of simple and complex described by Rich Hickey in "Simple Made Easy" (Strange Loop, 2011).
- Maintainable code is simple (single task, single concept, separate from other things).
- Maintainable projects expand on simple code by having simple structure (folders define classes of behaviors, e.g. you can be assured that a component directory will never initiate a network call, because that would be conflating visual display with data access)
- Maintainable applications flow out of simple organization and simple code. The old saying is a cluttered desk is representative of a cluttered mind. Rigorous discipline on simplicity will be represented in our output (the product). By being strict about working simply, we will naturally produce applications where our users can more easily reason about their behavior.
Done
GitLab has an existing definition of done which is geared primarily toward identifying when an MR is ready to be merged.
In addition to the items in the GitLab definition of done, work on RRD should also adhere to the following requirements:
- Meets or exceeds all metrics
- Meets or exceeds our minimum accessibility metrics (these are explicitly not part of our defined priorities, because they are non-negotiable)
- All work is fully documented for engineers (user documentation is a requirement of the standard definition of done)
Acceptance Criteria
To measure our success, we need to set meaningful metrics. These metrics should meaningfully and positively impact the end user.
- Meets or exceeds WCAG 2.2 AA.
- Meets or exceeds ATAG 2.0 AA.
- The RRD app loads less than or equal to 300 KiB of JavaScript (compressed / "across-the-wire")1.
- The RRD app loads less than or equal to 150 KiB of markup, images, styles, fonts, etc. (compressed / "across-the-wire")1.
- The Time to First Diff (
mr-diffs-mark-first-diff-file-shown
) happens before 3 seconds mark. - The RRD app can execute in total isolation from the rest of the GitLab product:
- "Execute" means the app can load, display data, and allows user interaction ("read-only").
- If a part of the application is only used in merge requests or diffs, it is considered part of the Diffs application.
- If a part of the application must be brought in from the rest of the product, it is not considered part of the Diffs load (as defined in metrics 3 and 4).
- If a part of the application must be brought in from the rest of the product, it may not block functionality of the Diffs application.
- If a part of the application must be brought in from the rest of the product, it must be loaded asynchronously.
- If a part of the application meets 5.1-5.5 (such as: the Markdown editor is loaded asynchronously when the user would like to leave a comment on a diff) and its inclusion causes a budget overflow:
- It must be added to a list of documented exceptions that we accept are out of bounds and out of our control.
- The exceptions list should be addressed on a regular basis to determine the ongoing value of overflowing our budget.
1: The Performance Inequality Gap, 2023
Frontend
Ideally, we would meet our definition of done and our accountability metrics on our first try. We also need to continue to stay within those boundaries as we move forward. To ensure this, we need to design an application architecture that:
- Is:
- Scalable.
- Malleable.
- Flexible.
- Considers itself a mission-critical part of the overall GitLab product.
- Treats itself as a complex, unique application with concerns that cannot be addressed as side effects of other parts of the product.
- Can handle data access/format changes without making UI changes.
- Can handle UI changes without making data access/format changes.
- Provides a hookable, inspectable API and avoids code coupling.
- Separates:
- State and application data.
- Application behavior and UI.
- Data access and network access.