argoproj / argoproj/argo-workflows

UI: Code Split larger and/or less-used paths for smaller initial bundle

Open
#12,059 6 comments 3 reactions 0 assignees View on GitHub
area/ui solution/suggested
Dominant language
Go
Stars
17k
Forks
3.7k
Avg merge
1d 20h
Merged PRs (30d)
138

Description

# Summary

Instead of having all the UI pages in one bundle, we can code split out certain pages that are either quite large (e.g. have a lot of code or deps) or less-used.

## Use Cases

- To load the UI faster by loading the most used pages first and then asynchronously loading other pages when needed. For a faster TTFP (time to first paint), TTI (time to interactive), etc. Use less networking on average as well.
- For slower devices such as those described in #11970

### Implementation Details

Nowadays, React supports loading components async with the built-in [`lazy` function](https://legacy.reactjs.org/docs/code-splitting.html), which you normally pass a dynamic import into. Webpack will [automatically code-split dynamic imports](https://webpack.js.org/guides/code-splitting/#dynamic-imports).

Two components that I think might be ripe for code-splitting are:
- the Swagger API docs (see also #12058 and #11970) that are used pretty infrequently, contain a whole `swagger-ui` in it [and the Swagger file itself](https://github.com/argoproj/argo-workflows/blob/03a6168da30717eba3a7e585832841350724e90d/ui/src/app/webpack.config.js#L79)
- perhaps the code editing features that rely on `monaco-editor`

Also, some pages could be good to code-split by default
- the Argo Events pages of the UI could be useful as well as not everyone uses Workflows and Events together
- the Reports page, which I literally had never used nor known that it even existed until #11794

#### Checklist

**EDIT**: This was added after a lot of analysis and work below to keep track of things, was not part of the original issue.

In order of most impact to the bundle and most splittable (some are used in many places and so are harder to split):

1. [ ] code split deps
1. [x] `monaco-editor` (et al): #12150
1. [x] `moment-timezone`: #12097
1. [x] `swagger-ui-react` (et al): #12061
1. [x] `xterm`: #12158
1. [ ] `moment`: #12611
1. [x] `chart.js`: #12061
1. [x] `react-markdown` (+ `remark-gfm` + etc): #12580
1. [ ] `react-datepicker` (+ `date-fns` + `react-popper` + etc):
1. [ ] `cron-parser` (+ `luxon`):

1. [ ] code split pages
1. [x] `ApiDocs`: #12061
1. [x] `Reports`: #12061
1. [ ] `event-sources`:
1. [ ] `sensors`:
1. [ ] `event-flow`:
1. [ ] `cron-workflows`:
1. [ ] `workflow-templates`:
1. [ ] `cluster-workflow-templates`:

### Trade-offs

Note that code-splitting is not without its trade-offs as more bundles can have downsides. In particular if those bundles are very small. In this case I think the pros outweigh the cons for certain pages (Swagger UI almost certainly), but may need some more testing for other pages.

---

**Message from the maintainers**:

Love this enhancement proposal? Give it a 👍. We prioritise the proposals with the most 👍.

Contributor guide

Open the contributing guide

Research direction

Start with ui/src/app/webpack.config.js and inspect the remaining page entries listed in the checklist: event-sources, sensors, event-flow, cron-workflows, workflow-templates, and cluster-workflow-templates. Compare their dependencies and usage before choosing a split, then verify that the initial bundle is smaller and each selected page still loads when opened.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
build-system, frontend, performance
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.