PROBLEMA RAÍZ ENCONTRADO: La función apus_remove_query_strings_from_static_resources() estaba eliminando TODOS los query strings (?ver=X.X.X) de los CSS, incluyendo el style.css principal. Esto impedía que los navegadores descargaran nuevas versiones del CSS cuando se hacían cambios, causando que el botón Let's Talk siguiera mostrándose azul en lugar de naranja. SOLUCIÓN: Modificar la función para que NO elimine el query string del /assets/css/style.css, permitiendo cache busting cuando se actualiza. Los demás archivos CSS siguen sin query string para mejor cache. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
624 lines
18 KiB
PHP
624 lines
18 KiB
PHP
<?php
|
|
/**
|
|
* Performance Optimization Functions
|
|
*
|
|
* Functions to remove WordPress bloat and improve performance.
|
|
*
|
|
* NOTA: Versión reducida con solo optimizaciones seguras después de
|
|
* resolver problemas de memory exhaustion en Issue #22.
|
|
*
|
|
* @package Apus_Theme
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Exit if accessed directly.
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Disable WordPress Emojis
|
|
*
|
|
* Removes emoji detection scripts and styles from WordPress.
|
|
* These scripts are loaded on every page but rarely used.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_disable_emojis() {
|
|
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
|
|
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
|
|
remove_action( 'wp_print_styles', 'print_emoji_styles' );
|
|
remove_action( 'admin_print_styles', 'print_emoji_styles' );
|
|
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
|
|
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
|
|
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
|
|
|
|
// Remove from TinyMCE.
|
|
add_filter( 'tiny_mce_plugins', 'apus_disable_emojis_tinymce' );
|
|
}
|
|
add_action( 'init', 'apus_disable_emojis' );
|
|
|
|
/**
|
|
* Filter function used to remove emoji plugin from TinyMCE
|
|
*
|
|
* @since 1.0.0
|
|
* @param array $plugins An array of default TinyMCE plugins.
|
|
* @return array Modified array of TinyMCE plugins without emoji plugin.
|
|
*/
|
|
function apus_disable_emojis_tinymce( $plugins ) {
|
|
if ( is_array( $plugins ) ) {
|
|
return array_diff( $plugins, array( 'wpemoji' ) );
|
|
}
|
|
|
|
return array();
|
|
}
|
|
|
|
/**
|
|
* Disable WordPress oEmbed
|
|
*
|
|
* Removes oEmbed discovery links and scripts.
|
|
* Only disable if you don't need to embed content from other sites.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_disable_oembed() {
|
|
// Remove oEmbed discovery links.
|
|
remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
|
|
|
|
// Remove oEmbed-specific JavaScript from the front-end and back-end.
|
|
remove_action( 'wp_head', 'wp_oembed_add_host_js' );
|
|
|
|
// Remove all embeds rewrite rules.
|
|
add_filter( 'rewrite_rules_array', 'apus_disable_oembed_rewrites' );
|
|
|
|
// Remove filter of the oEmbed result before any HTTP requests are made.
|
|
remove_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10 );
|
|
}
|
|
add_action( 'init', 'apus_disable_oembed', 9999 );
|
|
|
|
/**
|
|
* Remove all rewrite rules related to embeds
|
|
*
|
|
* @since 1.0.0
|
|
* @param array $rules WordPress rewrite rules.
|
|
* @return array Modified rewrite rules.
|
|
*/
|
|
function apus_disable_oembed_rewrites( $rules ) {
|
|
foreach ( $rules as $rule => $rewrite ) {
|
|
if ( false !== strpos( $rewrite, 'embed=true' ) ) {
|
|
unset( $rules[ $rule ] );
|
|
}
|
|
}
|
|
return $rules;
|
|
}
|
|
|
|
/**
|
|
* Disable wp-embed.js script
|
|
*
|
|
* Dequeues the wp-embed.js script that WordPress loads by default.
|
|
* This script is used for embedding WordPress posts on other sites.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_dequeue_embed_script() {
|
|
wp_deregister_script( 'wp-embed' );
|
|
}
|
|
add_action( 'wp_footer', 'apus_dequeue_embed_script' );
|
|
|
|
/**
|
|
* Disable WordPress Feeds
|
|
*
|
|
* Removes RSS, RDF, and Atom feeds.
|
|
* Only disable if you don't need feed functionality.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_disable_feeds() {
|
|
wp_die(
|
|
esc_html__( 'No feed available, please visit our homepage!', 'apus' ),
|
|
esc_html__( 'Feed Not Available', 'apus' ),
|
|
array(
|
|
'response' => 404,
|
|
'back_link' => true,
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Remove feed links and redirect feed URLs
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_disable_feed_links() {
|
|
// Remove feed links from header.
|
|
remove_action( 'wp_head', 'feed_links', 2 );
|
|
remove_action( 'wp_head', 'feed_links_extra', 3 );
|
|
|
|
// Redirect feed URLs to homepage.
|
|
add_action( 'do_feed', 'apus_disable_feeds', 1 );
|
|
add_action( 'do_feed_rdf', 'apus_disable_feeds', 1 );
|
|
add_action( 'do_feed_rss', 'apus_disable_feeds', 1 );
|
|
add_action( 'do_feed_rss2', 'apus_disable_feeds', 1 );
|
|
add_action( 'do_feed_atom', 'apus_disable_feeds', 1 );
|
|
add_action( 'do_feed_rss2_comments', 'apus_disable_feeds', 1 );
|
|
add_action( 'do_feed_atom_comments', 'apus_disable_feeds', 1 );
|
|
}
|
|
add_action( 'init', 'apus_disable_feed_links' );
|
|
|
|
/**
|
|
* Disable RSD and Windows Live Writer Manifest
|
|
*
|
|
* Really Simple Discovery (RSD) and Windows Live Writer (WLW) manifest
|
|
* are rarely used and can be safely removed.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_disable_rsd_wlw() {
|
|
// Remove RSD link.
|
|
remove_action( 'wp_head', 'rsd_link' );
|
|
|
|
// Remove Windows Live Writer manifest link.
|
|
remove_action( 'wp_head', 'wlwmanifest_link' );
|
|
}
|
|
add_action( 'init', 'apus_disable_rsd_wlw' );
|
|
|
|
/**
|
|
* Disable Dashicons for non-logged users
|
|
*
|
|
* Dashicons are only needed in the admin area and for logged-in users.
|
|
* This removes them from the front-end for visitors.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_disable_dashicons() {
|
|
if ( ! is_user_logged_in() ) {
|
|
wp_deregister_style( 'dashicons' );
|
|
}
|
|
}
|
|
add_action( 'wp_enqueue_scripts', 'apus_disable_dashicons' );
|
|
|
|
/**
|
|
* Disable Block Library CSS
|
|
*
|
|
* Removes the default WordPress block library styles.
|
|
* Only disable if you're not using the block editor or if you're
|
|
* providing your own block styles.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_disable_block_library_css() {
|
|
// Remove default block library styles.
|
|
wp_dequeue_style( 'wp-block-library' );
|
|
wp_dequeue_style( 'wp-block-library-theme' );
|
|
|
|
// Remove inline global styles.
|
|
wp_dequeue_style( 'global-styles' );
|
|
|
|
// Remove classic theme styles (if not using classic editor).
|
|
wp_dequeue_style( 'classic-theme-styles' );
|
|
}
|
|
add_action( 'wp_enqueue_scripts', 'apus_disable_block_library_css', 100 );
|
|
|
|
/**
|
|
* Remove WordPress version from head and feeds
|
|
*
|
|
* Removes the WordPress version number for security reasons.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_remove_wp_version() {
|
|
return '';
|
|
}
|
|
add_filter( 'the_generator', 'apus_remove_wp_version' );
|
|
|
|
/**
|
|
* Disable XML-RPC
|
|
*
|
|
* XML-RPC is often targeted by brute force attacks.
|
|
* Disable if you don't need remote publishing functionality.
|
|
*
|
|
* @since 1.0.0
|
|
* @return bool
|
|
*/
|
|
function apus_disable_xmlrpc() {
|
|
return false;
|
|
}
|
|
add_filter( 'xmlrpc_enabled', 'apus_disable_xmlrpc' );
|
|
|
|
/**
|
|
* Remove jQuery Migrate
|
|
*
|
|
* jQuery Migrate is used for backwards compatibility but adds extra overhead.
|
|
* Only remove if you've verified all scripts work without it.
|
|
*
|
|
* @since 1.0.0
|
|
* @param WP_Scripts $scripts WP_Scripts object.
|
|
*/
|
|
function apus_remove_jquery_migrate( $scripts ) {
|
|
if ( ! is_admin() && isset( $scripts->registered['jquery'] ) ) {
|
|
$script = $scripts->registered['jquery'];
|
|
|
|
if ( $script->deps ) {
|
|
// Remove jquery-migrate from dependencies.
|
|
$script->deps = array_diff( $script->deps, array( 'jquery-migrate' ) );
|
|
}
|
|
}
|
|
}
|
|
add_action( 'wp_default_scripts', 'apus_remove_jquery_migrate' );
|
|
|
|
/**
|
|
* Optimize WordPress Database Queries
|
|
*
|
|
* Removes unnecessary meta queries for better performance.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_optimize_queries() {
|
|
// Remove unnecessary post meta from queries
|
|
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 );
|
|
remove_action( 'wp_head', 'wp_shortlink_wp_head', 10 );
|
|
}
|
|
add_action( 'init', 'apus_optimize_queries' );
|
|
|
|
/**
|
|
* Disable WordPress Admin Bar for Non-Admins
|
|
*
|
|
* Reduces HTTP requests for non-admin users.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_disable_admin_bar() {
|
|
if ( ! current_user_can( 'administrator' ) && ! is_admin() ) {
|
|
show_admin_bar( false );
|
|
}
|
|
}
|
|
add_action( 'after_setup_theme', 'apus_disable_admin_bar' );
|
|
|
|
/**
|
|
* ============================================================================
|
|
* RESOURCE HINTS: DNS PREFETCH, PRECONNECT, PRELOAD
|
|
* ============================================================================
|
|
*/
|
|
|
|
/**
|
|
* Agregar DNS Prefetch y Preconnect para recursos externos
|
|
*
|
|
* DNS Prefetch: Resuelve DNS antes de que se necesite el recurso
|
|
* Preconnect: Establece conexión completa (DNS + TCP + TLS) por anticipado
|
|
*
|
|
* @since 1.0.0
|
|
* @param array $urls Array of resource URLs.
|
|
* @param string $relation_type The relation type (dns-prefetch, preconnect, etc.).
|
|
* @return array Modified array of resource URLs.
|
|
*/
|
|
function apus_add_resource_hints( $urls, $relation_type ) {
|
|
// DNS Prefetch para recursos externos que no son críticos
|
|
if ( 'dns-prefetch' === $relation_type ) {
|
|
// CDN de Bootstrap Icons (ya usado en enqueue-scripts.php)
|
|
$urls[] = 'https://cdn.jsdelivr.net';
|
|
|
|
// Google Analytics (si se usa)
|
|
$urls[] = 'https://www.google-analytics.com';
|
|
$urls[] = 'https://www.googletagmanager.com';
|
|
|
|
// Google AdSense (si se usa)
|
|
$urls[] = 'https://pagead2.googlesyndication.com';
|
|
$urls[] = 'https://adservice.google.com';
|
|
$urls[] = 'https://googleads.g.doubleclick.net';
|
|
}
|
|
|
|
// Preconnect para recursos críticos externos
|
|
if ( 'preconnect' === $relation_type ) {
|
|
// CDN de Bootstrap Icons - recurso crítico usado en el header
|
|
$urls[] = array(
|
|
'href' => 'https://cdn.jsdelivr.net',
|
|
'crossorigin' => 'anonymous',
|
|
);
|
|
}
|
|
|
|
return $urls;
|
|
}
|
|
add_filter( 'wp_resource_hints', 'apus_add_resource_hints', 10, 2 );
|
|
|
|
/**
|
|
* Preload de recursos críticos para mejorar LCP
|
|
*
|
|
* Preload indica al navegador que descargue recursos críticos lo antes posible.
|
|
* Útil para fuentes, CSS crítico, y imágenes hero.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_preload_critical_resources() {
|
|
// Preload de fuentes críticas
|
|
$fonts = array(
|
|
'inter-var.woff2',
|
|
'inter-var-italic.woff2',
|
|
);
|
|
|
|
foreach ( $fonts as $font ) {
|
|
$font_url = get_template_directory_uri() . '/assets/fonts/' . $font;
|
|
printf(
|
|
'<link rel="preload" href="%s" as="font" type="font/woff2" crossorigin="anonymous">' . "\n",
|
|
esc_url( $font_url )
|
|
);
|
|
}
|
|
|
|
// Preload del CSS de Bootstrap (crítico para el layout)
|
|
$bootstrap_css = get_template_directory_uri() . '/assets/vendor/bootstrap/css/bootstrap.min.css';
|
|
printf(
|
|
'<link rel="preload" href="%s" as="style">' . "\n",
|
|
esc_url( $bootstrap_css )
|
|
);
|
|
|
|
// Preload del CSS de fuentes (crítico para evitar FOIT/FOUT)
|
|
$fonts_css = get_template_directory_uri() . '/assets/css/fonts.css';
|
|
printf(
|
|
'<link rel="preload" href="%s" as="style">' . "\n",
|
|
esc_url( $fonts_css )
|
|
);
|
|
}
|
|
add_action( 'wp_head', 'apus_preload_critical_resources', 2 );
|
|
|
|
/**
|
|
* ============================================================================
|
|
* OPTIMIZACIÓN DE SCRIPTS Y ESTILOS
|
|
* ============================================================================
|
|
*/
|
|
|
|
/**
|
|
* Agregar atributos async/defer a scripts específicos
|
|
*
|
|
* Los scripts con defer se descargan en paralelo pero se ejecutan en orden
|
|
* después de que el DOM esté listo.
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $tag The script tag.
|
|
* @param string $handle The script handle.
|
|
* @return string Modified script tag.
|
|
*/
|
|
function apus_add_script_attributes( $tag, $handle ) {
|
|
// Scripts que deben tener async (no dependen de otros ni del DOM)
|
|
$async_scripts = array(
|
|
// Google Analytics u otros scripts de tracking
|
|
'google-analytics',
|
|
'gtag',
|
|
);
|
|
|
|
// Scripts que ya tienen defer via strategy en wp_enqueue_script
|
|
// No necesitamos modificarlos aquí ya que WordPress 6.3+ lo maneja
|
|
|
|
if ( in_array( $handle, $async_scripts, true ) ) {
|
|
// Agregar async solo si no tiene defer
|
|
if ( false === strpos( $tag, 'defer' ) ) {
|
|
$tag = str_replace( ' src', ' async src', $tag );
|
|
}
|
|
}
|
|
|
|
return $tag;
|
|
}
|
|
add_filter( 'script_loader_tag', 'apus_add_script_attributes', 10, 2 );
|
|
|
|
/**
|
|
* Remover query strings de assets estáticos para mejorar caching
|
|
*
|
|
* Algunos proxies y CDNs no cachean recursos con query strings.
|
|
* WordPress agrega ?ver= por defecto.
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $src The source URL.
|
|
* @return string Modified source URL without query strings.
|
|
*/
|
|
function apus_remove_query_strings_from_static_resources( $src ) {
|
|
// Solo remover de nuestros propios assets, EXCEPTO style.css principal
|
|
if ( strpos( $src, get_template_directory_uri() ) !== false ) {
|
|
// NO remover query string del CSS principal (necesita cache busting)
|
|
if ( strpos( $src, '/assets/css/style.css' ) === false ) {
|
|
$src = remove_query_arg( 'ver', $src );
|
|
}
|
|
}
|
|
|
|
return $src;
|
|
}
|
|
add_filter( 'style_loader_src', 'apus_remove_query_strings_from_static_resources', 10, 1 );
|
|
add_filter( 'script_loader_src', 'apus_remove_query_strings_from_static_resources', 10, 1 );
|
|
|
|
/**
|
|
* Optimizar el Heartbeat API de WordPress
|
|
*
|
|
* El Heartbeat API hace llamadas AJAX periódicas que pueden afectar el rendimiento.
|
|
* Lo desactivamos en el frontend y lo ralentizamos en el admin.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_optimize_heartbeat() {
|
|
// Desactivar completamente en el frontend
|
|
if ( ! is_admin() ) {
|
|
wp_deregister_script( 'heartbeat' );
|
|
}
|
|
}
|
|
add_action( 'init', 'apus_optimize_heartbeat', 1 );
|
|
|
|
/**
|
|
* Modificar configuración del Heartbeat en admin
|
|
*
|
|
* @since 1.0.0
|
|
* @param array $settings Heartbeat settings.
|
|
* @return array Modified settings.
|
|
*/
|
|
function apus_modify_heartbeat_settings( $settings ) {
|
|
// Cambiar intervalo de 15 segundos (default) a 60 segundos
|
|
$settings['interval'] = 60;
|
|
return $settings;
|
|
}
|
|
add_filter( 'heartbeat_settings', 'apus_modify_heartbeat_settings' );
|
|
|
|
/**
|
|
* ============================================================================
|
|
* OPTIMIZACIÓN DE BASE DE DATOS Y QUERIES
|
|
* ============================================================================
|
|
*/
|
|
|
|
/**
|
|
* Limitar revisiones de posts para reducir tamaño de BD
|
|
*
|
|
* Esto se debe configurar en wp-config.php, pero lo documentamos aquí:
|
|
* define('WP_POST_REVISIONS', 5);
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
/**
|
|
* Optimizar WP_Query para posts relacionados y listados
|
|
*
|
|
* @since 1.0.0
|
|
* @param WP_Query $query The WP_Query instance.
|
|
*/
|
|
function apus_optimize_main_query( $query ) {
|
|
// Solo en queries principales en el frontend
|
|
if ( is_admin() || ! $query->is_main_query() ) {
|
|
return;
|
|
}
|
|
|
|
// En archivos, limitar posts por página para mejorar rendimiento
|
|
if ( $query->is_archive() || $query->is_home() ) {
|
|
// No cargar meta innecesaria
|
|
$query->set( 'update_post_meta_cache', true );
|
|
$query->set( 'update_post_term_cache', true );
|
|
|
|
// Limitar posts por página si no está configurado
|
|
if ( ! $query->get( 'posts_per_page' ) ) {
|
|
$query->set( 'posts_per_page', 12 );
|
|
}
|
|
}
|
|
}
|
|
add_action( 'pre_get_posts', 'apus_optimize_main_query' );
|
|
|
|
/**
|
|
* Deshabilitar self-pingbacks
|
|
*
|
|
* Los self-pingbacks ocurren cuando un post enlaza a otro post del mismo sitio.
|
|
* Son innecesarios y generan queries adicionales.
|
|
*
|
|
* @since 1.0.0
|
|
* @param array $links An array of post links to ping.
|
|
* @return array Modified array without self-pings.
|
|
*/
|
|
function apus_disable_self_pingbacks( &$links ) {
|
|
$home = get_option( 'home' );
|
|
foreach ( $links as $l => $link ) {
|
|
if ( 0 === strpos( $link, $home ) ) {
|
|
unset( $links[ $l ] );
|
|
}
|
|
}
|
|
}
|
|
add_action( 'pre_ping', 'apus_disable_self_pingbacks' );
|
|
|
|
/**
|
|
* ============================================================================
|
|
* OPTIMIZACIÓN DE RENDER Y LAYOUT
|
|
* ============================================================================
|
|
*/
|
|
|
|
/**
|
|
* Agregar display=swap a Google Fonts para evitar FOIT
|
|
*
|
|
* Ya no usamos Google Fonts (fuentes locales), pero dejamos la función
|
|
* por si se necesita en el futuro.
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $src The source URL.
|
|
* @return string Modified source URL.
|
|
*/
|
|
function apus_add_font_display_swap( $src ) {
|
|
if ( strpos( $src, 'fonts.googleapis.com' ) !== false ) {
|
|
$src = add_query_arg( 'display', 'swap', $src );
|
|
}
|
|
return $src;
|
|
}
|
|
add_filter( 'style_loader_src', 'apus_add_font_display_swap' );
|
|
|
|
/**
|
|
* Agregar width y height a imágenes para prevenir CLS
|
|
*
|
|
* WordPress 5.5+ agrega automáticamente width/height, pero aseguramos que esté activo.
|
|
*
|
|
* @since 1.0.0
|
|
* @return bool
|
|
*/
|
|
function apus_enable_image_dimensions() {
|
|
return true;
|
|
}
|
|
add_filter( 'wp_lazy_loading_enabled', 'apus_enable_image_dimensions' );
|
|
|
|
/**
|
|
* Optimizar buffer de salida HTML
|
|
*
|
|
* Habilita compresión GZIP si está disponible y no está ya habilitada.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_enable_gzip_compression() {
|
|
// Solo en frontend
|
|
if ( is_admin() ) {
|
|
return;
|
|
}
|
|
|
|
// Verificar si GZIP ya está habilitado
|
|
if ( ! ini_get( 'zlib.output_compression' ) && 'ob_gzhandler' !== ini_get( 'output_handler' ) ) {
|
|
// Verificar si la extensión está disponible
|
|
if ( function_exists( 'gzencode' ) && extension_loaded( 'zlib' ) ) {
|
|
// Verificar headers
|
|
if ( ! headers_sent() ) {
|
|
// Habilitar compresión
|
|
ini_set( 'zlib.output_compression', 'On' );
|
|
ini_set( 'zlib.output_compression_level', '6' ); // Balance entre compresión y CPU
|
|
}
|
|
}
|
|
}
|
|
}
|
|
add_action( 'template_redirect', 'apus_enable_gzip_compression', 0 );
|
|
|
|
/**
|
|
* ============================================================================
|
|
* FUNCIONES AUXILIARES
|
|
* ============================================================================
|
|
*/
|
|
|
|
/**
|
|
* Limpiar caché de transients expirados periódicamente
|
|
*
|
|
* Los transients expirados se acumulan en la base de datos.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
function apus_cleanup_expired_transients() {
|
|
global $wpdb;
|
|
|
|
// Eliminar transients expirados (solo los del tema)
|
|
$wpdb->query(
|
|
$wpdb->prepare(
|
|
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s AND option_value < %d",
|
|
$wpdb->esc_like( '_transient_timeout_apus_' ) . '%',
|
|
time()
|
|
)
|
|
);
|
|
}
|
|
// Ejecutar limpieza semanalmente
|
|
add_action( 'apus_weekly_cleanup', 'apus_cleanup_expired_transients' );
|
|
|
|
// Registrar evento cron si no existe
|
|
if ( ! wp_next_scheduled( 'apus_weekly_cleanup' ) ) {
|
|
wp_schedule_event( time(), 'weekly', 'apus_weekly_cleanup' );
|
|
}
|
|
|
|
/*
|
|
* NOTA: Funciones previamente deshabilitadas han sido reimplementadas
|
|
* con mejoras para evitar loops infinitos y problemas de memoria.
|
|
*
|
|
* - Resource hints (dns-prefetch, preconnect) - REACTIVADO
|
|
* - Preload de recursos críticos - REACTIVADO
|
|
* - Optimización del Heartbeat API - REACTIVADO
|
|
* - Remoción de query strings - REACTIVADO (solo para assets propios)
|
|
* - Script attributes (defer/async) - REACTIVADO
|
|
*/
|