From ba8263206094c2d421ac080092b2606ff80bdccb Mon Sep 17 00:00:00 2001 From: FredrikOseberg Date: Mon, 11 Aug 2025 20:09:35 +0200 Subject: [PATCH] fix: critical css --- website/src/css/critical.css | 143 ++++++++------------------ website/src/theme/OptimizedStyles.tsx | 44 ++++---- website/src/theme/Root.tsx | 14 +-- 3 files changed, 70 insertions(+), 131 deletions(-) diff --git a/website/src/css/critical.css b/website/src/css/critical.css index f78a60bb05..ac798eb3a5 100644 --- a/website/src/css/critical.css +++ b/website/src/css/critical.css @@ -1,14 +1,6 @@ /* Critical CSS - Inline for immediate rendering */ /* Only includes above-the-fold styles needed for initial paint */ - -:root { - --unleash-color-green: #1a4049; - --unleash-color-purple: #635dc5; - --ifm-font-family-base: "Sen", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif; - --ifm-font-size-base: 15px; - --ifm-background-color: #fff; - --ifm-font-color-base: #202021; -} +/* This CSS should not conflict with main styles - only prevent layout shift */ /* Prevent layout shift - reserve space */ html, body { @@ -17,117 +9,68 @@ html, body { overflow-x: hidden; } -/* Navbar space reservation */ +/* Minimal navbar space reservation - matches custom.css */ .navbar { - height: 56px; + height: 3.75rem; position: sticky; top: 0; z-index: 100; - background: var(--ifm-background-color); } -/* Main container - prevent CLS */ -.docMainContainer_TBSr, -main[class*="docMainContainer"] { - min-height: 100vh; - contain: layout style; - display: block; - padding: 0 1rem; - max-width: 100%; +/* Navbar positioning for desktop with sidebar */ +@media (min-width: 997px) { + .navbar { + padding-left: 314px; + justify-content: center; + } + + .navbar .navbar__brand { + display: none; + } } -/* Content wrapper */ -.container { - max-width: 1140px; - margin: 0 auto; - padding: 0 1rem; +/* Minimal layout structure to prevent major shifts */ +main { + min-height: calc(100vh - 3.75rem); + display: flex; + justify-content: center; } -/* Basic typography for immediate readability */ -h1, h2, h3, h4, h5, h6 { - font-family: var(--ifm-font-family-base); - font-weight: 700; - line-height: 1.2; - color: var(--ifm-font-color-base); - margin-top: 0; - margin-bottom: 0.5rem; -} +/* Sidebar styling to match original design */ +@media (min-width: 997px) { + aside.theme-doc-sidebar-container { + border-right: none; + background: var(--ifm-background-color, #fff); + z-index: 200; + position: relative; + width: 300px; + min-width: 300px; + } -h1 { font-size: 2.5rem; } -h2 { font-size: 2rem; } -h3 { font-size: 1.5rem; } + aside.theme-doc-sidebar-container > div > div { + padding-top: 0; + } -p { - font-family: var(--ifm-font-family-base); - font-size: var(--ifm-font-size-base); - line-height: 1.6; - color: var(--ifm-font-color-base); - margin: 0 0 1rem; -} - -/* Links */ -a { - color: var(--unleash-color-purple); - text-decoration: none; -} - -/* Code blocks */ -code { - font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - font-size: 0.875em; - background: rgba(99, 93, 197, 0.1); - padding: 0.125rem 0.25rem; - border-radius: 0.25rem; -} - -/* Sidebar reservation */ -.docSidebarContainer_YfHR, -aside[class*="docSidebarContainer"] { - width: 250px; - position: sticky; - top: 56px; - height: calc(100vh - 56px); - overflow-y: auto; -} - -/* Article content */ -article { - min-height: 50vh; - padding: 2rem 0; -} - -/* Prevent FOUC for theme */ -[data-theme="dark"] { - --ifm-background-color: #222130; - --ifm-font-color-base: #f5f5f5; -} - -/* Loading skeleton animation */ -@keyframes skeleton-loading { - 0% { background-position: 200% 0; } - 100% { background-position: -200% 0; } -} - -.skeleton { - background: linear-gradient( - 90deg, - rgba(190, 190, 190, 0.2) 25%, - rgba(190, 190, 190, 0.3) 50%, - rgba(190, 190, 190, 0.2) 75% - ); - background-size: 200% 100%; - animation: skeleton-loading 1.5s infinite; + /* Sidebar brand logo space */ + .sidebar-brand-logo { + content: ""; + display: flex; + width: 300px; + height: 36px; + margin-top: 10px; + margin-left: 10px; + background-size: contain; + background-repeat: no-repeat; + } } /* Mobile responsiveness */ @media (max-width: 996px) { - .docSidebarContainer_YfHR, aside[class*="docSidebarContainer"] { display: none; } - .docMainContainer_TBSr, - main[class*="docMainContainer"] { + main { width: 100%; padding: 0 0.5rem; } diff --git a/website/src/theme/OptimizedStyles.tsx b/website/src/theme/OptimizedStyles.tsx index 4b75c29103..b9cfa69afd 100644 --- a/website/src/theme/OptimizedStyles.tsx +++ b/website/src/theme/OptimizedStyles.tsx @@ -88,11 +88,16 @@ export default function OptimizedStyles() { const allStylesheets = document.querySelectorAll('link[rel="stylesheet"]'); allStylesheets.forEach((stylesheet) => { const link = stylesheet as HTMLLinkElement; - // Skip critical styles - if (link.href.includes('critical') || link.getAttribute('data-critical') === 'true') { + // Skip critical styles and any styles that are already optimized + if (link.href.includes('critical') || + link.getAttribute('data-critical') === 'true' || + link.getAttribute('data-optimized') === 'true') { return; } + // Mark as optimized to avoid re-processing + link.setAttribute('data-optimized', 'true'); + // Convert blocking stylesheets to non-blocking if (!link.media || link.media === 'all') { // Temporarily set to print to make non-blocking @@ -115,16 +120,17 @@ export default function OptimizedStyles() { mutation.addedNodes.forEach((node) => { if (node.nodeName === 'LINK') { const link = node as HTMLLinkElement; - if (link.rel === 'stylesheet' && !link.getAttribute('data-optimized')) { + if (link.rel === 'stylesheet' && + !link.getAttribute('data-optimized') && + !link.getAttribute('data-critical') && + !link.href.includes('critical')) { link.setAttribute('data-optimized', 'true'); - // Make it non-blocking if it's not critical - if (!link.href.includes('critical')) { - const originalMedia = link.media || 'all'; - link.media = 'print'; - link.onload = function() { - (this as HTMLLinkElement).media = originalMedia; - }; - } + // Make it non-blocking + const originalMedia = link.media || 'all'; + link.media = 'print'; + link.onload = function() { + (this as HTMLLinkElement).media = originalMedia; + }; } } }); @@ -144,17 +150,7 @@ export default function OptimizedStyles() { }; }, []); - // Inline critical CSS for immediate rendering - return ( -