@ecopages/browser-router 0.2.0-alpha.20 → 0.2.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -16,6 +16,7 @@ All notable changes to `@ecopages/browser-router` are documented here.
16
16
  - Fixed mixed-runtime document ownership, script reruns, persisted head scripts, and client-managed `<html>` state during browser-router navigations.
17
17
  - Fixed skipped View Transition lifecycle aborts leaking as unhandled browser-router test errors.
18
18
  - Fixed body morph swaps retaining stale content when pages contain duplicate `id` attributes by limiting morphdom keying to explicitly persisted nodes.
19
+ - Fixed browser-router stylesheet prefetching to warm future page CSS without injecting unused `preload` hints that trigger browser console warnings.
19
20
 
20
21
  ### Refactoring
21
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecopages/browser-router",
3
- "version": "0.2.0-alpha.20",
3
+ "version": "0.2.0-alpha.21",
4
4
  "description": "Client-side router for Ecopages with view transitions support",
5
5
  "keywords": [
6
6
  "ecopages",
@@ -35,7 +35,7 @@
35
35
  "morphdom": "^2.7.8"
36
36
  },
37
37
  "peerDependencies": {
38
- "@ecopages/core": "0.2.0-alpha.20"
38
+ "@ecopages/core": "0.2.0-alpha.21"
39
39
  },
40
40
  "types": "./src/index.d.ts"
41
41
  }
@@ -14,6 +14,7 @@ export interface PrefetchOptions {
14
14
  export declare class PrefetchManager {
15
15
  private options;
16
16
  private prefetched;
17
+ private prefetchedStylesheets;
17
18
  private htmlCache;
18
19
  private observer;
19
20
  private hoverTimeouts;
@@ -159,12 +160,14 @@ export declare class PrefetchManager {
159
160
  /**
160
161
  * Prefetches stylesheets discovered in HTML content.
161
162
  *
162
- * Parses the HTML to find stylesheet links, then creates preload hints
163
- * for stylesheets not already present in the current document. This ensures
164
- * styles are cached before navigation to prevent FOUC.
163
+ * Parses the HTML to find stylesheet links, then warms the HTTP cache for
164
+ * stylesheets not already present in the current document. This keeps future
165
+ * navigation CSS warm without injecting `preload` hints that browsers expect
166
+ * the current page to consume immediately.
165
167
  *
166
168
  * @param html - The raw HTML string to parse
167
169
  * @param url - The base URL for resolving relative stylesheet paths
168
170
  */
169
171
  private prefetchStylesheets;
172
+ private prefetchStylesheet;
170
173
  }
@@ -8,6 +8,7 @@ const DEFAULT_PREFETCH_OPTIONS = {
8
8
  class PrefetchManager {
9
9
  options;
10
10
  prefetched = /* @__PURE__ */ new Set();
11
+ prefetchedStylesheets = /* @__PURE__ */ new Set();
11
12
  htmlCache = /* @__PURE__ */ new Map();
12
13
  observer = null;
13
14
  hoverTimeouts = /* @__PURE__ */ new Map();
@@ -346,9 +347,10 @@ class PrefetchManager {
346
347
  /**
347
348
  * Prefetches stylesheets discovered in HTML content.
348
349
  *
349
- * Parses the HTML to find stylesheet links, then creates preload hints
350
- * for stylesheets not already present in the current document. This ensures
351
- * styles are cached before navigation to prevent FOUC.
350
+ * Parses the HTML to find stylesheet links, then warms the HTTP cache for
351
+ * stylesheets not already present in the current document. This keeps future
352
+ * navigation CSS warm without injecting `preload` hints that browsers expect
353
+ * the current page to consume immediately.
352
354
  *
353
355
  * @param html - The raw HTML string to parse
354
356
  * @param url - The base URL for resolving relative stylesheet paths
@@ -358,20 +360,28 @@ class PrefetchManager {
358
360
  const doc = parser.parseFromString(`<base href="${url.href}">${html}`, "text/html");
359
361
  const existingHrefs = /* @__PURE__ */ new Set([
360
362
  ...Array.from(document.querySelectorAll('link[rel="stylesheet"]')).map((l) => l.href),
361
- ...Array.from(document.querySelectorAll('link[rel="preload"][as="style"]')).map(
362
- (l) => l.href
363
- )
363
+ ...this.prefetchedStylesheets
364
364
  ]);
365
365
  const newStylesheets = doc.querySelectorAll('link[rel="stylesheet"]');
366
+ const stylesheetFetches = [];
366
367
  for (const link of newStylesheets) {
367
368
  if (!existingHrefs.has(link.href)) {
368
- const preloadLink = document.createElement("link");
369
- preloadLink.rel = "preload";
370
- preloadLink.as = "style";
371
- preloadLink.href = link.href;
372
- document.head.appendChild(preloadLink);
369
+ existingHrefs.add(link.href);
370
+ this.prefetchedStylesheets.add(link.href);
371
+ stylesheetFetches.push(this.prefetchStylesheet(link.href));
373
372
  }
374
373
  }
374
+ await Promise.allSettled(stylesheetFetches);
375
+ }
376
+ async prefetchStylesheet(href) {
377
+ try {
378
+ await fetch(href, {
379
+ credentials: "same-origin",
380
+ priority: "low"
381
+ });
382
+ } catch {
383
+ this.prefetchedStylesheets.delete(href);
384
+ }
375
385
  }
376
386
  }
377
387
  export {