From 4b71c038d570541c07bb9c2392c57e0010d29715 Mon Sep 17 00:00:00 2001 From: Alex Bronstein <12581-effulgentsia@users.noreply.drupalcode.org> Date: Tue, 25 Feb 2025 20:20:15 -0800 Subject: [PATCH 1/2] Render block astro islands --- src/Element/AstroIsland.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Element/AstroIsland.php b/src/Element/AstroIsland.php index c72ca21401..bab88201ae 100644 --- a/src/Element/AstroIsland.php +++ b/src/Element/AstroIsland.php @@ -164,6 +164,18 @@ final class AstroIsland extends RenderElementBase { props="{{ __aie_props }}" ssr="" client="only" opts="{{ __aie_opts }}">'; + + // Reduce layout shift by blocking further document rendering until the + // renderer-url and component-url scripts are loaded, so that fetching them + // doesn't add delay between a rendering with the island blank and the + // hydrated rendering. This doesn't eliminate layout shift entirely, + // because with Astro's client="only" directive, Astro waits until the + // entire page is loaded before hydrating islands. + // @todo Investigate if it's possible to hydrate islands immediately + // after the <astro-island> element is parsed rather than on page load. + $template .= '<script type="module" src="{{ __aie_renderer }}" blocking="render"></script>'; + $template .= '<script type="module" src="{{ __aie_component_url }}" blocking="render"></script>'; + foreach ($slot_names as $slot_name) { // Prevent XSS via malicious render array. $escaped_slot_name = Html::escape((string) $slot_name); -- GitLab From 78d2e1bfc6609ea99def4f2fc40c0470eaf91dd1 Mon Sep 17 00:00:00 2001 From: Alex Bronstein <12581-effulgentsia@users.noreply.drupalcode.org> Date: Wed, 26 Feb 2025 09:57:52 -0800 Subject: [PATCH 2/2] Fixed test --- tests/src/Kernel/DataType/ComponentTreeHydratedTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Kernel/DataType/ComponentTreeHydratedTest.php b/tests/src/Kernel/DataType/ComponentTreeHydratedTest.php index cfc7d04390..8de1ac5b54 100644 --- a/tests/src/Kernel/DataType/ComponentTreeHydratedTest.php +++ b/tests/src/Kernel/DataType/ComponentTreeHydratedTest.php @@ -905,7 +905,7 @@ HTML, renderer-url="::XB_DIR_BASE_URL::/ui/lib/astro-hydration/dist/client.js" props="{"text":["raw","Hello, from a \"code component\"!"]}" ssr="" client="only" - opts="{"name":"My First Code Component","value":"preact"}"></astro-island><!-- xb-end-uuid-js-component --><!-- xb-start-uuid-last-in-tree --><div data-component-id="xb_test_sdc:props-no-slots" style="font-family: Helvetica, Arial, sans-serif; width: 100%; height: 100vh; background-color: #f5f5f5; display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; padding: 20px; box-sizing: border-box;"> + opts="{"name":"My First Code Component","value":"preact"}"><script type="module" src="::XB_DIR_BASE_URL::/ui/lib/astro-hydration/dist/client.js" blocking="render"></script><script type="module" src="::SITE_DIR_BASE_URL::/files/astro-island/STNRn46UCAs1xJCb2kgPiEOEZp0R24B5qjtHOsyYT-g.js" blocking="render"></script></astro-island><!-- xb-end-uuid-js-component --><!-- xb-start-uuid-last-in-tree --><div data-component-id="xb_test_sdc:props-no-slots" style="font-family: Helvetica, Arial, sans-serif; width: 100%; height: 100vh; background-color: #f5f5f5; display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; padding: 20px; box-sizing: border-box;"> <h1 style="font-size: 3em; margin: 0.5em 0; color: #333;"><!-- xb-prop-start-uuid-last-in-tree/heading -->Hello, from slot <LAST ONE>!<!-- xb-prop-end-uuid-last-in-tree/heading --></h1> </div> <!-- xb-end-uuid-last-in-tree --><!-- xb-slot-end-uuid-level-2/the_body --> -- GitLab