Slide 1

Slide 1 text

performance.now() – October 2022 Optimising 
 Largest Contentful Paint Harry Roberts – @csswizardry

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

What is LCP?

Slide 4

Slide 4 text

—web.dev/lcp “Largest Contentful Paint (LCP) is an important, user-centric metric for measuring perceived load speed because it marks the point in the page load timeline when the page’s main content has likely loaded—a fast LCP helps reassure the user that the page is useful.”

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

What Is ‘Good’?

Slide 10

Slide 10 text

— web.dev/lcp

Slide 11

Slide 11 text

— csswz.it/3ybF0NK To confirm that a threshold is achievable, we require that at least 10% of origins currently meet the ‘good’ threshold.

Slide 12

Slide 12 text

Site-Speed Is More Than Just SEO

Slide 13

Slide 13 text

€11,520,126/yr A 500ms improvement in LCP is worth

Slide 14

Slide 14 text

Getting to ‘Good’

Slide 15

Slide 15 text

Solve Everything Beforehand

Slide 16

Slide 16 text

Solve Everything Beforehand LCP is a milestone timing DNS, TCP, TLS Redirects TTFB* First Paint First Contentful Paint* If any of these are slow, you’re already on the back foot.

Slide 17

Slide 17 text

Treo

Slide 18

Slide 18 text

Choose the Best Element

Slide 19

Slide 19 text

Choose the Best Element Not all candidates are born equal elements elements inside an element elements (the poster image is used) An element with a background image loaded via the url() function (as opposed to a CSS gradient) Block-level elements containing text nodes or other inline-level text element children. web.dev/lcp

Slide 20

Slide 20 text

We Love Text-Based LCPs

Slide 21

Slide 21 text

844ms 1403ms

Slide 22

Slide 22 text

@font-face { ... font-display: [ swap | optional ]; ... }

Slide 23

Slide 23 text

What About Imagery?

Slide 24

Slide 24 text

Slide 25

Slide 25 text

Time (s) 0 1 2 3 4 5 in poster background-image 4.373 3.164 2.619 3.144

Slide 26

Slide 26 text

background-image poster in

Slide 27

Slide 27 text

Time (s) 0 1 2 3 4 5 in poster background-image 4.373 3.164 3.901 3.144

Slide 28

Slide 28 text

background-image poster in

Slide 29

Slide 29 text

Is Good

Slide 30

Slide 30 text

Slide 31

Slide 31 text

Slide 32

Slide 32 text

The Preload Scanner

Slide 33

Slide 33 text

The Preload Scanner Faster for free… Invented in IE8 as the ‘Speculative Pre-Parser’. A secondary, inert, asynchronous, download-only parser. Decouples resource discovery/download from runtime executions. Made the web a lot, lot faster. In every single modern browser. Some resources are visible to the Preload Scanner, some are not.

Slide 34

Slide 34 text

After: parsing and downloading are now decoupled and asynchronous. Before: parse, discover, download, execute, parse, discover, download, execute, parse…

Slide 35

Slide 35 text

in Is Bad

Slide 36

Slide 36 text

Slide 37

Slide 37 text

in

Slide 38

Slide 38 text

in Is Bad What’s going on here? Reporting is broken— element not counted. is hidden from the Preload Scanner—it’s inherently slow. Statistically unlikely to use it, but I still wouldn’t recommend it.

Slide 39

Slide 39 text

poster Is Good

Slide 40

Slide 40 text

Slide 41

Slide 41 text

poster

Slide 42

Slide 42 text

poster Is Good A pleasant surprise poster behaves much like . poster is available to the Preload Scanner. If you do have a -LCP, make sure you use poster…

Slide 43

Slide 43 text

— csswz.it/3Cp1Js5 Currently, a video element with a poster image will have that poster image considered for LCP, but without one, whether it is not present or the video autoplays, the video is ignored (for LCP purposes). The first frame of a video, when painted, should be considered as an LCP candidate.

Slide 44

Slide 44 text

background-image Is Bad

Slide 45

Slide 45 text

...

Slide 46

Slide 46 text

background-image

Slide 47

Slide 47 text

background-image Is Bad No surprise at all background-image is hidden from the Preload Scanner. Background images are late-discovered resources. Browsers only request background images (and web fonts) if it knows the page needs them… And it doesn’t know that until it encounters the DOM node that needs it. background-image is inherently slow.

