0% found this document useful (0 votes)
36 views74 pages

Optimizing Largest Contentful Paint

Uploaded by

Darpa-ha Das
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views74 pages

Optimizing Largest Contentful Paint

Uploaded by

Darpa-ha Das
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 74

LCP

Largest Contentful Paint


The render time of the largest content element
visible in the viewport.
First Contentful Paint ~Largest~ Contentful Paint
LCP players

(pre)fetching important assets early

Images - sizing and targeted appropriately

Fonts: progressive loading strategies

JS: enhancing content with little jank

3rd party JS: loading without blocking content


Fetching things sooner…

The many pre's


Preconnect
<link rel="preconnect" href="https://example.com" />

asks the browser to perform a connection to a domain in


advance.
DNS Prefetch
<link rel="dns-prefetch" href="https://example.com" /
>

asks the browser to perform a DNS resolution of a domain in


advance.
Preload
<link rel="preload" href="/scripts.js" as="script" />

tells the browser to download and cache a resource (like a


script or a stylesheet) as soon as possible. It's mandatory.
Potential impact of preloading
Possible "as" values
audio: Audio file, as typically used in <audio>.
document: An HTML document intended to be embedded by a <frame> or
<iframe>.
embed: A resource to be embedded inside an <embed> element.
fetch: Resource to be accessed by a fetch or XHR request, such as an
ArrayBuffer or JSON file.
font: Font file.
image: Image file.
object: A resource to be embedded inside an <object> element.
script: JavaScript file.
style: CSS stylesheet.
track: WebVTT file.
worker: A JavaScript web worker or shared worker.
video: Video file, as typically used in <video>.
Delivering Images
Images generally load unobtrusively
<img src="baseball.jpg" alt="…">
Data URIs: often an antipattern
<img src="data:text/
plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D…">
Aspect Ratio for CLS
Width & height are back!

<img src="baseball.jpg" width="600"


height="350" alt="…">
Don’t just optimize images,
make them responsive
Responsive images
<img src="sml.jpg" srcset=“sml.jpg 300w, lrg.jpg 800w”
sizes=“100vw”>

<picture>
<source srcset="large.png" media="(min-width: 800px)">
<source srcset="medium.jpg" media="(min-width: 400px)">
<img src="small.jpg" alt="…">
</picture>
Sml.jpg is 300px wide, and

The srcset syntax lrg.jpg is 800px wide

<img src="sml.jpg" srcset=“sml.jpg 300w, lrg.jpg 800w”


sizes=“100vw (max-width: 500px), 50vw” alt="…">
The srcset syntax
<img src="sml.jpg" srcset=“sml.jpg 300w, lrg.jpg 800w”
sizes=“100vw (max-width: 500px), 50vw” alt="…">

This image will be 100% viewport width up until 500px


viewport size, then it is 50% viewport width after that.
https://www.filamentgroup.com/lab/sizes-swap/
The Picture element syntax
<picture>
<source srcset="large.png" media="(min-width: 800px)">
<source srcset="medium.jpg" media="(min-width: 400px)">
<img src="small.jpg" alt="…">
</picture>

The rst one of these sources with a matching media query


wins!
If none, just use the img src as-is.
fi
http://usecases.responsiveimages.org/
Also good for image types
<picture>
<source srcset="awesome.webp" type="image/webp">
<img src="cool.jpg" alt="Alt Text!">
</picture>
Also good for image types
<picture>
<source srcset=“awesome.avif" type="image/avif">
<img src="cool.jpg" alt="Alt Text!">
</picture>
Great for art directed imagery
<picture>
<source src="large.jpg"
media="( (min-device-pixel-ratio: 1.5) and (min-width:
20.001em) and (max-width: 35.999em) ) or
( (max-device-pixel-ratio: 1.5) and (min-width:
120.001em) ) or
( (min-device-pixel-ratio: 1.5) and (min-width:
60.001em) )" />
<source src="medium.jpg"
media="( (max-device-pixel-ratio: 1.5) and (min-width:
20.001em) and (max-width: 35.999em) ) or
( (max-device-pixel-ratio: 1.5) and (min-width:
60.001em) ) or
Best bet: use both!
<picture>
<source srcset="small.jpg 400w, medium.jpg 800w"
sizes="(max-width: 400px) 100vw">

<source srcset="medium.jpg 800w, medium.jpg 1200w"


sizes="(max-width: 800px) 50vw">

<img src="large.jpg" alt="…">


</picture>
Loading SVGs
Performantly
External SVG… so many ways
<img src="skate.svg" alt="skateboard icon">

or… <svg width="100" height="100">


<use href="skate.svg"></use>
</svg>

or… <object data="skate.svg"></object>

or… background-image: url("skate.svg");


External SVG with control
<svg style="—wheelcolor: red;">
<use href="icons.svg#skateboard"></use>
</svg>

