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 */
/* 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;
}
/* Content wrapper */
.container {
max-width: 1140px;
margin: 0 auto;
padding: 0 1rem;
.navbar .navbar__brand {
display: none;
}
}
/* 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;
/* Minimal layout structure to prevent major shifts */
main {
min-height: calc(100vh - 3.75rem);
display: flex;
justify-content: center;
}
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.5rem; }
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;
/* 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;
}
/* Links */
a {
color: var(--unleash-color-purple);
text-decoration: none;
aside.theme-doc-sidebar-container > div > div {
padding-top: 0;
}
/* 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 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;
}
/* 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 */
@media (max-width: 996px) {
.docSidebarContainer_YfHR,
aside[class*="docSidebarContainer"] {
display: none;
}
.docMainContainer_TBSr,
main[class*="docMainContainer"] {
main {
width: 100%;
padding: 0 0.5rem;
}

View File

@ -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,10 +120,12 @@ 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')) {
// Make it non-blocking
const originalMedia = link.media || 'all';
link.media = 'print';
link.onload = function() {
@ -126,7 +133,6 @@ export default function OptimizedStyles() {
};
}
}
}
});
}
});
@ -144,17 +150,7 @@ export default function OptimizedStyles() {
};
}, []);
// Inline critical CSS for immediate rendering
return (
<style
dangerouslySetInnerHTML={{
__html: `
/* Inline critical styles for immediate paint */
/* This prevents render-blocking */
@import url('/src/css/critical.css');
`
}}
data-critical="true"
/>
);
// This component handles non-critical CSS optimization only
// Critical CSS is handled in Root.tsx
return null;
}

View File

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