Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy load cover image #57

Open
gingerchew opened this issue May 8, 2020 · 7 comments
Open

Lazy load cover image #57

gingerchew opened this issue May 8, 2020 · 7 comments

Comments

@gingerchew
Copy link

gingerchew commented May 8, 2020

This was briefly mentioned in #48 but since Firefox now supports loading="lazy", does it make sense to investigate moving away from background: url(...); and into inserting an <img src="..." loading="lazy" alt="" aria-hidden="true"/> tag as the cover image instead?

Lighthouse keeps bugging me to defer my lite-youtube cover images, so I wanted to see if others were having the same before I make something janky or something good, haha

I'd be happy to help!

@Garbee
Copy link
Contributor

Garbee commented May 12, 2020

Safari still seems to be missing support. So I guess we'd need a perf comparison on that browser (especially mobile) to really make the decision on this. At least that's the benchmark I'd use for whether to switch now or wait it out.

@paulirish do you have any immediate preference here on which method to go with without having data on hand?

@gingerchew
Copy link
Author

Maybe another solution is to use something like this Smashing Magazine article. A pseudo-hybrid-lazyloading. I was thinking it'd just be something simple like:

	...
	connectedCallback() {
	
		if ("loading" in HTMLImageElement.prototype) {
			LiteYTEmbed.addCoverImage(this.posterUrl);
		} else {
	        this.style.backgroundImage = `url("${this.posterUrl}")`;
		}
	
		// ...
    }

	// ...

	static addCoverImage(imageUrl) {

		const attrs = {
			loading: "lazy"
			src: imageUrl,
			alt: "",
			// other attributes
		}

		const image = document.createElement('img');

		for (let [key, value] in Object.entries(attrs)) {
			image.setAttribute(key, value);
		}

		// add necessary styles and stuffs

		this.append(image);
	}

That way you don't have to go all in on loading="lazy".

@Fiorinol
Copy link

I'm having the same issue here. Unfortunately, the cover image being a background-image css style is a dealbreaker for me. It's roughly a 30 kilobytes added load per image above the fold. With Google's upcoming web vitals changes, I'm trying to shave off any unnecessary load above the fold.

What would be the best way to just have an img element inside the lite-youtube html? Would that even be possible?

Have you managed anything @Frankie-tech ?

@gingerchew
Copy link
Author

Not really, kinda fell by the wayside. At my job, we made this change to circumvent the loading of the HQ default thumbnail and instead load our own. None of us really like it though.

One solution I saw on CSS-Tricks that I'll probably be using for now is the srcdoc attribute for iframe elements. The article is here, but long of the short, add an iframe with a regular src attribute with an embed url, like https://www.youtube.com/embed/Y8Wp3dafaMQ. Then add a srcdoc attribute that will "describe" the temporary HTML of the iframe.

Example is taken from the CSS Tricks article.

<!-- 
	Inside of srcdoc you can change the img src to whatever you want it to be,
	the example just uses the hqdefault
-->
<iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/Y8Wp3dafaMQ"
  srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href=https://www.youtube.com/embed/Y8Wp3dafaMQ?autoplay=1><img src=https://img.youtube.com/vi/Y8Wp3dafaMQ/hqdefault.jpg alt='Video The Dark Knight Rises: What Went Wrong? – Wisecrack Edition'><span>▶</span></a>"
  frameborder="0"
  allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
  allowfullscreen
  title="The Dark Knight Rises: What Went Wrong? – Wisecrack Edition"
></iframe>

It's not perfect, but it's simple and easy to implement when you've got a deadline 🙂

@Fiorinol
Copy link

Fiorinol commented Feb 2, 2021

I see @Frankie-tech , I tried using what was suggested on CSS-Tricks, but it caused a plethora of other issues for a client. That's why I ended up using this javascript to begin with.

My issue isn't with loading the image from Youtube as much as it is that the images load above the fold (IE not lazy-loaded). That 30kb image per youtube iframe adds up quickly.

@gingerchew
Copy link
Author

gingerchew commented Feb 2, 2021

Okay, I see what you're saying. Since this is just a custom element, you might be able to swap in an <img /> element and remove the background image code. Then when the custom element activates, you can hide the image.

This is just a proof of concept, but I think this will work:

lite-youtube > img {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    transition: opacity 0.35s ease-out, visibility 0 linear 0.35s;
}
.lyt-activated > img {
    opacity: 0;
    visibility: 'hidden';
}
<!-- I'm assuming you're using lazysizes, if not just use whatever img lazyloading library -->
<lite-youtube videoid="ogfYd705cRs">
    <!-- adding a transparent gif placeholder -->
    <img
        src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
        data-src="https://i.ytimg.com/vi/ogfYd705cRs/hqdefault.jpg" 
        loading="lazy"
        alt="..." class="lazyload" height="X" width="X" />
</lite-youtube>

and then just remove the background image code inside the lite-youtube Javascript.

If you're using lazysizes and still want to use loading="lazy" remember to add the plugin.

No guarantees on whether or not this will work, though. Good luck 😊

@gingerchew
Copy link
Author

Now that safari has enabled loading="lazy" by default (as of 15.4, maybe this can be revisited?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants