Chris Coyier (@css) has shared a code snippet that will add loading="lazy" to every scr=" instance in WordPress's content.

But this will replace every instance, not only in img or iframe tags, which can lead to some unwanted replacements.

Here's my version for that filter:

// in theme’s functions.php or a plugin
function wbr_add_lazy_loading($content){
  $content = preg_replace('/(< [^>]*?)(\ssrc=)(.*?\/?>)/','\1 loading="lazy" src=\3',$content);
  return $content;
}
add_filter('the_content','wbr_add_lazy_loading');

(! beware that WordPress here adds an empty space after the "<", look at the test link for the correct regex)

This should match all src attributes in tags, but excludes for example "data-src" from the match and doesn't care about single or double quoted attribute values.

I tested the regex here, but be careful if you try this - I have not tested it here in my WordPress instance yet.

Update: I updated the code and the test - it did still match the scr= in a sentence that had p tags.

If you're wondering why this "loading" attribute is something to look forward to, read Chris' post on CSS-tricks.

If you're more into Kirby CMS (which I would totally understand), this one is for you: Holger Bartel has just shared a way to include the newfangled loading attribute to the Kirbytext tags.