Repository navigation
UI: Preload base React plugin bundles with the page - #74777
Merged
Merged
Conversation
A React plugin with destination "base" renders on every page, but the UI only learns its bundle URL from the plugins endpoint after its own scripts have run. The bundle download starts late, and the page moves down when the plugin appears. The server now adds a modulepreload link for each base app's bundle to index.html, so the browser fetches it alongside the UI's scripts. The UI's later import() of the same URL reuses the preloaded module. Only plugins without a team are included, because the page is rendered before the user is known.
jlaneve
marked this pull request as ready for review
October 16, 2026 01:22
jlaneve
requested review from
bbovenzi,
bugraoz93,
choo121600,
ephraimbuddy,
guan404ming,
henry3260,
jason810496,
pierrejeambrun,
rawwar,
ryanahamilton,
shubhamraj-git and
vatsrahul1001
as code owners
October 16, 2026 01:22
bbovenzi
approved these changes
Oct 21, 2026
Contributor
Backport successfully created: v3-4-testNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
|
github-actions Bot
pushed a commit
to aws-mwaa/upstream-to-airflow
that referenced
this pull request
Oct 21, 2026
…he#74777) * UI: Preload base React plugin bundles with the page A React plugin with destination "base" renders on every page, but the UI only learns its bundle URL from the plugins endpoint after its own scripts have run. The bundle download starts late, and the page moves down when the plugin appears. The server now adds a modulepreload link for each base app's bundle to index.html, so the browser fetches it alongside the UI's scripts. The UI's later import() of the same URL reuses the preloaded module. Only plugins without a team are included, because the page is rendered before the user is known. * Cover the empty and escaped cases of the preload links (cherry picked from commit 165f5ad) Co-authored-by: Julian LaNeve <lanevejulian@gmail.com>
aws-airflow-bot
pushed a commit
to aws-mwaa/upstream-to-airflow
that referenced
this pull request
Oct 21, 2026
…he#74777) * UI: Preload base React plugin bundles with the page A React plugin with destination "base" renders on every page, but the UI only learns its bundle URL from the plugins endpoint after its own scripts have run. The bundle download starts late, and the page moves down when the plugin appears. The server now adds a modulepreload link for each base app's bundle to index.html, so the browser fetches it alongside the UI's scripts. The UI's later import() of the same URL reuses the preloaded module. Only plugins without a team are included, because the page is rendered before the user is known. * Cover the empty and escaped cases of the preload links (cherry picked from commit 165f5ad) Co-authored-by: Julian LaNeve <lanevejulian@gmail.com>
bbovenzi
pushed a commit
that referenced
this pull request
Oct 21, 2026
…) (#75259) * UI: Preload base React plugin bundles with the page A React plugin with destination "base" renders on every page, but the UI only learns its bundle URL from the plugins endpoint after its own scripts have run. The bundle download starts late, and the page moves down when the plugin appears. The server now adds a modulepreload link for each base app's bundle to index.html, so the browser fetches it alongside the UI's scripts. The UI's later import() of the same URL reuses the preloaded module. Only plugins without a team are included, because the page is rendered before the user is known. * Cover the empty and escaped cases of the preload links (cherry picked from commit 165f5ad) Co-authored-by: Julian LaNeve <lanevejulian@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A React plugin with
destination: "base"renders on every page, but the UI learns its bundle URL only fromGET /api/v2/plugins, after the UI's own scripts have run. On a Fast 3G profile the browser starts the bundle download 11.3 s into the page load, so the plugin shows up late and the page moves down. The server now adds amodulepreloadlink toindex.htmlfor each base app's bundle, and the browser starts the download 0.2 s into the load. The UI's laterimport()of the same URL takes the preloaded module, so the bundle still downloads once.Only plugins without a team get a link. The server renders the page before it knows the user, so it can't apply the team filter that
GET /api/v2/pluginsapplies. For the same reason, a user who can't view plugins still downloads a global base plugin's bundle, which the UI never imports.I checked this on Airflow 3.3.1 in Chromium, Firefox and WebKit, with one base plugin and a base path. Every page load downloaded the bundle once, including a bundle on another origin. On Fast 3G the plugin appeared 0.8 s after the page instead of 1.3 s. On Fast 4G it made no difference.
Call-stack diff
GET /{rest_of_path} core_api/app.py └─ webapp() └─ TemplateResponse("/index.html") ├─ backend_server_base_url # unchanged + └─ preload_bundle_urls # computed once in init_views + └─ base_react_app_bundle_urls() + └─ get_plugin_info(["react_apps"]) # base apps, no team index.html <base href> # unchanged + <link rel="modulepreload" href> # one per base bundleUnchanged:
ReactPluginstill loads the bundle withimport()and resolves the URL againstdocument.baseURI. The<link>follows<base>, so both resolve to the same URL.Related: #74762
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Claude Opus 5.5) following the guidelines
{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.