wp-media / wp-rocket

Performance optimization plugin for WordPress
https://wp-rocket.me
GNU General Public License v2.0
692 stars 215 forks source link

LazyLoad video HTML elements and the associated poster attribute #2952

Open WordPresseur opened 4 years ago

WordPresseur commented 4 years ago

Is your feature request related to a problem? Please describe. For now, our LazyLoad feature will only the iframe HTML element. In Gutenberg, you can embed a video in autoplay and it will use the video HTML element:

<video class="wp-video-shortcode" id="video-317-1_html5" width="480" height="350" loop="1" autoplay="1" preload="auto" src="https://example.com/wp-content/uploads/2020/07/wp5-gutenberg.mp4?_=1" style="width: 480px; height: 350px;"><source type="video/mp4" src="https://example.com/wp-content/uploads/2020/07/wp5-gutenberg.mp4?_=1"><a href="https://test.romainvincent.com/wp-content/uploads/2020/07/wp5-gutenberg.mp4">https://example.com.com/wp-content/uploads/2020/07/wp5-gutenberg.mp4</a></video>

We can't LazyLoad it actually.

Describe the solution you'd like It could use other HTML element like video

Tabrisrp commented 4 years ago

As a note: The lazyload script we use is already capable of handling lazyload of the video element, so what are currently missing is detecting and transforming the video elements in the HTML during the optimization process

arunbasillal commented 3 years ago

Another markup that was suggested in - https://github.com/wp-media/wp-rocket/issues/3285

<video controls poster="lazy-wannabe.jpg">
  <source src="movie.mp4" type="video/mp4">
  Your browser does not support the video tag.
</video>
NataliaDrause commented 3 years ago

Related request for video poster: https://wordpress.org/support/topic/video-poster-dont-lazyload/

xxl-escort commented 3 years ago

PLEASE ADD THIS FEATURE, Every self hostet video have a poster... its important

Tabrisrp commented 3 years ago

Scope a solution ✅

We can add a new class to our lazyload library, to handle video elements.

In the class, we search for video elements in the HTML.

For each video element, do the following:

The new class will have to be loaded in the service provider, and in the lazyload subscriber. The subscriber is starting to do too much, so it could be interesting to see how we can split things into multiple subscribers, to reduce class complexity and spread the responsabilities into multiple objects.

Automated tests to be written for all the new code added.

Estimate the effort ✅

Effort [M]

viobru commented 3 years ago

Related ticket: https://secure.helpscout.net/conversation/1484962811/256444/

israel-clearpg commented 3 years ago

How do I vote for this? yes please. Lazy Load HTML video tags.

JohnTorvik commented 3 years ago

Related: https://secure.helpscout.net/conversation/1525052006/267066/

webtrainingwheels commented 3 years ago

https://secure.helpscout.net/conversation/1554354344/274685?folderId=377611

webtrainingwheels commented 3 years ago

https://secure.helpscout.net/conversation/1557819798/275506?folderId=4130695

straightvisions-matthias-bathke commented 3 years ago

This should be a nobrainer, please enable lazy loading for video-elements, as these are used in WP Block Editor.

straightvisions-matthias-bathke commented 3 years ago

Hotfix to enable lazy loading for HTML5 video tag via wp-rocket:

        add_filter('rocket_buffer', 'sv_lazy_load_videos', 999999);
        add_filter( 'rocket_lazyload_script_args', 'sv_lazy_load_videos_args' );
        function sv_lazy_load_videos($buffer){
            preg_match_all('/<video (.*?)\>/', $buffer, $videos);
            if(!is_null($videos)) {
                foreach($videos[1] as $index => $value) {
                    if(!preg_match('/data-src=/', $value)){ // not prepared for lazyload yet
                        $new_video = str_replace(array(
                            'class="',
                            'src=',
                            'poster='
                        ), array(
                            'class="rocket-lazyload ',
                            'data-lazy-src=',
                            'data-poster='
                        ), $videos[0][$index]);
                        $buffer = str_replace($videos[0][$index], $new_video, $buffer);
                    }
                }
            }

            return $buffer;
        }
        function sv_lazy_load_videos_args($inline_args){
            $inline_args['elements']['video']            = 'video[data-lazy-src]';

            return $inline_args;
        }
alexsoyes commented 3 years ago

