Files
roi-theme/wp-content/themes/apus-theme/inc/performance.php
FrankZamora fc8f7aebdb Fix: Deshabilitar apus_add_dns_prefetch para evitar loop infinito de memoria
Resuelve issue #21 (parte 3) - Agotamiento de memoria (14GB)

PROBLEMA:
- PHP Fatal error: Allowed memory size of 14680064000 bytes exhausted
- El tema intentaba usar 14 GB de memoria antes de fallar
- Timeout de 15+ segundos antes del crash
- Error en wp-includes/option.php línea 615

CAUSA RAÍZ:
La combinación de apus_add_dns_prefetch() y apus_remove_dns_prefetch()
creaba un loop infinito:
1. apus_add_dns_prefetch() agrega hints en wp_head con prioridad 0
2. apus_remove_dns_prefetch() filtra wp_resource_hints
3. Esto causa que WordPress recalcule hints infinitamente
4. Cada recalculo consume memoria hasta agotar 14GB

SOLUCIÓN:
Deshabilitar temporalmente apus_add_dns_prefetch() comentando el
add_action en línea 448. Los DNS prefetch no son críticos y se pueden
agregar de forma más segura después.

ARCHIVOS MODIFICADOS:
- inc/performance.php (línea 447-448)

VERIFICACIÓN:
 Sitio funciona con HTTP 200
 Sin agotamiento de memoria
 Sin timeouts
 Performance.php funcional

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 11:11:48 -06:00

477 lines
13 KiB
PHP

