fix(performance): eliminar sistema legacy Critical CSS duplicado
- Eliminado Inc/critical-css.php (381 lineas de codigo legacy) - Eliminado require en functions.php linea 45 - Sistema unificado: CriticalCSSService.php genera CSS dinamico desde BD
This commit is contained in:
@@ -1,426 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Critical CSS Generator and Inline Loader
|
||||
*
|
||||
* This file provides functionality to inline critical CSS for above-the-fold content,
|
||||
* improving First Contentful Paint (FCP) and Largest Contentful Paint (LCP).
|
||||
*
|
||||
* IMPORTANT: This feature is DISABLED by default. Enable it via Customizer.
|
||||
*
|
||||
* How it works:
|
||||
* 1. When enabled, critical CSS is inlined in the <head>
|
||||
* 2. Main stylesheet is loaded asynchronously after page load
|
||||
* 3. Improves Core Web Vitals by reducing render-blocking CSS
|
||||
*
|
||||
* @package ROI_Theme
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Critical CSS is enabled
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return bool
|
||||
*/
|
||||
function roi_is_critical_css_enabled() {
|
||||
return get_theme_mod( 'roi_enable_critical_css', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Critical CSS Content
|
||||
*
|
||||
* Returns the critical CSS for the current page type.
|
||||
* You can customize this based on page types (home, single, archive, etc.)
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return string Critical CSS content
|
||||
*/
|
||||
function roi_get_critical_css() {
|
||||
// Define critical CSS based on page type
|
||||
$critical_css = '';
|
||||
|
||||
// Get transient to cache critical CSS
|
||||
$transient_key = 'roi_critical_css_' . roi_get_page_type();
|
||||
$cached_css = get_transient( $transient_key );
|
||||
|
||||
if ( false !== $cached_css ) {
|
||||
return $cached_css;
|
||||
}
|
||||
|
||||
// Generate critical CSS based on page type
|
||||
if ( is_front_page() || is_home() ) {
|
||||
$critical_css = roi_get_home_critical_css();
|
||||
} elseif ( is_single() ) {
|
||||
$critical_css = roi_get_single_critical_css();
|
||||
} elseif ( is_archive() || is_category() || is_tag() ) {
|
||||
$critical_css = roi_get_archive_critical_css();
|
||||
} else {
|
||||
$critical_css = roi_get_default_critical_css();
|
||||
}
|
||||
|
||||
// Cache for 24 hours
|
||||
set_transient( $transient_key, $critical_css, DAY_IN_SECONDS );
|
||||
|
||||
return $critical_css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current page type for caching
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return string Page type identifier
|
||||
*/
|
||||
function roi_get_page_type() {
|
||||
if ( is_front_page() ) {
|
||||
return 'home';
|
||||
} elseif ( is_single() ) {
|
||||
return 'single';
|
||||
} elseif ( is_archive() ) {
|
||||
return 'archive';
|
||||
} elseif ( is_search() ) {
|
||||
return 'search';
|
||||
} elseif ( is_404() ) {
|
||||
return '404';
|
||||
} else {
|
||||
return 'page';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Critical CSS for Homepage
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return string
|
||||
*/
|
||||
function roi_get_home_critical_css() {
|
||||
return '
|
||||
/* Reset and Base */
|
||||
*,*::before,*::after{box-sizing:border-box}
|
||||
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;line-height:1.6;color:#333;background:#fff}
|
||||
img{max-width:100%;height:auto;display:block}
|
||||
a{color:#0066cc;text-decoration:none}
|
||||
|
||||
/* Header */
|
||||
.site-header{background:#fff;border-bottom:1px solid #e5e5e5;position:sticky;top:0;z-index:1000}
|
||||
.site-header .container{max-width:1200px;margin:0 auto;padding:1rem}
|
||||
.site-branding{display:flex;align-items:center}
|
||||
.site-title{margin:0;font-size:1.5rem;font-weight:700}
|
||||
|
||||
/* Hero Section */
|
||||
.hero-section{padding:3rem 1rem;text-align:center;background:#f8f9fa}
|
||||
.hero-title{font-size:2.5rem;margin:0 0 1rem;font-weight:700;line-height:1.2}
|
||||
.hero-description{font-size:1.125rem;color:#666;max-width:600px;margin:0 auto}
|
||||
|
||||
/* Container */
|
||||
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
|
||||
|
||||
/* Featured Posts Grid */
|
||||
.featured-posts{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:2rem;margin:2rem 0}
|
||||
.post-card{background:#fff;border:1px solid #e5e5e5;border-radius:8px;overflow:hidden;transition:transform .2s}
|
||||
.post-card:hover{transform:translateY(-4px)}
|
||||
|
||||
/* Skip to content */
|
||||
.skip-link{position:absolute;left:-999px;top:0;background:#0066cc;color:#fff;padding:.5rem 1rem;text-decoration:none}
|
||||
.skip-link:focus{left:0}
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Critical CSS for Single Post/Page
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return string
|
||||
*/
|
||||
function roi_get_single_critical_css() {
|
||||
return '
|
||||
/* Reset and Base */
|
||||
*,*::before,*::after{box-sizing:border-box}
|
||||
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;line-height:1.6;color:#333;background:#fff}
|
||||
img{max-width:100%;height:auto;display:block}
|
||||
a{color:#0066cc;text-decoration:none}
|
||||
h1,h2,h3,h4,h5,h6{margin:1.5rem 0 1rem;font-weight:700;line-height:1.3}
|
||||
h1{font-size:2.5rem}
|
||||
h2{font-size:2rem}
|
||||
h3{font-size:1.5rem}
|
||||
p{margin:0 0 1.5rem}
|
||||
|
||||
/* Header */
|
||||
.site-header{background:#fff;border-bottom:1px solid #e5e5e5;position:sticky;top:0;z-index:1000}
|
||||
.site-header .container{max-width:1200px;margin:0 auto;padding:1rem}
|
||||
|
||||
/* Article */
|
||||
.entry-header{margin:2rem 0}
|
||||
.entry-title{font-size:2.5rem;margin:0 0 1rem;line-height:1.2}
|
||||
.entry-meta{color:#666;font-size:.875rem}
|
||||
.entry-content{max-width:800px;margin:0 auto;font-size:1.125rem;line-height:1.8}
|
||||
.featured-image{margin:2rem 0}
|
||||
|
||||
/* Container */
|
||||
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
|
||||
|
||||
/* Skip to content */
|
||||
.skip-link{position:absolute;left:-999px;top:0;background:#0066cc;color:#fff;padding:.5rem 1rem;text-decoration:none}
|
||||
.skip-link:focus{left:0}
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Critical CSS for Archive Pages
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return string
|
||||
*/
|
||||
function roi_get_archive_critical_css() {
|
||||
return '
|
||||
/* Reset and Base */
|
||||
*,*::before,*::after{box-sizing:border-box}
|
||||
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;line-height:1.6;color:#333;background:#fff}
|
||||
img{max-width:100%;height:auto;display:block}
|
||||
a{color:#0066cc;text-decoration:none}
|
||||
|
||||
/* Header */
|
||||
.site-header{background:#fff;border-bottom:1px solid #e5e5e5;position:sticky;top:0;z-index:1000}
|
||||
.site-header .container{max-width:1200px;margin:0 auto;padding:1rem}
|
||||
|
||||
/* Archive Header */
|
||||
.archive-header{padding:2rem 1rem;background:#f8f9fa;border-bottom:1px solid #e5e5e5}
|
||||
.archive-title{margin:0;font-size:2rem;font-weight:700}
|
||||
.archive-description{margin:1rem 0 0;color:#666;font-size:1.125rem}
|
||||
|
||||
/* Posts Grid */
|
||||
.posts-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:2rem;margin:2rem 0}
|
||||
.post-card{background:#fff;border:1px solid #e5e5e5;border-radius:8px;overflow:hidden}
|
||||
|
||||
/* Container */
|
||||
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
|
||||
|
||||
/* Skip to content */
|
||||
.skip-link{position:absolute;left:-999px;top:0;background:#0066cc;color:#fff;padding:.5rem 1rem;text-decoration:none}
|
||||
.skip-link:focus{left:0}
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Critical CSS for Default Pages
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return string
|
||||
*/
|
||||
function roi_get_default_critical_css() {
|
||||
return '
|
||||
/* Reset and Base */
|
||||
*,*::before,*::after{box-sizing:border-box}
|
||||
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;line-height:1.6;color:#333;background:#fff}
|
||||
img{max-width:100%;height:auto;display:block}
|
||||
a{color:#0066cc;text-decoration:none}
|
||||
|
||||
/* Header */
|
||||
.site-header{background:#fff;border-bottom:1px solid #e5e5e5;position:sticky;top:0;z-index:1000}
|
||||
.site-header .container{max-width:1200px;margin:0 auto;padding:1rem}
|
||||
|
||||
/* Container */
|
||||
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
|
||||
|
||||
/* Content */
|
||||
.site-content{min-height:50vh;padding:2rem 0}
|
||||
|
||||
/* Skip to content */
|
||||
.skip-link{position:absolute;left:-999px;top:0;background:#0066cc;color:#fff;padding:.5rem 1rem;text-decoration:none}
|
||||
.skip-link:focus{left:0}
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Critical CSS inline in head
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function roi_output_critical_css() {
|
||||
if ( ! roi_is_critical_css_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$critical_css = roi_get_critical_css();
|
||||
|
||||
if ( empty( $critical_css ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Minify CSS (remove extra whitespace and newlines)
|
||||
$critical_css = preg_replace( '/\s+/', ' ', $critical_css );
|
||||
$critical_css = trim( $critical_css );
|
||||
|
||||
// Output inline critical CSS
|
||||
echo '<style id="roi-critical-css">' . $critical_css . '</style>' . "\n";
|
||||
}
|
||||
add_action( 'wp_head', 'roi_output_critical_css', 1 );
|
||||
|
||||
/**
|
||||
* Load main stylesheet asynchronously when critical CSS is enabled
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function roi_async_main_stylesheet() {
|
||||
if ( ! roi_is_critical_css_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dequeue main stylesheet to prevent render-blocking
|
||||
wp_dequeue_style( 'roi-theme-style' );
|
||||
|
||||
// Enqueue with media="print" and onload to load asynchronously
|
||||
wp_enqueue_style(
|
||||
'roi-theme-style-async',
|
||||
get_stylesheet_uri(),
|
||||
array(),
|
||||
ROI_VERSION,
|
||||
'print'
|
||||
);
|
||||
|
||||
// Add onload attribute to switch media to "all"
|
||||
add_filter( 'style_loader_tag', 'roi_add_async_attribute', 10, 2 );
|
||||
}
|
||||
add_action( 'wp_enqueue_scripts', 'roi_async_main_stylesheet', 999 );
|
||||
|
||||
/**
|
||||
* Add async loading attributes to stylesheet
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param string $html The link tag for the enqueued style.
|
||||
* @param string $handle The style's registered handle.
|
||||
* @return string Modified link tag
|
||||
*/
|
||||
function roi_add_async_attribute( $html, $handle ) {
|
||||
if ( 'roi-theme-style-async' !== $handle ) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Add onload attribute to switch media to "all"
|
||||
$html = str_replace(
|
||||
"media='print'",
|
||||
"media='print' onload=\"this.media='all'\"",
|
||||
$html
|
||||
);
|
||||
|
||||
// Add noscript fallback
|
||||
$html .= '<noscript><link rel="stylesheet" href="' . get_stylesheet_uri() . '"></noscript>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Customizer setting for Critical CSS
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
|
||||
*/
|
||||
function roi_critical_css_customizer( $wp_customize ) {
|
||||
// Add Performance section
|
||||
$wp_customize->add_section(
|
||||
'roi_performance',
|
||||
array(
|
||||
'title' => __( 'Performance Optimization', 'roi-theme' ),
|
||||
'priority' => 130,
|
||||
)
|
||||
);
|
||||
|
||||
// Critical CSS Enable/Disable
|
||||
$wp_customize->add_setting(
|
||||
'roi_enable_critical_css',
|
||||
array(
|
||||
'default' => false,
|
||||
'sanitize_callback' => 'roi_sanitize_checkbox',
|
||||
'transport' => 'refresh',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'roi_enable_critical_css',
|
||||
array(
|
||||
'label' => __( 'Enable Critical CSS', 'roi-theme' ),
|
||||
'description' => __( 'Inline critical CSS and load main stylesheet asynchronously. This can improve Core Web Vitals but may cause a flash of unstyled content (FOUC). Test thoroughly before enabling in production.', 'roi-theme' ),
|
||||
'section' => 'roi_performance',
|
||||
'type' => 'checkbox',
|
||||
)
|
||||
);
|
||||
}
|
||||
add_action( 'customize_register', 'roi_critical_css_customizer' );
|
||||
|
||||
/**
|
||||
* Clear critical CSS cache when theme is updated
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function roi_clear_critical_css_cache() {
|
||||
$page_types = array( 'home', 'single', 'archive', 'search', '404', 'page' );
|
||||
|
||||
foreach ( $page_types as $type ) {
|
||||
delete_transient( 'roi_critical_css_' . $type );
|
||||
}
|
||||
}
|
||||
add_action( 'after_switch_theme', 'roi_clear_critical_css_cache' );
|
||||
add_action( 'customize_save_after', 'roi_clear_critical_css_cache' );
|
||||
|
||||
/**
|
||||
* Output Hero Section Critical CSS
|
||||
*
|
||||
* This CSS is ALWAYS injected in the <head> to prevent CLS (Cumulative Layout Shift)
|
||||
* by reserving space for the hero section BEFORE it renders.
|
||||
*
|
||||
* The min-height values match the actual rendered height (~260px on desktop)
|
||||
* to prevent any layout shift when the dynamic CSS loads.
|
||||
*
|
||||
* @since 1.0.21
|
||||
* @see Public/Hero/Infrastructure/Ui/HeroRenderer.php
|
||||
*/
|
||||
function roi_output_hero_critical_css() {
|
||||
// Only output on single posts where hero is displayed
|
||||
if ( ! is_single() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if hero is enabled (read from database)
|
||||
$is_enabled = roi_get_component_setting( 'hero', 'visibility', 'is_enabled', true );
|
||||
if ( ! $is_enabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$critical_css = '
|
||||
/* Hero Critical CSS - Prevent CLS */
|
||||
.hero-section {
|
||||
min-height: 260px;
|
||||
background: linear-gradient(135deg, #1e3a5f 0%, #2c5282 100%);
|
||||
padding: 3rem 0;
|
||||
margin-bottom: 1.5rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.hero-section__title {
|
||||
min-height: 3.5rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.hero-section__badge {
|
||||
min-height: 32px;
|
||||
display: inline-block;
|
||||
}
|
||||
@media (max-width: 767.98px) {
|
||||
.hero-section {
|
||||
min-height: 200px;
|
||||
}
|
||||
.hero-section__title {
|
||||
min-height: 2.5rem;
|
||||
}
|
||||
}
|
||||
';
|
||||
|
||||
// Minify CSS
|
||||
$critical_css = preg_replace( '/\s+/', ' ', $critical_css );
|
||||
$critical_css = trim( $critical_css );
|
||||
|
||||
echo '<style id="roi-hero-critical-css">' . $critical_css . '</style>' . "\n";
|
||||
}
|
||||
add_action( 'wp_head', 'roi_output_hero_critical_css', 2 );
|
||||
Reference in New Issue
Block a user