### Open question
Is there any way we can limit the CSS that is shipped to what is *actually* needed on a given page (both for server-rendered and client-rendered components)? Having to load ALL of “codex-css” and then Vue, and then Codex JS means a lot of code
### Exploration
Consider the following scenario. We have a given wiki page that contains some static content (markup + styles) as well as a feature – **Feature A**. Feature A contains three Codex components: **Component 1**, **Component 2**, and **Component 3**. Component 3 only becomes visible after the user takes some sort of action, but components 1 and 2 are visible "above the fold" as soon as the page loads. Feature A is an interactive, Vue.js-based feature, but we want to show the basic UI before JS is initialized for performance reasons (and also to help out users who have JS disabled for some reason).### Proposed Solution
For the best possible performance, we'd want the following behavior:
- **Styles for components 1 and 2 should be available *immediately***, alongside the page markupSee https://phabricator.wikimedia.org/T323179#8455644 for what the current proposed implementation path for how to ship CSS Codex components alongside the JS ones we are already building. The markup for these components should be correctly styled before JS initializes on the page (we don't want a "flash of unstyled content")
- **Styles for component 3 *should not* be included in the initial payload**;at proposal is informed by the performance considerations explored here, we want to keep this as small as possible and we do not want to ship code to users that they might not need
- **An additional bundle should be provided to clients that can support JS**but it is balanced with some practical concerns (minimizing risk, have a modern browsernot needing changes to existing infrastructure, etc (we already have the means to differentiate here). This bundle should contain the JS for Components 1, 2,etc).
Here is a short summary of the performance implications of the approach under consideration:
1. and 3 as well as the styles for ComponCodex components will be organized into a few different 3 (since it is JS-only).modules for use inside of MediaWiki, Finally,similar to how we currently do things with OOUI. if there are any style overrides for JS-enabled components (additional styles that only get loaded in the Vue version of a component as opposed to the CSS version),To do this we'll need to create additional bundles using Vite that contain the JS and CSS for a sub-set of our components. they can be included here as well.
- **This additional bundle *must not include* any of the styles that have already been shipped to the user** – in this case the styles for Components 1 and 2. We don't want to waste bytes shipping styles to the user that they already got with the static,For example a bundle that just contained Codex buttons and related components would have `codex-buttons.js` and `codex-buttons.css`. HTML version of the page.
| Initial HTML Payload (delivered to all users) | JS-enabled bundle (delivered to some users) |
| --- | --- |This is similar to how we are currently building the `codex-search` package as a separate bundle.
| Component 1 CSS | Component 3 JS & CSS |2. These bundles will get included in MediaWiki as separate ResourceLoader modules. Each new codex "sub-package" will likely require two RL bundles: one for the styles (which can be used by itself if only CSS-based components are needed), and one with the JS. The latter module will have the former as a dependency.
This will allow for users of Codex inside of MediaWiki to gain the following benefits:
| Component 2 CSS | Component 2 CSS overrides |* They won't need to load ALL of Codex just to use a small number of components. Without more sophisticated front-end build tools (which all require a Node.js runtime) we can't do perfect tree-shaking, but at least this will allow us to avoid the worst inefficiencies (where all of Codex needs to be loaded when only one component is needed). We believe this will be acceptable for now from a performance standpoint (we do the same thing for OOUI). If more optimization is needed then we need to explore introducing a true front-end build step in MediaWiki.
| **must not contain**: anything relating to component 3 | **must not contain**: duplicate styles for components 1 and 2 |
I suspect that it will be much easier to satisfy these conditions if we have mostly decoupled component styles and JS, and if each one of these things can be further broken down at a pretty granular level (either by component, or by component groups – similar to `OOUI.buttons`, etc).
In a perfect world we could run a just-in-time build step to tree-shake down to the exact code needed (both for the server-rendered UI as well as the JS follow-up),* CSS can be loaded independently of JS – and subsequent loading of JS (to progressively enhance the page) will not require re-loading the CSS that has already been delivered. but without such a system in place we maSimple features that don't need JS at all can just use the CSS style module for the components they need to do this manuallyand be done with it.
---
## Acceptance criteria
- [x] DST discusses potential problems and solutions
- [] DST determines a path forward based in tandem with choosing implementation path (see T323179) and documents work via subtasks of the CSS-only components epic