Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,10 @@ src/*.html

# SSL certificates
*.pem

/guest-profiles
/benchmark-results/**

# Next.js example app
examples/nextjs-rsc-app/node_modules/
examples/nextjs-rsc-app/.next/
532 changes: 532 additions & 0 deletions OPTIMIZATION.md

Large diffs are not rendered by default.

462 changes: 454 additions & 8 deletions crates/common/src/html_processor.rs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!doctype html>
<html lang="en">
<head>
<meta charSet="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Blog Post - Next.js RSC Test App</title>
<link rel="stylesheet" href="https://origin.example.com/styles/main.css"/>
<link rel="preload" as="image" href="https://origin.example.com/images/blog/hello-world/hero.jpg"/>
</head>
<body>
<nav><a href="https://origin.example.com/">Home</a><a href="https://origin.example.com/about">About</a><a href="https://origin.example.com/blog/hello-world">Blog</a></nav>
<main>
<article>
<h1>Blog Post: hello-world</h1>
<div><span>Published on </span><a href="https://origin.example.com/blog">the blog</a></div>
<div><img src="https://origin.example.com/images/blog/hello-world/hero.jpg" alt="Hero image for hello-world" width="1200" height="630"/></div>
<p>Paragraph 1: This content references https://origin.example.com/article/1 and includes links to https://origin.example.com/category/tech.</p>
<p>Paragraph 2: This content references https://origin.example.com/article/2 and includes links to https://origin.example.com/category/tech.</p>
<p>Paragraph 3: This content references https://origin.example.com/article/3 and includes links to https://origin.example.com/category/tech.</p>
<p>Paragraph 4: This content references https://origin.example.com/article/4 and includes links to https://origin.example.com/category/tech.</p>
<p>Paragraph 5: This content references https://origin.example.com/article/5 and includes links to https://origin.example.com/category/tech.</p>
<nav><h2>Related Posts</h2><ul><li><a href="https://origin.example.com/blog/related-post-1">Related Post 1</a></li><li><a href="https://origin.example.com/blog/related-post-2">Related Post 2</a></li><li><a href="https://origin.example.com/blog/related-post-3">Related Post 3</a></li></ul></nav>
<footer><a href="https://origin.example.com/blog/hello-world/comments">View Comments</a><a href="https://origin.example.com/blog/hello-world/share">Share</a></footer>
</article>
</main>
<footer><a href="https://origin.example.com/privacy">Privacy Policy</a><a href="https://origin.example.com/terms">Terms of Service</a></footer>
<script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script>
<script>self.__next_f.push([1,"8:{\"title\":\"hello-world\",\"heroUrl\":\"https://origin.example.com/images/blog/hello-world/hero.jpg\"}\n"])</script>
<script>self.__next_f.push([1,"9:{\"url\":\"https://origin.example.com/blog/related-post-1\",\"title\":\"Related Post 1\"}\na:{\"url\":\"https://origin.example.com/blog/related-post-2\",\"title\":\"Related Post 2\"}\nb:{\"url\":\"https://origin.example.com/blog/related-post-3\",\"title\":\"Related Post 3\"}\n"])</script>
<script>self.__next_f.push([1,"c:T12c,{\"paragraphs\":[\"Paragraph 1 references https://origin.example.com/article/1\",\"Paragraph 2 references https://origin.example.com/article/2\",\"Paragraph 3 references https://origin.example.com/article/3\"],\"categoryUrl\":\"https://origin.example.com/category/tech\",\"authorUrl\":\"https://origin.example.com/author/staff\"}"])</script>
<script>self.__next_f.push([1,"d:{\"commentsUrl\":\"https://origin.example.com/blog/hello-world/comments\",\"shareUrl\":\"https://origin.example.com/blog/hello-world/share\"}\n"])</script>
<script>self.__next_f.push([1,"e:Te5,{\"nav\":[{\"href\":\"https://origin.example.com/blog/related-post-1\",\"text\":\"Related 1\"},{\"href\":\"https://origin.example.com/blog/related-post-2\",\"text\":\"Related 2\"}],\"footer\":\"https://origin.example.com/privacy\"}"])</script>
<script src="https://origin.example.com/_next/static/chunks/main-abc123.js" async=""></script>
<script src="https://origin.example.com/_next/static/chunks/webpack-def456.js" async=""></script>
<script src="https://origin.example.com/_next/static/chunks/app-layout-ghi789.js" async=""></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!doctype html>
<html lang="en">
<head>
<meta charSet="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Next.js RSC Test App</title>
<link rel="stylesheet" href="https://origin.example.com/styles/main.css"/>
<link rel="icon" href="https://origin.example.com/favicon.ico"/>
<link rel="preload" as="script" href="https://origin.example.com/_next/static/chunks/main-abc123.js"/>
<link rel="preload" as="script" href="https://origin.example.com/_next/static/chunks/webpack-def456.js"/>
</head>
<body>
<nav><a href="https://origin.example.com/">Home</a><a href="https://origin.example.com/about">About</a><a href="https://origin.example.com/blog/hello-world">Blog</a></nav>
<main>
<div>
<h1>Welcome to the Test App</h1>
<p>Visit our <a href="https://origin.example.com/getting-started">getting started guide</a>.</p>
<ul>
<li><a href="https://origin.example.com/docs">Documentation</a><span> - Learn about the platform</span></li>
<li><a href="https://origin.example.com/api/v1">API Reference</a><span> - Explore the REST API</span></li>
<li><a href="https://origin.example.com/dashboard">Dashboard</a><span> - View your analytics</span></li>
</ul>
<img src="https://origin.example.com/images/hero.jpg" alt="Hero" width="800" height="400"/>
</div>
</main>
<footer><a href="https://origin.example.com/privacy">Privacy Policy</a><a href="https://origin.example.com/terms">Terms of Service</a></footer>
<script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script>
<script>self.__next_f.push([1,"1:{\"url\":\"https://origin.example.com/docs\",\"title\":\"Documentation\"}\n"])</script>
<script>self.__next_f.push([1,"2:{\"url\":\"https://origin.example.com/api/v1\",\"title\":\"API Reference\"}\n"])</script>
<script>self.__next_f.push([1,"3:{\"url\":\"https://origin.example.com/dashboard\",\"title\":\"Dashboard\"}\n"])</script>
<script src="https://origin.example.com/_next/static/chunks/main-abc123.js" async=""></script>
<script src="https://origin.example.com/_next/static/chunks/webpack-def456.js" async=""></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<html lang="en">
<head>
<meta charSet="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>About Us - Next.js RSC Test App</title>
<link rel="stylesheet" href="https://origin.example.com/styles/main.css"/>
</head>
<body>
<nav><a href="https://origin.example.com/">Home</a><a href="https://origin.example.com/about">About</a></nav>
<main>
<div>
<h1>About Us</h1>
<p>We are building at <a href="https://origin.example.com/about">origin.example.com</a>.</p>
<section>
<h2>Our Team</h2>
<div><img src="https://origin.example.com/avatars/alice.jpg" alt="Alice Johnson" width="64" height="64"/><h3><a href="https://origin.example.com/team/alice">Alice Johnson</a></h3><p>Engineering Lead</p></div>
<div><img src="https://origin.example.com/avatars/bob.jpg" alt="Bob Smith" width="64" height="64"/><h3><a href="https://origin.example.com/team/bob">Bob Smith</a></h3><p>Product Manager</p></div>
</section>
</div>
</main>
<footer><a href="https://origin.example.com/privacy">Privacy Policy</a></footer>
<script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script>
<script>self.__next_f.push([1,"4:{\"name\":\"Alice\",\"profileUrl\":\"https://origin.example.com/team/alice\"}\n5:T87,{\"html\":\"\\u003cdiv\\u003e\\u003ca href=\\\"https://origin.example.com/team/alice\\\"\\u003eAlice Johnson\\u003c/a\\u003e\\u003c/div\\u003e\"}"])</script>
<script>self.__next_f.push([1,"6:{\"name\":\"Bob\",\"profileUrl\":\"https://origin.example.com/team/bob\"}\n"])</script>
<script>self.__next_f.push([1,"7:T83,{\"html\":\"\\u003cdiv\\u003e\\u003ca href=\\\"https://origin.example.com/team/bob\\\"\\u003eBob Smith\\u003c/a\\u003e\\u003c/div\\u003e\"}"])</script>
<script src="https://origin.example.com/_next/static/chunks/main-abc123.js" async=""></script>
</body>
</html>
38 changes: 38 additions & 0 deletions crates/common/src/integrations/nextjs/fixtures/non-rsc-page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Static Page - No RSC</title>
<link rel="stylesheet" href="https://origin.example.com/styles/main.css"/>
<link rel="icon" href="https://origin.example.com/favicon.ico"/>
</head>
<body>
<nav>
<a href="https://origin.example.com/">Home</a>
<a href="https://origin.example.com/about">About</a>
<a href="https://origin.example.com/contact">Contact</a>
</nav>
<main>
<h1>Welcome</h1>
<p>This is a static page without any React Server Components.</p>
<p>It contains regular HTML with URLs that should be rewritten:</p>
<ul>
<li><a href="https://origin.example.com/docs">Documentation</a></li>
<li><a href="https://origin.example.com/api">API</a></li>
<li><a href="https://origin.example.com/support">Support</a></li>
</ul>
<img src="https://origin.example.com/images/banner.jpg" alt="Banner" width="960" height="320"/>
<form action="https://origin.example.com/search" method="get">
<input type="text" name="q" placeholder="Search..."/>
<button type="submit">Search</button>
</form>
</main>
<footer>
<a href="https://origin.example.com/privacy">Privacy</a>
<a href="https://origin.example.com/terms">Terms</a>
</footer>
<script>console.log("analytics loaded");</script>
<script>window.dataLayer = window.dataLayer || []; window.dataLayer.push({"page": "static"});</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!DOCTYPE html><!--_0Lth74qNT2E7WJR76kUR--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="https://origin.example.com/avatars/alice.jpg"/><link rel="preload" as="image" href="https://origin.example.com/avatars/bob.jpg"/><link rel="preload" as="image" href="https://origin.example.com/avatars/carol.jpg"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-078f6dfb37dff419.js"/><script src="/_next/static/chunks/4bd1b696-c023c6e3521b1417.js" async=""></script><script src="/_next/static/chunks/255-632950a301ed81a4.js" async=""></script><script src="/_next/static/chunks/main-app-00fb03c24437bd47.js" async=""></script><link rel="icon" href="https://origin.example.com/favicon.ico"/><title>Next.js RSC Test App</title><meta name="description" content="Minimal app for testing Trusted Server RSC integration"/><link rel="stylesheet" href="https://origin.example.com/styles/main.css"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><nav><a href="https://origin.example.com/">Home</a><a href="https://origin.example.com/about">About</a><a href="https://origin.example.com/blog/hello-world">Blog</a></nav><main><div><h1>About Us</h1><p>We are building at<!-- --> <a href="https://origin.example.com/about">origin.example.com</a>.</p><section><h2>Our Team</h2><div><img src="https://origin.example.com/avatars/alice.jpg" alt="Alice Johnson" width="64" height="64"/><h3><a href="https://origin.example.com/team/alice">Alice Johnson</a></h3><p>Engineering Lead</p></div><div><img src="https://origin.example.com/avatars/bob.jpg" alt="Bob Smith" width="64" height="64"/><h3><a href="https://origin.example.com/team/bob">Bob Smith</a></h3><p>Product Manager</p></div><div><img src="https://origin.example.com/avatars/carol.jpg" alt="Carol Williams" width="64" height="64"/><h3><a href="https://origin.example.com/team/carol">Carol Williams</a></h3><p>Designer</p></div></section><section><h2>Resources</h2><ul><li><a href="https://origin.example.com/blog">Blog</a></li><li><a href="https://origin.example.com/careers">Careers</a></li><li><a href="https://origin.example.com/contact">Contact</a></li></ul></section></div><!--$--><!--/$--></main><footer><a href="https://origin.example.com/privacy">Privacy Policy</a><a href="https://origin.example.com/terms">Terms of Service</a></footer><script src="/_next/static/chunks/webpack-078f6dfb37dff419.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[9766,[],\"\"]\n3:I[8924,[],\"\"]\n4:I[4431,[],\"OutletBoundary\"]\n6:I[5278,[],\"AsyncMetadataOutlet\"]\n8:I[4431,[],\"ViewportBoundary\"]\na:I[4431,[],\"MetadataBoundary\"]\nb:\"$Sreact.suspense\"\nd:I[7150,[],\"\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"-0Lth74qNT2E7WJR76kUR\",\"p\":\"\",\"c\":[\"\",\"about\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"about\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"link\",null,{\"rel\":\"stylesheet\",\"href\":\"https://origin.example.com/styles/main.css\"}],[\"$\",\"link\",null,{\"rel\":\"icon\",\"href\":\"https://origin.example.com/favicon.ico\"}]]}],[\"$\",\"body\",null,{\"children\":[[\"$\",\"nav\",null,{\"children\":[[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/\",\"children\":\"Home\"}],[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/about\",\"children\":\"About\"}],[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/blog/hello-world\",\"children\":\"Blog\"}]]}],[\"$\",\"main\",null,{\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}],[\"$\",\"footer\",null,{\"children\":[[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/privacy\",\"children\":\"Privacy Policy\"}],[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/terms\",\"children\":\"Terms of Service\"}]]}]]}]]}]]}],{\"children\":[\"about\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"div\",null,{\"children\":[[\"$\",\"h1\",null,{\"children\":\"About Us\"}],[\"$\",\"p\",null,{\"children\":[\"We are building at\",\" \",[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/about\",\"children\":\"origin.example.com\"}],\".\"]}],[\"$\",\"section\",null,{\"children\":[[\"$\",\"h2\",null,{\"children\":\"Our Team\"}],[[\"$\",\"div\",\"Alice Johnson\",{\"children\":[[\"$\",\"img\",null,{\"src\":\"https://origin.example.com/avatars/alice.jpg\",\"alt\":\"Alice Johnson\",\"width\":64,\"height\":64}],[\"$\",\"h3\",null,{\"children\":[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/team/alice\",\"children\":\"Alice Johnson\"}]}],[\"$\",\"p\",null,{\"children\":\"Engineering Lead\"}]]}],[\"$\",\"div\",\"Bob Smith\",{\"children\":[[\"$\",\"img\",null,{\"src\":\"https://origin.example.com/avatars/bob.jpg\",\"alt\":\"Bob Smith\",\"width\":64,\"height\":64}],[\"$\",\"h3\",null,{\"children\":[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/team/bob\",\"children\":\"Bob Smith\"}]}],[\"$\",\"p\",null,{\"children\":\"Product Manager\"}]]}],[\"$\",\"div\",\"Carol Williams\",{\"children\":[[\"$\",\"img\",null,{\"src\":\"https://origin.example.com/avatars/carol.jpg\",\"alt\":\"Carol Williams\",\"width\":64,\"height\":64}],[\"$\",\"h3\",null,{\"children\":[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/team/carol\",\"children\":\"Carol Williams\"}]}],[\"$\",\"p\",null,{\"children\":\"Designer\"}]]}]]]}],[\"$\",\"section\",null,{\"children\":[[\"$\",\"h2\",null,{\"children\":\"Resources\"}],[\"$\",\"ul\",null,{\"children\":[[\"$\",\"li\",null,{\"children\":[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/blog\",\"children\":\"Blog\"}]}],[\"$\",\"li\",null,{\"children\":[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/careers\",\"children\":\"Careers\"}]}],[\"$\",\"li\",null,{\"children\":[\"$\",\"a\",null,{\"href\":\"https://origin.example.com/contact\",\"children\":\"Contact\"}]}]]}]]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$L5\",[\"$\",\"$L6\",null,{\"promise\":\"$@7\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],null],[\"$\",\"$La\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$b\",null,{\"fallback\":null,\"children\":\"$Lc\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,"7:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Next.js RSC Test App\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Minimal app for testing Trusted Server RSC integration\"}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"c:\"$7:metadata\"\n"])</script></body></html>

Large diffs are not rendered by default.

Loading