Skip to content

Commit

Permalink
Avoid re-prefetching stylesheets for active routes during a revalidat…
Browse files Browse the repository at this point in the history
…ion (#6679)
  • Loading branch information
brophdawg11 committed Jul 6, 2023
1 parent efcea9e commit eccc180
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/stylesheet-re-prefetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/react": patch
---

Avoid re-prefetching stylesheets for active routes during a revalidation
92 changes: 92 additions & 0 deletions integration/prefetch-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,3 +342,95 @@ test.describe("prefetch=viewport", () => {
await expect(page.locator("div link")).toHaveCount(0);
});
});

test.describe("other scenarios", () => {
let fixture: Fixture;
let appFixture: AppFixture;

test.afterAll(() => {
appFixture?.close();
});

test("does not add prefetch links for stylesheets already in the DOM (active routes)", async ({
page,
}) => {
fixture = await createFixture({
config: {
future: { v2_routeConvention: true },
},
files: {
"app/root.jsx": js`
import { Links, Meta, Scripts, useFetcher } from "@remix-run/react";
import globalCss from "./global.css";
export function links() {
return [{ rel: "stylesheet", href: globalCss }];
}
export async function action() {
return null;
}
export async function loader() {
return null;
}
export default function Root() {
let fetcher = useFetcher();
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<button
id="submit-fetcher"
onClick={() => fetcher.submit({}, { method: 'post' })}>
Submit Fetcher
</button>
<p id={"fetcher-state--" + fetcher.state}>{fetcher.state}</p>
<Scripts />
</body>
</html>
);
}
`,

"app/global.css": `
body {
background-color: black;
color: white;
}
`,

"app/routes/_index.jsx": js`
export default function() {
return <h2 className="index">Index</h2>;
}
`,
},
});
appFixture = await createAppFixture(fixture);
let requests: { type: string; url: string }[] = [];

page.on("request", (req) => {
requests.push({
type: req.resourceType(),
url: req.url(),
});
});

let app = new PlaywrightFixture(appFixture, page);
await app.goto("/");
await page.click("#submit-fetcher");
await page.waitForSelector("#fetcher-state--idle");
// We should not send a second request for this root stylesheet that's
// already been rendered in the DOM
let stylesheets = requests.filter(
(r) => r.type === "stylesheet" && /\/global-[a-z0-9]+\.css/i.test(r.url)
);
expect(stylesheets.length).toBe(1);
});
});
7 changes: 5 additions & 2 deletions packages/remix-react/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,12 @@ export async function prefetchStyleLinks(
}
}

// don't block for non-matching media queries
// don't block for non-matching media queries, or for stylesheets that are
// already in the DOM (active route revalidations)
let matchingLinks = styleLinks.filter(
(link) => !link.media || window.matchMedia(link.media).matches
(link) =>
(!link.media || window.matchMedia(link.media).matches) &&
!document.querySelector(`link[rel="stylesheet"][href="${link.href}"]`)
);

await Promise.all(matchingLinks.map(prefetchStyleLink));
Expand Down

0 comments on commit eccc180

Please sign in to comment.