Skip to content

Use HTML canvas to improve roadmap render performance

euko requested to merge 247495-use-canvas-to-render-timeline-row-grid into master

What does this MR do?

This MR refactors the components used in Roadmap to improve user performance.

We currently use EpicItemTimeline vue component to render a cell for each row shown in Epics Roadmap. Take a look at one of the rows highlighted in red. Each one of the cells (some of them marked in green for identification) in the row is rendered using EpicItemTimeline which can have an adverse performance implication described in #247495 (closed):

image

To improve performance, we are making the following changes in this MR:

  • Use one canvas element for each row to draw the cells(grid) and the current time indicator (the red vertical line). EpicItemTimeline will only render an epic timeline bar (the blue bars in the picture) and nothing else.

Here's a comparison of the component hierarchies before and after this MR is applied.

Before After
EpicItem
- EpicDetailsItem
- EpicItemTimeline
.
.
- EpicItemTimeline
EpicItem
- RoadmapItem (only contains logic, intended to replace mixins)
  - EpicDetailsItem
  - RoadmapItemTimelineGrid (wraps canvas)
  - EpicItemTimeline

Another major change included in this MR is the addition of RoadmapItem component which is meant to replace the use of mixins in EpicTimeline and few other components. RoadmapItem can be used to replace the use of mixins in MilestoneItem as well in a later MR.

List of changes

In support of the main work, a lot of auxiliary changes such as new packages, specs, an helpers used in those specs have been added. Here's a detailed summary of the changes that significant:

filename changes/other commentary
roadmap_item.vue Newly added. This replaces common_mixin.js for EpicItemTimeline and imports the methods from the following mixins:
  • months_preset_mixin.js
  • weeks_preset_mixins.js
  • quarters_preset_mixins.js
(these mixins only include methods).
RoadmapItem can be used to phase out the mixins for MilestoneItem component as well (not happening in this MR)
*_preset_mixin.js - Modified methods to optionally return a raw number (ex. instead of returning 'left: 10%', return 10
epic_item_timeline.vue - Removed use of mixins and a lot of logic have been delegated to RoadmapItem. It is now only used to render an epic timeline bar
roadmap_timeline_grid.vue - Newly added. This component renders <canvas> element. Grids/cells are drawn on the canvas as well as the current time indicator (the red vertical line)
epic_item.vue - Also removed common_mixin.js from this component.
Moved some of the computed props into RoadmapItem
epics_list_section.vue - Removed CurrentDayIndicator (this red indicator is drawn on canvas in RoadmapTimelineGrid
- Added getEmptyRowContainerHeight to return the height of the bottom margin - it is the empty space past the last epic in the screenshot.

Third party packages added

package why link
jest-image-snapshot (Apache 2.0) Needed for image snapshot testing https://github.com/americanexpress/jest-image-snapshot
PureImage (MIT) Used to provide a stub for Canvas element. It was chosen because it's all-javascript without any external dependencies (namely, c++ lib.) https://github.com/joshmarinacci/node-pureimage

Related MRs

Few MRs have been merged recently to get some prework done for this MR (such as getting rid of deprecated vue testing helpers)

merge request what did it do
!48654 (merged) Removed unused skeleton loader, css and fix mock data for roadmap specs
!49433 (merged) 1) Switched in vue-test-utils and removed deprecated vue test helpers. 2) Fixed flawed specs
!49530 (merged) Refactored hasStartDate* methods in preset* mixins

Screenshots (strongly suggested)

There is no visual change image

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Related to #247495 (closed)

Edited by euko

Merge request reports