Inside icons.svg:

<svg>
<symbol id="skateboard">
<path style="fill: var(—wheelcolor, blue);">
https://frontstuff.io/multi-colored-svg-symbol-icons-with-css-variables
Preloading RWD
Images?
Preload a <picture> hero image
<link rel="preload" href="small.jpg" as="image"
media="(max-width: 399px)">
<link rel="preload" href="medium.jpg" as="image"
media="(min-width: 400px) and (max-width: 799px)">
<link rel="preload" href="large.jpg" as="image"
media="(min-width: 800px)">

<picture>
<source srcset="large.jpg" media="(min-width: 800px)">
<source srcset="medium.jpg" media="(min-width: 400px)">
<img src="sml.jpg" alt="…">
</picture>
Preload an image[srcset]…?
<img src="sml.jpg" srcset=“sml.jpg 300w, lrg.jpg 800w”
sizes=“100vw”>
How that would look…
<link rel="preload" imagesrcset="sml.jpg 300w, lrg.jpg
800w" imagesizes="100vw" as="image">

<img src="sml.jpg" srcset=“sml.jpg 300w, lrg.jpg 800w”


sizes=“100vw”>
Most images are
not that important…
https://afarkas.github.io/lazysizes/index.html
https://addyosmani.com/blog/lazy-loading/
So Lazy!
<img src="very-lazy.jpg loading="lazy">

<iframe src="ads.html" loading="lazy"></iframe>


Loading Video
Performantly
Video - like picture syntax!
<video controls playsinline poster="somevideo.jpg"
preload="none">
<source src="somevideo.webm" type="video/webm">
<source src="somevideo.mp4" type="video/mp4">
</video>
Video - make it responsive too.
<video controls playsinline poster="somevideo.jpg">
<source src="somevideo-sml.webm" media="(max-width: 400px)"
type="video/webm">
<source src="somevideo-sml.mp4" media="(max-width: 400px)"
type="video/mp4">
<source src="somevideo-lrg.webm" type="video/webm">
<source src="somevideo-lrg.mp4" type="video/mp4">
</video>
Short code tidbit.
<code attribute=”value”>
<morecode anotherattr=”value” />
<morecode anotherattr=”value” />
</code attribute=”value”>
Font rendering
Progressive font rendering

Standard

Optimized
No More JS: CSS font-display

@font-face {
font-family: “Nice Serif”;
src: url(niceserif.woff2);
font-display: swap;
}
h1 {
font-family: “Nice Serif”, “Georgia”, serif;
}
https://twitter.com/szynszyliszys/status/1126261253280649216
https://caniuse.com/#search=font-display
https://www.filamentgroup.com/lab/js-web-fonts.html
Grouped Repaints
var font = new FontFace( … );
var fontBold = new FontFace( … );
Promise.all([
font.load(),
fontBold.load()
]).then(function(loadedFonts) {
loadedFonts.forEach(function(font) {
document.fonts.add(font);
});
});
}
Adapt to User Preferences
function loadFonts() {
/* NOTE: Reuse the Group Repaints code snippet above,
here */
}

if( navigator.connection &&


navigator.connection.saveData ) {
} else {
loadFonts();
}
Adapt to User Context
function loadFonts() {
/* NOTE: Reuse the Group Repaints code snippet above,
here */
}

if( navigator.connection &&


( navigator.connection.effectiveType === "slow-2g" ||
navigator.connection.effectiveType === "2g" ) ) {
// do nothing
} else {
loadFonts();
}
https://www.zachleat.com/web/comprehensive-webfonts/
Identifying
Problems
https://filamentgroup.com
speedcurve.com
Over-reliance on JavaScript
for Content
Empty Body = Fragile/Slow!
<body>
<div id="app"></div>
</body>

<script>
createApp( "#app", data );
</script>
https://css-tricks.com/server-side-react-rendering/
https://developers.google.com/web/updates/2019/02/rendering-on-the-web
Tag Managers and the Double Delay

1st MP

When we started this process we had a collection of very
old scripts and couldn’t track the original requester. We
removed those on the premise that, if they were
important, people would get back in touch — no one did.

The Telegraph Engineering

https://medium.com/the-telegraph-engineering/improving-third-party-web-performance-at-the-telegraph-a0a1000be5
https://docs.adobelaunch.com/client-side-information/asynchronous-deployment#synchronous-vs-asynchronous
Good options; tough sells

Don't vary content for rst-time visits

Async the scripts, only change content far


down the page

Preconnect the scripts involved.

Move the content variation to the server-side


fi
At very least… preconnect the inevitable.

<link rel="preconnect" href="https://example.com/">

<script src="https://example.com/thirdparty-2.js"
async defer>
https://www.cloudflare.com/products/cloudflare-workers/
https://www.filamentgroup.com/lab/servers-workers.html

You might also like