keycdn / cache-enabler

A lightweight caching plugin for WordPress that makes your website faster by generating static HTML files.
https://wordpress.org/plugins/cache-enabler/
123 stars 46 forks source link

Feature: .webp Background Images and Lazy Loading #9

Closed johnhearfield closed 6 years ago

johnhearfield commented 6 years ago

Currently, the plugin only targets only the following attributes: src, srcset and *-ref for changing the output to use .webp if the file exists.

It would be good to also target background images and those lazy-loaded (using attributes like 'data-bg'.

I have come up with a crude implementation:

# ... From line 286 cache_enable_disk.class.php

// Call the webp converter on background images
// TODO: Optimise this regex
$bg_regex_rule = '#(?:(?<=background-image: url)|(?<=background: url)|(?<=background-image:url)|(?<=background:url))(?:\([\'"]?)(.*?)(\.png|\.jp[e]?g)(.*?)(?:[\'"]?\))#';

$converted_data = preg_replace_callback($bg_regex_rule, function ($asset) {
    return _convert_webp_bg($asset[1] . $asset[2]);
}, $converted_data);

// Call the webp converter on data-bg
$databg_regex_rule = '#(?<=(?:(data-bg)=[\"\']))(?:http[s]?[^\"\']+)(\.png|\.jp[e]?g)(?:[^\"\']+)?(?=[\"\')])#';

$converted_data = preg_replace_callback($databg_regex_rule, function($asset) {
    return self::_convert_webp_src($asset[0]);
}, $converted_data);

The function _convert_webp_bg is based off of _convert_webp_src

function _convert_webp_bg($src) {
    $upload_dir = wp_upload_dir();
    $src_url = parse_url($upload_dir['baseurl']);
    $upload_path = $src_url['path'];

    if (strpos($src, $upload_path) !== false) {

        $src_webp = str_replace('.jpg', '.webp', $src);
        $src_webp = str_replace('.jpeg', '.webp', $src_webp);
        $src_webp = str_replace('.png', '.webp', $src_webp);

        $parts = explode($upload_path, $src_webp);
        $relative_path = $parts[1];

        // check if relative path is not empty and file exists
        if (!empty($relative_path) && file_exists($upload_dir['basedir'] . $relative_path)) {
            return sprintf('(%s)', $src_webp);
        } else {
            // try appended webp extension
            $src_webp_appended = $src . '.webp';
            $parts_appended = explode($upload_path, $src_webp_appended);
            $relative_path_appended = $parts_appended[1];

            // check if relative path is not empty and file exists
            if (!empty($relative_path_appended) && file_exists($upload_dir['basedir'] . $relative_path_appended)) {
                return sprintf('(%s)', $src_webp_appended);
            }
        }

    }

    return sprintf('(%s)', $src);
}

but we return the $src wrapped in parenthesis

svenba commented 6 years ago

Please open a pull request if this is a solid solution.

coreykn commented 3 years ago

Added in PR #116, updated in PR #125, and extended in PR #183.