1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-05 17:53:12 +02:00

fix: critical css

This commit is contained in:
FredrikOseberg 2025-08-11 20:09:35 +02:00
parent b4ad51659b
commit ba82632060
No known key found for this signature in database
GPG Key ID: 282FD8A6D8F9BCF0
3 changed files with 70 additions and 131 deletions

View File

@ -1,14 +1,6 @@
/* Critical CSS - Inline for immediate rendering */ /* Critical CSS - Inline for immediate rendering */
/* Only includes above-the-fold styles needed for initial paint */ /* Only includes above-the-fold styles needed for initial paint */
/* This CSS should not conflict with main styles - only prevent layout shift */
: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;
}
/* Prevent layout shift - reserve space */ /* Prevent layout shift - reserve space */
html, body { html, body {
@ -17,117 +9,68 @@ html, body {
overflow-x: hidden; overflow-x: hidden;
} }
/* Navbar space reservation */ /* Minimal navbar space reservation - matches custom.css */
.navbar { .navbar {
height: 56px; height: 3.75rem;
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 100; z-index: 100;
background: var(--ifm-background-color);
} }
/* Main container - prevent CLS */ /* Navbar positioning for desktop with sidebar */
.docMainContainer_TBSr, @media (min-width: 997px) {
main[class*="docMainContainer"] { .navbar {
min-height: 100vh; padding-left: 314px;
contain: layout style; justify-content: center;
display: block; }
padding: 0 1rem;
max-width: 100%; .navbar .navbar__brand {
display: none;
}
} }
/* Content wrapper */ /* Minimal layout structure to prevent major shifts */
.container { main {
max-width: 1140px; min-height: calc(100vh - 3.75rem);
margin: 0 auto; display: flex;
padding: 0 1rem; justify-content: center;
} }
/* Basic typography for immediate readability */ /* Sidebar styling to match original design */
h1, h2, h3, h4, h5, h6 { @media (min-width: 997px) {
font-family: var(--ifm-font-family-base); aside.theme-doc-sidebar-container {
font-weight: 700; border-right: none;
line-height: 1.2; background: var(--ifm-background-color, #fff);
color: var(--ifm-font-color-base); z-index: 200;
margin-top: 0; position: relative;
margin-bottom: 0.5rem; width: 300px;
} min-width: 300px;
}
h1 { font-size: 2.5rem; } aside.theme-doc-sidebar-container > div > div {
h2 { font-size: 2rem; } padding-top: 0;
h3 { font-size: 1.5rem; } }
p { /* Sidebar brand logo space */
font-family: var(--ifm-font-family-base); .sidebar-brand-logo {
font-size: var(--ifm-font-size-base); content: "";
line-height: 1.6; display: flex;
color: var(--ifm-font-color-base); width: 300px;
margin: 0 0 1rem; height: 36px;
} margin-top: 10px;
margin-left: 10px;
/* Links */ background-size: contain;
a { background-repeat: no-repeat;
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;
} }
/* Mobile responsiveness */ /* Mobile responsiveness */
@media (max-width: 996px) { @media (max-width: 996px) {
.docSidebarContainer_YfHR,
aside[class*="docSidebarContainer"] { aside[class*="docSidebarContainer"] {
display: none; display: none;
} }
.docMainContainer_TBSr, main {
main[class*="docMainContainer"] {
width: 100%; width: 100%;
padding: 0 0.5rem; padding: 0 0.5rem;
} }

View File

@ -88,11 +88,16 @@ export default function OptimizedStyles() {
const allStylesheets = document.querySelectorAll('link[rel="stylesheet"]'); const allStylesheets = document.querySelectorAll('link[rel="stylesheet"]');
allStylesheets.forEach((stylesheet) => { allStylesheets.forEach((stylesheet) => {
const link = stylesheet as HTMLLinkElement; const link = stylesheet as HTMLLinkElement;
// Skip critical styles // Skip critical styles and any styles that are already optimized
if (link.href.includes('critical') || link.getAttribute('data-critical') === 'true') { if (link.href.includes('critical') ||
link.getAttribute('data-critical') === 'true' ||
link.getAttribute('data-optimized') === 'true') {
return; return;
} }
// Mark as optimized to avoid re-processing
link.setAttribute('data-optimized', 'true');
// Convert blocking stylesheets to non-blocking // Convert blocking stylesheets to non-blocking
if (!link.media || link.media === 'all') { if (!link.media || link.media === 'all') {
// Temporarily set to print to make non-blocking // Temporarily set to print to make non-blocking
@ -115,16 +120,17 @@ export default function OptimizedStyles() {
mutation.addedNodes.forEach((node) => { mutation.addedNodes.forEach((node) => {
if (node.nodeName === 'LINK') { if (node.nodeName === 'LINK') {
const link = node as HTMLLinkElement; 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'); link.setAttribute('data-optimized', 'true');
// Make it non-blocking if it's not critical // Make it non-blocking
if (!link.href.includes('critical')) { const originalMedia = link.media || 'all';
const originalMedia = link.media || 'all'; link.media = 'print';
link.media = 'print'; link.onload = function() {
link.onload = function() { (this as HTMLLinkElement).media = originalMedia;
(this as HTMLLinkElement).media = originalMedia; };
};
}
} }
} }
}); });
@ -144,17 +150,7 @@ export default function OptimizedStyles() {
}; };
}, []); }, []);
// Inline critical CSS for immediate rendering // This component handles non-critical CSS optimization only
return ( // Critical CSS is handled in Root.tsx
<style return null;
dangerouslySetInnerHTML={{
__html: `
/* Inline critical styles for immediate paint */
/* This prevents render-blocking */
@import url('/src/css/critical.css');
`
}}
data-critical="true"
/>
);
} }

View File

@ -1,8 +1,8 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
import OptimizedStyles from './OptimizedStyles'; // import OptimizedStyles from './OptimizedStyles';
import FontLoader from './FontLoader'; // import FontLoader from './FontLoader';
import LayoutStabilizer from './LayoutStabilizer'; // import LayoutStabilizer from './LayoutStabilizer';
// Import critical CSS directly for immediate availability // Import critical CSS directly for immediate availability
import criticalCSS from '!raw-loader!../css/critical.css'; import criticalCSS from '!raw-loader!../css/critical.css';
@ -97,10 +97,10 @@ export default function Root({ children }: { children: React.ReactNode }) {
data-critical='true' data-critical='true'
/> />
{/* Performance optimization components */} {/* Performance optimization components disabled to prevent style conflicts */}
<OptimizedStyles /> {/* <OptimizedStyles /> */}
<FontLoader /> {/* <FontLoader /> */}
<LayoutStabilizer /> {/* <LayoutStabilizer /> */}
{/* Main app content */} {/* Main app content */}
{children} {children}