Hotfix to enable lazy loading for HTML5 video tag via wp-rocket:

      add_filter('rocket_buffer', 'sv_lazy_load_videos', 999999);
      add_filter( 'rocket_lazyload_script_args', 'sv_lazy_load_videos_args' );
      function sv_lazy_load_videos($buffer){
          preg_match_all('/<video (.*?)\>/', $buffer, $videos);
          if(!is_null($videos)) {
              foreach($videos[1] as $index => $value) {
                  if(!preg_match('/data-src=/', $value)){ // not prepared for lazyload yet
                      $new_video = str_replace(array(
                          'class="',
                          'src=',
                          'poster='
                      ), array(
                          'class="rocket-lazyload ',
                          'data-lazy-src=',
                          'data-poster='
                      ), $videos[0][$index]);
                      $buffer = str_replace($videos[0][$index], $new_video, $buffer);
                  }
              }
          }

          return $buffer;
      }
      function sv_lazy_load_videos_args($inline_args){
          $inline_args['elements']['video']            = 'video[data-lazy-src]';

          return $inline_args;
      }

Sadly not working to me, filter rocket_buffer is never called on WP Rocket's plugin.

We really need WP media to fix this :)

NataliaDrause commented 3 years ago

Related: https://secure.helpscout.net/conversation/1625729810/293362/

straightvisions-matthias-bathke commented 3 years ago

Sadly not working to me, filter rocket_buffer is never called on WP Rocket's plugin.

We really need really media to fix this :)

This filter is triggered on generation of the cached version of the website, so you may try it e.g. logged out / inkognito mode when visting the page and cache is active.

alexsoyes commented 3 years ago

This filter is triggered on generation of the cached version of the website, so you may try it e.g. logged out / inkognito mode when visting the page and cache is active.

I guess you are using WP Rocket? Because even with no cache plugin (e.g. Cache Enabler), the filter does not seem to be triggered.

straightvisions-matthias-bathke commented 3 years ago

This filter is triggered on generation of the cached version of the website, so you may try it e.g. logged out / inkognito mode when visting the page and cache is active.

I guess you are using WP Rocket? Because even with no cache plugin (e.g. Cache Enabler), the filter does not seem to be triggered.

The filter is triggered on cache creation by wp-rocket. If you disable Cache Creation, this filter is never triggered at all. Once a html-cache-file is created for a post, this filter won't be triggered upon next cache-recreation for that post again.

NataliaDrause commented 2 years ago

Related: https://secure.helpscout.net/conversation/1626848151/293659?folderId=3864740

PaulSchiretz commented 2 years ago

Pleas add this soon, I'm going to replace some gif and apng images for speed reasons with mp4, pretty pointless if lazyloading doesn't work...

straightvisions-matthias-bathke commented 2 years ago

We've implemented the patch I've posted before in this ticket as opt-in-feature in our SV100 Companion Plugin: https://de.wordpress.org/plugins/sv100-companion/

Output

without our patch <video class="wp-block-cover__video-background intrinsic-ignore" autoplay muted loop playsinline src="..."></video>

with our patch plain (noscript) <video class="rocket-lazyload wp-block-cover__video-background intrinsic-ignore" autoplay muted loop playsinline data-lazy-src="..."></video>

with our patch in combination with wp-rocket lazyloading videos feature: <video class="rocket-lazyload wp-block-cover__video-background intrinsic-ignore entered lazyloaded" autoplay="" muted="" loop="" playsinline="" data-lazy-src="..." data-ll-status="loaded" src="..."></video>

girlie commented 2 weeks ago

Related: https://secure.helpscout.net/conversation/2709971205/512700/

CurlyFlow commented 2 weeks ago

Did this got lost somewhere? Its 2024 still no lazy loading for video elements? xD

When i add videos via wp bakery it does it like this: <video autoplay="" loop="" muted="" playsinline="" preload="auto"><source type="video/mp4" src="https://some.thing.com/XXX.mp4"></video>

neither wp rocket nor sv100 seem to try to lazy load it? (thats the copied code from frontend)

CurlyFlow commented 6 days ago

I dug a little bit around and used a free plugin which just replaces "xxxs" with "xxxxxx". Ive used that for images and videos, making my site even faster then with wp rocket. (use other plugin to cache response)

as a tip for everyone finding this thread