mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-14 13:16:16 -08:00
Merge remote-tracking branch 'origin/master' into perf/zoneless-flip
# Conflicts: # apps/web/src/app/app.config.ts # tools/performance/journey-baselines.json
This commit is contained in:
commit
7b00a57138
53 files changed
+2068
-543
No files matched your search
@@ -88,6 +88,55 @@ tokens, so the retired `--mdc-*` names compile but do nothing;
|
||||
a spec loads as raw CSS cannot use Sass modules; it declares the `--mat-*`
|
||||
token directly and says why.
|
||||
|
||||
### Material off the startup path
|
||||
|
||||
`renderer.initialBytes` ([performance journeys](performance-journeys.md#rendererinitialbytes))
|
||||
counts every module an eager file imports, and the bundler keeps a module in
|
||||
one chunk, so one import of one export carries the whole module. Material
|
||||
therefore reaches the initial bundle only through the snack-bar, which root
|
||||
services inject (and with it `button`, the icon button and the CDK overlay).
|
||||
Everything else is lazy by these rules:
|
||||
|
||||
- **Form-field defaults.** A component that renders `<mat-form-field>`
|
||||
adds `providers: [provideFormFieldDefaults()]`
|
||||
(`@iptvnator/ui/components/form-field-defaults`); the token is never
|
||||
provided at the root, where its import alone put the 54 KB form-field
|
||||
chunk on the initial path. `pnpm run ui:form-field-defaults:validate` (CI)
|
||||
requires the provider on every such component and allows the token
|
||||
nowhere else; see the Dialogs and forms notes below.
|
||||
- **Dialogs from services created with the app.** A root service that opens a
|
||||
dialog resolves `MatDialog` through `LazyMatDialog`
|
||||
(`@iptvnator/ui/components/lazy-dialog`) and imports the dialog component
|
||||
on demand, as `DialogService`, the player service, the parental lock prompt
|
||||
and the workspace shell actions do; `openConfirmDialog` returns a promise
|
||||
that settles once the dialog is open. A component in a lazy chunk injects
|
||||
`MatDialog` directly.
|
||||
- **Panels the shell mounts on every launch.** The EPG progress panel and the
|
||||
update notification are an eager host with `@defer (when visible)` around
|
||||
the view that imports Material; the startup status draws its spinner as
|
||||
static markup copied from `mat-spinner`. A new always-mounted component
|
||||
follows the same split.
|
||||
- **Theme scope.** `m3-theme.scss` themes only the components in its
|
||||
`$material-components` list, through `meta.apply` for both the light theme
|
||||
and the dark colours. Add an entry with a new `@angular/material/<entry>`
|
||||
import and remove it with the last one;
|
||||
`pnpm run styles:material-theme-scope:validate` (CI) checks both directions
|
||||
(`core` always stays, `button` brings `icon-button` and `fab`).
|
||||
- **No animations module.** Nothing declares an Angular animation trigger and
|
||||
Material 22 animates with CSS, deciding from `prefers-reduced-motion` itself,
|
||||
so `app.config.ts` does not call `provideAnimations()`; the Electron
|
||||
`material-motion.e2e.ts` checks that dialogs, selects, menus, snack-bars and
|
||||
tooltips still animate in and out and stop under reduced motion. One side
|
||||
effect of the module is gone with it: its renderer deferred every DOM
|
||||
removal to the end of the change-detection tick, so a destroy hook still
|
||||
saw its view attached. Without it Angular detaches the view first, where
|
||||
`scrollTop` reads 0 and Chromium has already fired a `focusout` with no
|
||||
related target for the focused control. A destroy hook therefore never
|
||||
reads geometry or focus from its own view: the catalog list tracks the
|
||||
grid offset from scroll events, and the player settings panel decides
|
||||
"focus was inside" in a microtask after such a `focusout`, which the close
|
||||
destroys the panel before. Both have specs that detach the view first.
|
||||
|
||||
The app theme is the `.dark-theme` class that `SettingsService` puts on
|
||||
`<body>`; a "System" choice resolves the OS preference there and nowhere
|
||||
else. Component styles never use a `prefers-color-scheme` query, which
|
||||
|
||||
@@ -1167,6 +1167,24 @@ replace with
|
||||
`performance-build-config.spec.ts` keeps it that way. Removing the static
|
||||
import lowered the counter by 12,565 bytes.
|
||||
|
||||
The bundler keeps each module in one chunk, so one eager import of any
|
||||
export carries the module's whole code: providing
|
||||
`MAT_FORM_FIELD_DEFAULT_OPTIONS` in `app.config.ts` alone put the 54 KB
|
||||
form-field chunk on the initial path, although every form field renders in a
|
||||
lazy route or dialog. Angular Material therefore stays off the startup path by
|
||||
construction, with the rules and guards in the
|
||||
[UI guidelines](iptvnator-ui-guidelines.md#material-off-the-startup-path):
|
||||
form-field defaults are provided per component (#1928), services created with
|
||||
the app resolve `MatDialog` through `LazyMatDialog`, the panels the shell
|
||||
mounts on every launch defer their Material views, the theme emits tokens only
|
||||
for imported components, and the app does not provide the animations module,
|
||||
which nothing used (Material 22 animates with CSS). Together these lowered the
|
||||
counter from 1,596,201 to 1,344,067 bytes (-252,134, 15.8%) on a local
|
||||
production build at the branch point (#1931); the baseline follows the
|
||||
measurement of the branch merged with `master`, 1,345,807. The snack-bar stays: root
|
||||
services inject it, and with it Material's button, the icon button chunk and
|
||||
the CDK overlay (about 190 KB) remain initial.
|
||||
|
||||
`--summary` writes the journey summary shape (`journeys.<journey>.counters`)
|
||||
that the ratchet checker consumes. `--dist <dir>` points the script at another
|
||||
build output, for example the `electron-performance` configuration.
|
||||
|
||||
Reference in new issue
Block a user