Slide 48

Slide 48 text

CSS Doesn’t Download Images…

Slide 49

Slide 49 text

…The Render Tree Does

Slide 50

Slide 50 text

— csswz.it/3rvESok The reason these resources (in this specific case, background images) are slow is because they aren’t requested until the browser is ready to paint the DOM node that needs them.

Slide 51

Slide 51 text

Not All Candidates Are Born Equal Takeaways… Ideally, a text-based candidate with appropriate font-display will be fastest. poster is nice and fast, but statistically unlikely to be used. in is broken—reports very fast but is actually among the slowest. background-image is likely very common but also inherently slow. is statistically most likely and is also pretty fast. Google may use the first frame of a video in future. That’s gonna hurt.

Slide 52

Slide 52 text

Common Mistakes

Slide 53

Slide 53 text

Don’t Lazy Load Your LCP

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

Slide 56

Slide 56 text

— Well-meaning developers Can’t we just add loading=lazy and the browser works out what to do?

Slide 57

Slide 57 text

loading=lazy hides the From the Preload Scanner

Slide 58

Slide 58 text

Slide 59

Slide 59 text

img[loading=lazy] { outline: 10px solid red; }

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

Don’t Build Your LCP 
 with JavaScript

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

LCPs built with JS contain extra steps. Use HTML. HTML is fast.

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

Don’t Host Off-Site

Slide 68

Slide 68 text

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

Image was 1.5× smaller, but took 2.6× longer!

Slide 71

Slide 71 text

Don’t Usurp* Your LCP 👑

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

46,287px2 32,943px2 44,485px2 44,485px2

Slide 74

Slide 74 text

Stretch Goals

Slide 75

Slide 75 text

Resource Hints

Slide 76

Slide 76 text

Slide 77

Slide 77 text

Resource Hints preload rel=preload is useful for late discovered resources. The clue is in the name—remember the Preload Scanner? This exposes otherwise hidden resources to the Preload Scanner. Generally speaking, don’t use rel=preload for resources already available in HTML. Useful if your LCP candidate is a background-image.

Slide 78

Slide 78 text

Discovered after CSS; fourth request; bandwidth heavily shared. LCP approx. 2s. Requested in parallel with CSS; exclusive use of bandwidth. LCP approx. 1.2s.

Slide 79

Slide 79 text

! Beware Google Chrome — csswz.it/3TcnPUv

Slide 80

Slide 80 text

Priority Hints

Slide 81

Slide 81 text

Slide 82

Slide 82 text

Priority Hints fetchpriority fetchpriority=high is useful for in-page resources. Also fetchpriority=[ low | auto ]. Reduces amount of time spent queueing. This is amazing. Allows us to control priorities! We need to understand what priorities are.

Slide 83

Slide 83 text

— csswz.it/3SCCjNh

Slide 84

Slide 84 text

No content

Slide 85

Slide 85 text

No content

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

No content

Slide 88

Slide 88 text

No content

Slide 89

Slide 89 text

No content

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

No content

Slide 92

Slide 92 text

auto high Change Discovered 794ms 771ms -23ms Queuing 2,160ms 0.85ms -2,159.15ms Duration 12,030ms 5,370ms -6,660ms LCP 13,795ms 4,960ms -8,835ms

Slide 93

Slide 93 text

Image Decoding

Slide 94

Slide 94 text

— csswz.it/3RwpeUk Image decoding is said to be synchronous if it prevents presentation of other content until it is finished.

Slide 95

Slide 95 text

Image Decoding decoding Tells the browser how to deal with image decode tasks. decoding=sync is useful for LCP candidates. Also decoding=[ async | auto ].

Slide 96

Slide 96 text

Slide 97

Slide 97 text

No content

Slide 98

Slide 98 text

Slide 99

Slide 99 text

No content

Slide 100

Slide 100 text

Slide 101

Slide 101 text

Slide 102

Slide 102 text

Summary

Slide 103

Slide 103 text

Summary Putting it all together… LCP is the final metric—solve everything that happens before it. Choose the best candidate—text is best; is good. Expose the LCP candidate early—we love HTML! Don’t work against yourself—don’t make silly mistakes. Step in and help the browser—use new APIs to push things further. Use new features sparingly—test everything.

Slide 104

Slide 104 text

Slides: csswz.it/lcp Thank You harry.is/for-hire