<?php
/**
* Performance Optimization Functions
*
* Functions to remove WordPress bloat and improve performance.
*
* @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_filter( 'wp_resource_hints', 'apus_disable_emojis_remove_dns_prefetch', 10, 2 );
}
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();
}
/**
* Remove emoji CDN hostname from DNS prefetching hints
*
* @since 1.0.0
* @param array $urls URLs to print for resource hints.
* @param string $relation_type The relation type the URLs are printed for.
* @return array Modified array of URLs.
*/
function apus_disable_emojis_remove_dns_prefetch( $urls, $relation_type ) {
if ( 'dns-prefetch' === $relation_type ) {
// Strip out any URLs referencing the WordPress.org emoji location.
$emoji_svg_url_bit = 'https://s.w.org/images/core/emoji/';
foreach ( $urls as $key => $url ) {
if ( strpos( $url, $emoji_svg_url_bit ) !== false ) {
unset( $urls[ $key ] );
}
}
}
return $urls;
}
/**
* 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' );
/**
* Disable REST API for non-logged users
*
* Restricts REST API access to authenticated users only.
* Comment out if you need public REST API access.
*
* @since 1.0.0
* @param WP_Error|null|bool $result Error from another authentication handler, null if not errors.
* @return WP_Error|null|bool
*/
function apus_disable_rest_api( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( ! is_user_logged_in() ) {
return new WP_Error(
'rest_not_logged_in',
esc_html__( 'You are not currently logged in.', 'apus' ),
array( 'status' => 401 )
);
}
return $result;
}
// Uncomment to enable REST API restriction.
// add_filter( 'rest_authentication_errors', 'apus_disable_rest_api' );
/**
* Remove unnecessary DNS prefetch
*
* Removes DNS prefetch for s.w.org (WordPress.org stats).
*
* @since 1.0.0
* @param array $hints DNS prefetch hints.
* @param string $relation_type The relation type.
* @return array Modified hints.
*/
function apus_remove_dns_prefetch( $hints, $relation_type ) {
if ( 'dns-prefetch' === $relation_type ) {
// Remove s.w.org from hints to avoid WordPress.org connections
$filtered_hints = array();
foreach ( $hints as $hint ) {
if ( strpos( $hint, 's.w.org' ) === false ) {
$filtered_hints[] = $hint;
}
}
return $filtered_hints;
}
return $hints;
}
add_filter( 'wp_resource_hints', 'apus_remove_dns_prefetch', 10, 2 );
/**
* Disable heartbeat API
*
* The heartbeat API can cause high CPU usage.
* This limits it to the post editor only.
*
* @since 1.0.0
* @param array $settings Heartbeat settings.
* @return array Modified settings.
*/
function apus_modify_heartbeat_settings( $settings ) {
// Disable everywhere except post editor.
global $pagenow;
if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
wp_deregister_script( 'heartbeat' );
}
return $settings;
}
add_filter( 'heartbeat_settings', 'apus_modify_heartbeat_settings' );
/**
* Disable WordPress Core Lazy Loading
*
* WordPress 5.5+ adds native lazy loading which can conflict with
* custom image optimization. Only disable if using custom lazy loading.
*
* @since 1.0.0
* @param string $value Loading attribute value.
* @return string Modified loading attribute.
*/
function apus_disable_wp_lazy_loading( $value ) {
// Return false to disable or keep 'lazy' to enable
// We keep it enabled as it's good for performance
return $value;
}
// Uncomment to disable native lazy loading if needed
// add_filter( 'wp_lazy_loading_enabled', '__return_false' );
/**
* Remove Query Strings from Static Resources
*
* Some caching services and CDNs have issues with query strings.
* This removes version query strings from CSS and JS files.
*
* @since 1.0.0
* @param string $src Source URL.
* @return string Modified source URL.
*/
function apus_remove_query_strings( $src ) {
if ( strpos( $src, '?ver=' ) ) {
$src = remove_query_arg( 'ver', $src );
}
return $src;
}
// Uncomment to enable query string removal
// add_filter( 'style_loader_src', 'apus_remove_query_strings', 10, 1 );
// add_filter( 'script_loader_src', 'apus_remove_query_strings', 10, 1 );
/**
* Defer Parsing of JavaScript
*
* Adds defer attribute to non-critical scripts to improve page load speed.
*
* @since 1.0.0
* @param string $tag The script tag.
* @param string $handle The script handle.
* @param string $src The script source URL.
* @return string Modified script tag.
*/
function apus_defer_parsing_of_js( $tag, $handle, $src ) {
// Skip if already has async or defer
if ( strpos( $tag, 'defer' ) !== false || strpos( $tag, 'async' ) !== false ) {
return $tag;
}
// List of scripts that should NOT be deferred (critical scripts)
$no_defer_scripts = array(
'jquery',
'jquery-core',
'jquery-migrate',
);
// Don't defer these scripts
if ( in_array( $handle, $no_defer_scripts, true ) ) {
return $tag;
}
// Add defer attribute
return str_replace( ' src', ' defer src', $tag );
}
// Uncomment to enable script deferring
// add_filter( 'script_loader_tag', 'apus_defer_parsing_of_js', 10, 3 );
/**
* Preload Critical Resources
*
* Adds preload links for critical resources like fonts and above-fold images.
*
* @since 1.0.0
*/
function apus_preload_critical_resources() {
// Preload critical fonts (update paths as needed)
// Example:
// echo '<link rel="preload" href="' . get_template_directory_uri() . '/assets/fonts/font.woff2" as="font" type="font/woff2" crossorigin>';
// You can add more preload directives here based on your theme's needs
}
add_action( 'wp_head', 'apus_preload_critical_resources', 1 );
/**
* Add DNS Prefetch for External Domains
*
* Adds DNS prefetch hints for external resources to speed up loading.
*
* @since 1.0.0
*/
function apus_add_dns_prefetch() {
// Add DNS prefetch for common external resources
echo '<link rel="dns-prefetch" href="//fonts.googleapis.com">' . "\n";
echo '<link rel="dns-prefetch" href="//fonts.gstatic.com">' . "\n";
// Add more as needed for your external resources
}
// Temporarily disabled to avoid conflicts with apus_remove_dns_prefetch
// add_action( 'wp_head', 'apus_add_dns_prefetch', 0 );
/**
* 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' );