WordPress / performance

Performance plugin from the WordPress Performance Group, which is a collection of standalone performance modules.
https://wordpress.org/plugins/performance-lab/
GNU General Public License v2.0
345 stars 94 forks source link

Implement Facade Method for Rich Media iFrame Embeds #113

Open dainemawer opened 2 years ago

dainemawer commented 2 years ago

iFrames, especially those that load rich media formats like Youtube and Vimeo have generally been loaded and rendered on page load. This can often constitute a negative impact to page load speed as resources come from 3rd-party origins and can potentially pull in a lot of their own scripts.

The idea here would be to lazy-load rich media iFrames in order to improve page speed. One method of doing this, is known as the Facade method. Generally, this would apply to iFrames that are below the fold.

The facade method states that instead of loading the fully dynamic element, load a static element say an image instead, and then on a certain action, such as a mouseover or click: fetch, connect, render that 3rd-party resource.

There are number of libraries in the wild that already address this like: https://github.com/paulirish/lite-youtube-embed

The idea, and logic behind this implementation is not overly complicated and could find a good home in the performance plugin or core as an opt-in feature / default. Based on my research, this could be an added feature to certain Gutenberg blocks which would aid in Frontend performance.

More information:

futtta commented 2 years ago

The biggest challenge is getting a representative thumbnail image in the facade, which for YouTube when done correctly requires hooking into YouTube's API which in turn requires an API key which is ... a hassle (I'm the dev of WP YouTube Lyte).

dainemawer commented 2 years ago

@futtta what if this was left up to the user, to upload / assign an image from the media library? I don't think its too much of stretch.

futtta commented 2 years ago

That's certainly a possibility, but that requires quite a few extra steps to be executed by the user as opposed to just adding a normal embed, so not really ideal?

To be clear; one can with reasonable certainty "guess" the a thumbnail URL for normal YT video's (but not playlists) in low-ish resolution; https://i.ytimg.com/vi/<video id>/hqdefault.jpg

always works, but the resolution is not great. there is also maxresdefault.jpg, but not all video's have that.

And there's also webp, but don't think every video has that available either; https://i.ytimg.com/vi_webp/<video id>/sddefault.webp

dainemawer commented 2 years ago

Fair point @futtta Theres also another avenue of setting a default placeholder for a user - maybe like a grey thumbnail image that can be filtered to be something closer to the brand tone of their site if need be, possibly if the the Youtube thumbnail is not present or the video has been taken download (which can also happen, and is a valid edge case)

In my opinion, the performance benefits out weighs the strain on the user, especially if we can take steps to mitigate it, ie default placeholder if youtube thumbnail is no present, other filter it and make it your own.

futtta commented 2 years ago

Ideal solution; upon a rich embed being added in the block editor (or being saved server-side) the thumbnail is fetched automatically and saved in the media library. If not available we automatically fallback on a (filterable) default one?

Additional advantages:

westonruter commented 2 years ago

If tapping the facade causes an iframe to be injected, a big problem here is on mobile where this will require a second tap to play the video. See also https://github.com/paulirish/lite-youtube-embed/issues/6

dainemawer commented 2 years ago

@futtta that sounds like a pretty good approach.

@westonruter - interesting - I see there's a lot of back and forth on that issue. I agree with your comment that there's no real difference between lazy loading the frame and using the IntersectionObserver - I'll give this some thought.

futtta commented 2 years ago

a big difference between a facade-implementation and lazyloading is that the facade remains in place even when in view, the iframe is only loaded when a visitor wants to see the video by clicking/ tapping play. the impact on performance when the video is above-the-fold is obviously big but indeed comes with the double-tap disadvantage which I have not found a workaround for.