diff --git a/Cargo.lock b/Cargo.lock
index 0b0eed4..966e8ae 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2948,7 +2948,7 @@ dependencies = [
[[package]]
name = "portal"
-version = "0.3.31"
+version = "0.3.32"
dependencies = [
"anyhow",
"arc-swap",
diff --git a/src/app.rs b/src/app.rs
index efdb7c6..052fef5 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -40,6 +40,20 @@ pub fn shell(options: LeptosOptions) -> impl IntoView {
// once loaded via / on Safari/iOS.
+ // Fonts hide behind the stylesheet: the browser must
+ // fetch and parse CSS before it discovers them. The
+ // latin subset is on every page's critical path, so
+ // announce it up front; latin-ext and vietnamese stay
+ // unicode-range-gated and load only when script needs
+ // them - preloading those would tax everyone for a few.
+ // (Font preloads require crossorigin even same-origin.)
+
// Server-side, so it can read hash.txt and link the
// content-hashed stylesheet (hash-files = true).
@@ -89,6 +103,19 @@ pub fn App() -> impl IntoView {
.and_then(|s| s.stylesheet)
.map(|p| format!("/site/{p}"))
});
+ // The wordmark paints in the hero on first view; announcing it in
+ // the head starts the fetch during hydration instead of after. On
+ // redoal.com it lives on the content host, so a preconnect opens
+ // that TLS session while the preload is still queued.
+ let wordmark_href = Memo::new(move |_| {
+ site.get().and_then(|r| r.ok()).and_then(|s| s.wordmark)
+ });
+ let wordmark_origin = Memo::new(move |_| {
+ wordmark_href.get().and_then(|w| {
+ let rest = w.strip_prefix("https://")?;
+ Some(format!("https://{}", rest.split('/').next()?))
+ })
+ });
// A content-shipped favicon overrides the built-in one; injected
// into the head after the static defaults, so it wins.
let favicon = Memo::new(move |_| {
@@ -100,6 +127,8 @@ pub fn App() -> impl IntoView {
view! {
+ {move || wordmark_origin.get().map(|href| view! { })}
+ {move || wordmark_href.get().map(|href| view! { })}
{move || custom_css.get().map(|href| view! { })}
{move || favicon.get().map(|href| view! { })}