AeroCore Theme LCP Optimization: Images, JS, CSS, and Preconnect

My website uses the AeroCore theme, and I've noticed that many images on the post and list pages use lazy loading, including those on the homepage. However, using lazy loading on the homepage affects the LCP.

I also used a few third-party scripts and stylesheets. As a result, the above-the-fold loading was very slow, and the LCP score wasn’t very high either. So I wrote a piece of PHP code. This code consists of four parts.

Part 1: Configuring eager and lazy image loading. Part 2: Adding `defer` to scripts. Part 3: Asynchronously loading non-critical CSS. Part 4: Adding `preconnect`. I’ve placed the code in the themefunctions.php As mentioned at the beginning of the document, this method improves the first-screen load speed.

PageSpeed Insights test results:

PageSpeed Insights的测试效果-手机

PageSpeed Insights的测试效果-桌面设备

However, this solution is not yet fully developed and may cause performance issues on some servers. Please use it as a reference at your own discretion; I am still working on a more efficient solution.

Keep the original code in the functions.php file

<?php
if (!defined('ABSPATH')) exit;

$fun_file = __DIR__ . '/fun.php';
if (is_file($fun_file)) {
    require_once $fun_file;
}

1. Image Loading Optimization: Dynamically Set "Eager" and "Lazy"

This code identifies images containing text. It only processes /wp-content/uploads/ images below. It excludes avatars, logos, and ICP registration icons. It then determines the number of eager images based on the page type. The homepage, archive pages, and search pages display 5 images. Post pages display 2 images. Other pages display 3 images. The first eager image is added fetchpriority="high". Add "eager" or "lazy" to the remaining images. Add to all images decoding="async". This way, the first-screen image loads first, resulting in a faster LCP.

// 图片加载优化
add_action('template_redirect', function () {
    if (is_admin() || wp_doing_ajax() || (defined('REST_REQUEST') && REST_REQUEST)) return;
    ob_start('meow_filter_images_by_page');
}, 0);

function meow_filter_images_by_page($html) {
    if (stripos($html, '<img') === false) return $html;
    $eager_count = meow_get_eager_count();

    $is_content_img = function ($tag, &$src_out) {
        $src_out = '';
        if (!preg_match('/src=["\']([^"\']+)["\']/i', $tag, $s)) return false;
        $src = html_entity_decode($s[1], ENT_QUOTES);
        if (strpos($src, '/wp-content/uploads/') === false) return false;
        if (stripos($src, 'weavatar.com') !== false) return false;
        if (stripos($src, 'gravatar.com') !== false) return false;
        if (preg_match('/\/(icp|police)\./i', $src)) return false;
        if (preg_match('/\bclass=["\']([^"\']*)/i', $tag, $c)) {
            $cls = strtolower($c[1]);
            foreach (['site-logo', 'avatar', 'trp-flag', 'logo-', 'gravatar'] as $skip) {
                if (strpos($cls, $skip) !== false) return false;
            }
        }
        $src_out = $src;
        return true;
    };

    $i = 0;
    $html = preg_replace_callback('/<img\b[^>]*>/i', function ($m) use ($is_content_img, $eager_count, &$i) {
        $tag = $m[0];
        $src = '';
        if (!$is_content_img($tag, $src)) return $tag;
        $i++;
        $tag = preg_replace('/\s+(loading|decoding|fetchpriority)=["\'][^"\']*["\']/i', '', $tag);
        if ($i <= $eager_count) {
            if ($i === 1) {
                $tag = preg_replace('/<img\b/i', '<img fetchpriority="high" loading="eager" decoding="async"', $tag, 1);
            } else {
                $tag = preg_replace('/<img\b/i', '<img loading="eager" decoding="async"', $tag, 1);
            }
        } else {
            $tag = preg_replace('/<img\b/i', '<img loading="lazy" decoding="async"', $tag, 1);
        }
        return $tag;
    }, $html);

    return $html;
}

function meow_get_eager_count() {
    if (is_front_page() || is_home() || is_tag() || is_category() || is_author()) {
        return (int) apply_filters('meow_archive_eager_count', 5);
    }
    if (is_search()) {
        return (int) apply_filters('meow_search_eager_count', 5);
    }
    if (is_single()) {
        return 2;
    }
    return (int) apply_filters('meow_default_eager_count', 3);
}

2. JS Defer: Prevents scripts from blocking rendering

This code adds to the front-end script defer Properties. It excludes jQuery and jQuery migration scripts. Because many themes use $() Inline calls. When a script is marked with `defer`, the browser continues to parse the HTML. This prevents JavaScript from blocking the rendering of the first screen, resulting in a shorter LCP time.

// JS defer
add_filter('script_loader_tag', function ($tag, $handle, $src) {
    if (is_admin()) return $tag;
    $exclude = ['jquery', 'jquery-core', 'jquery-migrate'];
    if (in_array($handle, $exclude, true)) return $tag;
    if (strpos($tag, ' defer') !== false || strpos($tag, ' async') !== false) return $tag;
    return str_replace(' src=', ' defer src=', $tag);
}, 10, 3);

3. Asynchronous Loading of Non-Critical CSS: Reduce Render Blocking

This code identified three non-critical style sheets. They are not required for the above-the-fold content. The code uses preloadonload Load these CSS files asynchronously. For browsers that do not support JavaScript, use noscript Load. This way, the browser won't wait for these style sheets. The above-the-fold rendering is faster.

// 非关键 CSS 异步
add_filter('style_loader_tag', function ($html, $handle, $href) {
    if (is_admin()) return $html;
    $async = [
        'trp-language-switcher-v2.css',
        'bbhcuschma-style.css',
        'perf_metrics/style.css',
    ];
    foreach ($async as $p) {
        if (strpos($href, $p) !== false) {
            return '<link rel="preload" as="style" href="' . esc_url($href)
                 . '" onload="this.rel=\'stylesheet\'">'
                 . '<noscript><link rel="stylesheet" href="' . esc_url($href) . '"></noscript>';
        }
    }
    return $html;
}, 10, 3);

4. Preconnect: Preconnect to a third-party domain

This code adds three preconnect Tip: The browser establishes connections to statistics, tab management, and avatar services in advance. By the time the page needs to request these resources, the connections are already in place. This reduces latency for subsequent requests and improves overall page load speed.

// preconnect
add_action('wp_head', function () {
    echo '' . "\n";
    echo '' . "\n";
    echo '' . "\n";
}, 1);
Previous Article CapCut Keyboard Shortcuts, Windows & Mac Cheat Sheet
Next Article AeroCore Theme SEO Optimization: Prevent indexing of date and search pages; add page numbers to pagination titles