You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by "safaehar (via GitHub)" <gi...@apache.org> on 2026/10/13 16:59:37 UTC
[PR] UI: Reduce initial JavaScript payload [airflow]
safaehar opened a new pull request, #74663:
URL: https://github.com/apache/airflow/pull/74663
Airflow currently includes every UI page in the initial JavaScript payload, even though a browser only needs the modules for the active route. This increases download, parse, and execution work before the UI can respond.
Use React Router's lazy route modules to load page components on demand while keeping the base layout and error boundary available immediately. Routes that require wrapper components or configured props retain their existing rendering behavior through dedicated lazy loaders.
Production bundle comparison against current `main`:
| Initial static JavaScript | `main` | This PR | Reduction |
| --- | ---: | ---: | ---: |
| Raw | 7,779,813 bytes | 2,562,705 bytes | 67.1% |
| Gzip | 2,289,844 bytes | 698,535 bytes | 69.5% |
Validation:
- Airflow pre-commit UI compile, lint, format, and TypeScript checks
- Production UI asset compilation
- `pnpm test src/router.test.tsx` (18 tests)
- Optimized Vite production build
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes — Codex (GPT-5)
Generated-by: Codex (GPT-5) following [the guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
---
Drafted-by: Codex (GPT-5) (no human review before posting)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "safaehar (via GitHub)" <gi...@apache.org>.
safaehar commented on PR #74663:
URL: https://github.com/apache/airflow/pull/74663#issuecomment-6275069927
> Please make sure that React tests and E2E tests all pass. Also please provide a video of the UI navigating between different pages.
@bbovenzi
https://github.com/user-attachments/assets/5d28e4f3-272b-4e13-a9ce-efd37fcaa273
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "safaehar (via GitHub)" <gi...@apache.org>.
safaehar commented on PR #74663:
URL: https://github.com/apache/airflow/pull/74663#issuecomment-6314432334
> Let's make sure we are catching any dynamic loading errors: [remix-run/react-router#10333](https://github.com/remix-run/react-router/discussions/10333)
@bbovenzi Good point. The root route already has an errorElement, so rejected lazy imports reach the error page, but the current Back/Home actions do not recover from a stale chunk after a deployment.
I can add a recovery scoped specifically to dynamic imports:
- On the first import failure, perform one hard reload (Guard it with sessionStorage to prevent reload loops.)
- If loading still fails after the reload, rethrow to the route error boundary and provide an explicit “Reload page” action.
what do you think ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "pierrejeambrun (via GitHub)" <gi...@apache.org>.
pierrejeambrun commented on code in PR #74663:
URL: https://github.com/apache/airflow/pull/74663#discussion_r4312074198
##########
airflow-core/newsfragments/74663.improvement.rst:
##########
@@ -0,0 +1 @@
+Reduce the initial UI JavaScript payload by lazily loading page routes.
Review Comment:
As mentioned in our newsfragment policy, please remove this file.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "bbovenzi (via GitHub)" <gi...@apache.org>.
bbovenzi commented on PR #74663:
URL: https://github.com/apache/airflow/pull/74663#issuecomment-6306657961
Let's make sure we are catching any dynamic loading errors: https://github.com/remix-run/react-router/discussions/10333
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "safaehar (via GitHub)" <gi...@apache.org>.
safaehar commented on code in PR #74663:
URL: https://github.com/apache/airflow/pull/74663#discussion_r4405052545
##########
airflow-core/src/airflow/ui/src/router.tsx:
##########
@@ -16,289 +16,356 @@
* specific language governing permissions and limitations
* under the License.
*/
+import type { ComponentType } from "react";
+
import { queryOptions } from "@tanstack/react-query";
import { createBrowserRouter } from "react-router-dom";
import { UseConfigServiceGetConfigsKeyFn } from "openapi/queries";
import { ConfigService } from "openapi/requests/services.gen";
import { BaseLayout } from "src/layouts/BaseLayout";
-import { DagsLayout } from "src/layouts/DagsLayout";
-import { Asset } from "src/pages/Asset";
-import { AssetEvents } from "src/pages/Asset/AssetEvents";
-import { AssetStateStore } from "src/pages/Asset/AssetStateStore";
-import { AssetsList } from "src/pages/AssetsList";
-import { Configs } from "src/pages/Configs";
-import { Connections } from "src/pages/Connections";
-import { Dag } from "src/pages/Dag";
-import { Backfills } from "src/pages/Dag/Backfills";
-import { Calendar } from "src/pages/Dag/Calendar/Calendar";
-import { Code } from "src/pages/Dag/Code";
-import { Details as DagDetails } from "src/pages/Dag/Details";
-import { Overview } from "src/pages/Dag/Overview";
-import { Tasks } from "src/pages/Dag/Tasks";
-import { Versions } from "src/pages/Dag/Versions";
-import { DagBundle } from "src/pages/DagBundle";
-import { DagBundles } from "src/pages/DagBundles";
-import { DagRuns } from "src/pages/DagRuns";
-import { DagsList } from "src/pages/DagsList";
-import { Dashboard } from "src/pages/Dashboard";
-import { Deadlines } from "src/pages/Deadlines";
import { ErrorPage } from "src/pages/Error";
-import { Events } from "src/pages/Events";
-import { ExternalView } from "src/pages/ExternalView";
-import { GroupTaskInstance, GroupTaskInstances } from "src/pages/GroupTaskInstance";
-import { HITLTaskInstances } from "src/pages/HITLTaskInstances";
-import { Jobs } from "src/pages/Jobs";
-import { LandingPage } from "src/pages/LandingPage";
-import { MappedTaskInstance } from "src/pages/MappedTaskInstance";
-import { Details as MappedTaskInstanceDetails } from "src/pages/MappedTaskInstance/Details";
-import { Plugins } from "src/pages/Plugins";
-import { Pools } from "src/pages/Pools";
-import { Providers } from "src/pages/Providers";
-import { Run } from "src/pages/Run";
-import { AssetEvents as DagRunAssetEvents } from "src/pages/Run/AssetEvents";
-import { Callbacks as DagRunCallbacks } from "src/pages/Run/Callbacks";
-import { Details as DagRunDetails } from "src/pages/Run/Details";
-import { Security } from "src/pages/Security";
-import { Settings } from "src/pages/Settings";
-import { Task } from "src/pages/Task";
-import { Overview as TaskOverview } from "src/pages/Task/Overview";
-import { TaskInstance, Logs } from "src/pages/TaskInstance";
-import { AssetEvents as TaskInstanceAssetEvents } from "src/pages/TaskInstance/AssetEvents";
-import { DefaultTab as TaskInstanceDefaultTab } from "src/pages/TaskInstance/DefaultTab";
-import { Details as TaskInstanceDetails } from "src/pages/TaskInstance/Details";
-import { HITLResponse } from "src/pages/TaskInstance/HITLResponse";
-import { RenderedTemplates } from "src/pages/TaskInstance/RenderedTemplates";
-import { TaskInstances } from "src/pages/TaskInstances";
-import { TaskStateStore } from "src/pages/TaskStateStore";
-import { Variables } from "src/pages/Variables";
-import { XCom } from "src/pages/XCom";
import { TabEntity, TabName, TaskInstanceTab } from "src/constants/tab";
import { client } from "./queryClient";
+const ROUTE_MODULE_RELOAD_KEY = "airflow-route-module-reload-attempted";
+
+export const loadRouteModule = async <Module,>(factory: () => Promise<Module>) => {
+ try {
+ return await factory();
+ } catch (error) {
Review Comment:
Good catch. I moved the automatic reload to ErrorPage, so it runs after react router has committed the requested URL. A repeated failure still reloads only once, while a successful route-module load now clears the guard so a later deployment can recover again. I added regression tests for both cases in last commit (5ad366d773).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "pierrejeambrun (via GitHub)" <gi...@apache.org>.
pierrejeambrun commented on code in PR #74663:
URL: https://github.com/apache/airflow/pull/74663#discussion_r4402986968
##########
airflow-core/src/airflow/ui/vite.config.ts:
##########
@@ -76,8 +76,10 @@ export default defineConfig({
environment: "happy-dom",
exclude: ["**/node_modules/**", "**/dist/**", "tests/e2e/**"],
globals: true,
+ maxWorkers: 4,
Review Comment:
I checked these locally: without the three settings 27 tests time out, and even with the longer timeouts, dropping `maxWorkers` still leaves 2 failures on my machine. So tests that render the full router now depend on how loaded the machine is, and these settings cap parallelism and make every failing `waitFor` wait 10s for the whole suite. Do you think we could keep the extra time to the tests that render the router (for example by preloading the route modules there) rather than changing it globally? Not blocking, but I'm worried about CI flakiness.
##########
airflow-core/src/airflow/ui/src/router.tsx:
##########
@@ -16,289 +16,356 @@
* specific language governing permissions and limitations
* under the License.
*/
+import type { ComponentType } from "react";
+
import { queryOptions } from "@tanstack/react-query";
import { createBrowserRouter } from "react-router-dom";
import { UseConfigServiceGetConfigsKeyFn } from "openapi/queries";
import { ConfigService } from "openapi/requests/services.gen";
import { BaseLayout } from "src/layouts/BaseLayout";
-import { DagsLayout } from "src/layouts/DagsLayout";
-import { Asset } from "src/pages/Asset";
-import { AssetEvents } from "src/pages/Asset/AssetEvents";
-import { AssetStateStore } from "src/pages/Asset/AssetStateStore";
-import { AssetsList } from "src/pages/AssetsList";
-import { Configs } from "src/pages/Configs";
-import { Connections } from "src/pages/Connections";
-import { Dag } from "src/pages/Dag";
-import { Backfills } from "src/pages/Dag/Backfills";
-import { Calendar } from "src/pages/Dag/Calendar/Calendar";
-import { Code } from "src/pages/Dag/Code";
-import { Details as DagDetails } from "src/pages/Dag/Details";
-import { Overview } from "src/pages/Dag/Overview";
-import { Tasks } from "src/pages/Dag/Tasks";
-import { Versions } from "src/pages/Dag/Versions";
-import { DagBundle } from "src/pages/DagBundle";
-import { DagBundles } from "src/pages/DagBundles";
-import { DagRuns } from "src/pages/DagRuns";
-import { DagsList } from "src/pages/DagsList";
-import { Dashboard } from "src/pages/Dashboard";
-import { Deadlines } from "src/pages/Deadlines";
import { ErrorPage } from "src/pages/Error";
-import { Events } from "src/pages/Events";
-import { ExternalView } from "src/pages/ExternalView";
-import { GroupTaskInstance, GroupTaskInstances } from "src/pages/GroupTaskInstance";
-import { HITLTaskInstances } from "src/pages/HITLTaskInstances";
-import { Jobs } from "src/pages/Jobs";
-import { LandingPage } from "src/pages/LandingPage";
-import { MappedTaskInstance } from "src/pages/MappedTaskInstance";
-import { Details as MappedTaskInstanceDetails } from "src/pages/MappedTaskInstance/Details";
-import { Plugins } from "src/pages/Plugins";
-import { Pools } from "src/pages/Pools";
-import { Providers } from "src/pages/Providers";
-import { Run } from "src/pages/Run";
-import { AssetEvents as DagRunAssetEvents } from "src/pages/Run/AssetEvents";
-import { Callbacks as DagRunCallbacks } from "src/pages/Run/Callbacks";
-import { Details as DagRunDetails } from "src/pages/Run/Details";
-import { Security } from "src/pages/Security";
-import { Settings } from "src/pages/Settings";
-import { Task } from "src/pages/Task";
-import { Overview as TaskOverview } from "src/pages/Task/Overview";
-import { TaskInstance, Logs } from "src/pages/TaskInstance";
-import { AssetEvents as TaskInstanceAssetEvents } from "src/pages/TaskInstance/AssetEvents";
-import { DefaultTab as TaskInstanceDefaultTab } from "src/pages/TaskInstance/DefaultTab";
-import { Details as TaskInstanceDetails } from "src/pages/TaskInstance/Details";
-import { HITLResponse } from "src/pages/TaskInstance/HITLResponse";
-import { RenderedTemplates } from "src/pages/TaskInstance/RenderedTemplates";
-import { TaskInstances } from "src/pages/TaskInstances";
-import { TaskStateStore } from "src/pages/TaskStateStore";
-import { Variables } from "src/pages/Variables";
-import { XCom } from "src/pages/XCom";
import { TabEntity, TabName, TaskInstanceTab } from "src/constants/tab";
import { client } from "./queryClient";
+const ROUTE_MODULE_RELOAD_KEY = "airflow-route-module-reload-attempted";
+
+export const loadRouteModule = async <Module,>(factory: () => Promise<Module>) => {
+ try {
+ return await factory();
+ } catch (error) {
Review Comment:
I tried this by making the route chunks 404 and found two things. The reload happens before React Router commits the new URL, so it reloads the page the user was leaving and the click is lost. And since the flag is never cleared, a second redeploy later in the same tab gets no automatic reload, only the error page. Could we clear the flag once a module loads?
```suggestion
export const loadRouteModule = async <Module,>(factory: () => Promise<Module>) => {
try {
const module = await factory();
globalThis.sessionStorage.removeItem(ROUTE_MODULE_RELOAD_KEY);
return module;
} catch (error) {
```
For the first part, maybe the one-time reload could move into `ErrorPage`? It renders after the URL has changed, so the reload would land on the page the user asked for.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "bbovenzi (via GitHub)" <gi...@apache.org>.
bbovenzi commented on PR #74663:
URL: https://github.com/apache/airflow/pull/74663#issuecomment-6316972214
Yes that sounds good!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "safaehar (via GitHub)" <gi...@apache.org>.
safaehar commented on PR #74663:
URL: https://github.com/apache/airflow/pull/74663#issuecomment-6398146727
> Yes that sounds good!
@bbovenzi done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "bbovenzi (via GitHub)" <gi...@apache.org>.
bbovenzi commented on PR #74663:
URL: https://github.com/apache/airflow/pull/74663#issuecomment-6153230219
Please make sure that React tests and E2E tests all pass.
Also please provide a video of the UI navigating between different pages.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] UI: Reduce initial JavaScript payload [airflow]
Posted by "safaehar (via GitHub)" <gi...@apache.org>.
safaehar commented on code in PR #74663:
URL: https://github.com/apache/airflow/pull/74663#discussion_r4405072666
##########
airflow-core/src/airflow/ui/vite.config.ts:
##########
@@ -76,8 +76,10 @@ export default defineConfig({
environment: "happy-dom",
exclude: ["**/node_modules/**", "**/dist/**", "tests/e2e/**"],
globals: true,
+ maxWorkers: 4,
Review Comment:
Good point. Those global timeout and worker settings were added to stabilize full-suite runs under CPU contention, but they are not required for the lazy-loading behavior itself. I removed them
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org