diff --git a/.gitignore b/.gitignore
index 611ba66e439..ba113e0e744 100644
--- a/.gitignore
+++ b/.gitignore
@@ -234,3 +234,6 @@ public/app/plugins/**/dist/
public/mockServiceWorker.js
/e2e/test-plugins/*/dist
+
+# vite
+stats.html
diff --git a/pkg/api/dtos/index.go b/pkg/api/dtos/index.go
index 93d967e3402..f1403c3138e 100644
--- a/pkg/api/dtos/index.go
+++ b/pkg/api/dtos/index.go
@@ -40,6 +40,7 @@ type IndexViewData struct {
type EntryPointAssets struct {
ContentDeliveryURL string `json:"cdn,omitempty"`
JSFiles []EntryPointAsset `json:"jsFiles"`
+ PreloadJSFiles []EntryPointAsset `json:"preloadJsFiles"`
// CSSFiles []EntryPointAsset `json:"cssFiles"`
Dark string `json:"dark"`
Light string `json:"light"`
diff --git a/pkg/api/webassets/webassets.go b/pkg/api/webassets/webassets.go
index d78c9ba0ed6..8ebf45ce538 100644
--- a/pkg/api/webassets/webassets.go
+++ b/pkg/api/webassets/webassets.go
@@ -36,6 +36,8 @@ type ViteManifestEntry struct {
Src string `json:"src"`
}
+type Manifest map[string]ViteManifestEntry
+
type EntryPointInfo struct {
Assets struct {
JS []string `json:"js,omitempty"`
@@ -135,13 +137,14 @@ func readWebAssetsFromCDN(ctx context.Context, baseURL string) (*dtos.EntryPoint
}
func readWebAssets(r io.Reader) (*dtos.EntryPointAssets, error) {
- manifest := map[string]ViteManifestEntry{}
+ manifest := Manifest{}
if err := json.NewDecoder(r).Decode(&manifest); err != nil {
return nil, fmt.Errorf("failed to read assets-manifest.json %w", err)
}
// TODO: This is a temporary hack to get the entrypoints for the vite frontend loading.
var entryPointJSAssets []dtos.EntryPointAsset
+ var preloadJSAssets []dtos.EntryPointAsset
var darkCSS, lightCSS string
for _, entry := range manifest {
@@ -153,6 +156,7 @@ func readWebAssets(r io.Reader) (*dtos.EntryPointAssets, error) {
}
if strings.HasSuffix(entry.File, ".js") {
entryPointJSAssets = append(entryPointJSAssets, asset)
+ preloadJSAssets = getPreloadChunks(manifest, entry.Src)
}
if entry.Src == "sass/grafana.dark.scss" && entry.IsEntry {
darkCSS = entry.File
@@ -189,9 +193,11 @@ func readWebAssets(r io.Reader) (*dtos.EntryPointAssets, error) {
// }
rsp := &dtos.EntryPointAssets{
- JSFiles: entryPointJSAssets,
- Dark: darkCSS,
- Light: lightCSS,
+ JSFiles: entryPointJSAssets,
+ PreloadJSFiles: preloadJSAssets,
+ Dark: darkCSS,
+ Light: lightCSS,
+ // TODO: Need to figure this out. Ideally the swagger assets are built in a separate build process.
// Swagger: make([]dtos.EntryPointAsset, 0, len(entryPoints.Swagger.Assets.JS)),
// SwaggerCSSFiles: make([]dtos.EntryPointAsset, 0, len(entryPoints.Swagger.Assets.CSS)),
}
@@ -222,3 +228,41 @@ func readWebAssets(r io.Reader) (*dtos.EntryPointAssets, error) {
// }
return rsp, nil
}
+
+// Create a list of all the chunks that need to be preloaded for a given entrypoint.
+func getPreloadChunks(manifest Manifest, name string) []dtos.EntryPointAsset {
+ seen := make(map[string]bool)
+
+ var getImportedChunks func(chunk ViteManifestEntry) []dtos.EntryPointAsset
+
+ getImportedChunks = func(chunk ViteManifestEntry) []dtos.EntryPointAsset {
+ var chunks []dtos.EntryPointAsset
+
+ for _, file := range chunk.Imports {
+ importee, exists := manifest[file]
+ if !exists {
+ continue
+ }
+ if seen[file] {
+ continue
+ }
+ seen[file] = true
+
+ chunks = append(chunks, getImportedChunks(importee)...)
+
+ chunks = append(chunks, dtos.EntryPointAsset{
+ FilePath: importee.File,
+ Integrity: "",
+ })
+ }
+
+ return chunks
+ }
+
+ entryChunk, exists := manifest[name]
+ if !exists {
+ return nil
+ }
+
+ return getImportedChunks(entryChunk)
+}
diff --git a/pkg/api/webassets/webassets_test.go b/pkg/api/webassets/webassets_test.go
index 9d899eec874..60488544f91 100644
--- a/pkg/api/webassets/webassets_test.go
+++ b/pkg/api/webassets/webassets_test.go
@@ -24,7 +24,8 @@ func TestReadWebassets(t *testing.T) {
}
],
"dark": "public/build/grafana-BwD1GyB5.css",
- "light": "public/build/grafana-RC8BVZtE.css"
+ "light": "public/build/grafana-RC8BVZtE.css",
+ "preloadJsFiles": null
}`, string(dto))
assets.SetContentDeliveryURL("https://grafana-assets.grafana.net/grafana/10.3.0-64123/")
@@ -42,7 +43,8 @@ func TestReadWebassets(t *testing.T) {
}
],
"dark": "https://grafana-assets.grafana.net/grafana/10.3.0-64123/public/build/grafana-BwD1GyB5.css",
- "light": "https://grafana-assets.grafana.net/grafana/10.3.0-64123/public/build/grafana-RC8BVZtE.css"
+ "light": "https://grafana-assets.grafana.net/grafana/10.3.0-64123/public/build/grafana-RC8BVZtE.css",
+ "preloadJsFiles": null
}`, string(dto))
}
@@ -86,5 +88,6 @@ func TestReadWebassetsFromCDN(t *testing.T) {
],
"dark": "https://grafana-assets.grafana.net/grafana/10.3.0-64123/public/build/grafana.dark.b44253d019cd9cb46428.css",
"light": "https://grafana-assets.grafana.net/grafana/10.3.0-64123/public/build/grafana.light.e8e11c59b604d62836be.css"
+ "preloadJsFiles": null
}`, string(dto))
}
diff --git a/public/views/index.html b/public/views/index.html
index 9a0d061e5cd..a8c3b81b1de 100644
--- a/public/views/index.html
+++ b/public/views/index.html
@@ -29,6 +29,13 @@
performance.mark('frontend_boot_css_time_seconds');
+ [[range $asset := .Assets.PreloadJSFiles]]
+
+ [[end]]
+