Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Boosting Frontend Speed: Quick Wins for Backend...

Boosting Frontend Speed: Quick Wins for Backend Developers

Page speed is a critical part of modern web application performance. From the speed of generating a response on the server, to how it ultimately gets rendered in the user's device, there are a number of areas we need to stay on top of. However, many devs are more comfortable with the backend side of things - happier working with APIs and CLIs than fighting CSS oddities, JS race conditions or images jumping around as a page loads. And that's before we even get to the fun of node js and npm versioning issues! As a result, many backend devs tend to shy away from performance issues caused on the frontend of the application.

Fortunately there are a number of "quick wins" available to backend devs to significantly boost frontend speed! In this talk, I cover a number of techniques to improve things like:
* Image loading
* Font rendering
* Video players
* Display ad performance

All of these can be improved by backend devs without getting bogged down in frontend tooling or frameworks, and make a rapid improvement to page speed scores. We'll also cover the metrics we can use to objectively measure the impact of our changes.

Avatar for Paul Conroy

Paul Conroy

December 06, 2025
Tweet

More Decks by Paul Conroy

Other Decks in Technology

Transcript

  1. From Dublin, Ireland Started playing with the web 30+ years

    ago (Notepad, Frontpage & Geocities!) CTO at Square1 conroyp.com / @conroyp Paul Conroy 👴 🌍 🇮🇪
  2. In the beginning • First website in 1991 • Plain

    text, links - simple! https://info.cern.ch/hypertext/WWW/TheProject.html
  3. In the beginning • First website in 1991 • Plain

    text, links - simple! • Img tag! Scrolling marquees! • Basic CSS
  4. In the beginning • First website in 1991 • Plain

    text, links - simple! • Img tag! Scrolling marquees! • Basic CSS
  5. In the beginning • First website in 1991 • Plain

    text, links - simple! • Img tag! Scrolling marquees! • Basic CSS -> More advanced CSS • Interactivity (Java applets, Flash, Javascript)
  6. Improved metrics • Stand-alone metrics • Objectively quantify performance •

    Core Web Vitals - how does the site “feel”? • Google search algorithm • CLS, LCP, INP
  7. Improved metrics • CLS - how much do things jump

    around on a page? • LCP - how long does it take to draw the biggest thing on the page? • INP - how long between clicking and seeing something happen? (menu open etc)
  8. • Uses same data Google uses in rankings • Based

    on real-world Chrome user data • More than page speed! Sitemaps, crawl errors, inbound links • Data has a lag of ~30 days https://search.google.com/search-console/ Search Console
  9. https://pagespeed.web.dev/ • Aggregate score 1 - 100 • Separate score

    for individual CWV metrics • Detailed information on reasons behind failing metrics Page Speed Insights
  10. • Aggregate score 1 - 100 • Separate score for

    individual CWV metrics • Detailed information on reasons behind failing metrics • Lab and “real world” data • Server cache of ~30 minutes https://pagespeed.web.dev/ Page Speed Insights
  11. • Runs locally in Chrome • Same as Page Speed

    Insights • Local conditions impact results (cookies, cache, etc) • Potential for significant variations run-to-run Lighthouse
  12. • Runs locally in Chrome • Same as Page Speed

    Insights • Local conditions impact results (cookies, cache, etc) • Potential for significant variations run-to-run • Lighthouse-php Lighthouse
  13. Lighthouse-PHP Consider a “?noads=1” url toggle to get a “raw”

    result https://spatie.be/docs/lighthouse-php/v1/introduction 💡
  14. Option 1 • Send the team snowboarding for 6 months

    • Browsers and hardware will improve in that time • Problem solved
  15. Option 1 • Send the team snowboarding for 6 months

    • Browsers and hardware will improve in that time • Problem solved • Might need an Option 2…
  16. • Images make up roughly 60% of average page load

    • More responsive sites → more image sizes being generated • Particularly tricky to manage when handling user- generated content! IMAGES JS HTML CSS, FONTS
  17. Image sizing • Stops the image from appearing too large

    • Still requires a large image download
  18. • Stops the image from appearing too large • File

    size is appropriate to the image being shown Image sizing • Stops the image from appearing too large • Still requires a large image download
  19. Choosing the right size • Detecting the browser size based

    on User Agent / headers • Generate different markup based on browser size
  20. Choosing the right size • Detecting the browser size based

    on User Agent / headers • Generate different markup based on browser size • Impact on URL-based caching • How does it handle device resizing after load?
  21. Responsive images • srcset allows multiple sizes to be specified

    in markup • Browser can determine best one to load • A single URL cache works fine! • Resizing of the browser? Right image size loaded • Getting the sizes right can be fiddly (high density devices)
  22. Smaller images • Webp - image format from Google •

    25 - 30% file size reduction, with minimal quality drop • Conversion support in many PHP image libraries • 15 years old, but widespread support only recently https://photutorial.com/image-format-comparison-statistics/
  23. • Important to “reserve” space! • Tell the browser how

    much space we’ll need • Different sizes on different devices? Define heights in media queries for each breakpoint
  24. Lazy loading • Only load assets when they are needed

    • Potentially save a lot of bandwidth • Load images just before they scroll into view
  25. Lazy loading • Only load assets when they are needed

    • Potentially save a lot of bandwidth • Load images just before they scroll into view
  26. THEN • Load polyfill library • When image top is

    near viewport, swap data-src and src • Scroll listener thrashed rendering thread! Polyfills
  27. THEN • Load polyfill library • When image top is

    near viewport, swap data-src and src • Scroll listener thrashed rendering thread! Polyfills
  28. • Tempting to apply loading=”lazy” to all images • Actively

    harmful if applied to images above the fold • Browser is trying to optimise loading - help it out! Lazyload everything?
  29. Lazy loading background images • Background images usually large, full

    width, lots of detail • CSS property - background-image • Some lazy loading polyfills support background images, some don’t!
  30. Lazy loading background images • Background images usually large, full

    width, lots of detail • CSS property - background-image • Some lazy loading polyfills support background images, some don’t! • IntersectionObserver replaces window.scroll
  31. Display ads • A developer has no way of knowing

    if an ad will show or not until the ad server responds • Page content “jumping” - very bad for CLS • Very annoying for users! • Accidental clicks, maybe good for site owners?
  32. Display ads • A developer has no way of knowing

    if an ad will show or not until the ad server responds • Page content “jumping” - very bad for CLS • Very annoying for users! • Accidental clicks, maybe good for site owners?
  33. Two-click penalty • Google adds overlay on ads, asks user

    to click again • Unexpected behaviour! Most users won’t click again • Google don’t tell you this is happening! • It doesn’t show to every user • How do we know when it’s happening?
  34. Two-click penalty • Google adds overlay on ads, asks user

    to click again • Unexpected behaviour! Most users won’t click again • Google don’t tell you this is happening! • It doesn’t show to every user • How do we know when it’s happening? 📉 📉 💸
  35. Avoiding the Two-click Penalty • Label ads clearly • Consistent

    spacing from content • Avoid areas near menus, buttons, etc • Prevention is better than cure!
  36. Reducing CLS • Min-height on the ad container, matching expected

    ad unit size • Same technique as with images
  37. • Min-height on the ad container, matching expected ad unit

    size • Same technique as with images • Ad loads in, taking the reserved space, no CLS or “Jumping” Reducing CLS
  38. • Min-height on the ad container, matching expected ad unit

    size • Same technique as with images • Ad loads in, taking the reserved space, no CLS or “Jumping” Reducing CLS
  39. Variable ad sizes? • Responsive ad sizes (single request in

    markup) • Google might give us more than we ask for! • How do we reserve the right space for each ad when we don’t know the size?
  40. Callbacks • Google Ad Manager has a slotRenderEnded callback •

    When an ad loads, check what div it was in • If ad is smaller than our min height, remove the min height
  41. Callbacks • Set min height to that of most popular

    ad unit • “Bakes in” some CLS, but should be net positive
  42. Results • Users experiencing bad CLS fell by 64% overnight

    • Regular review of most popular slots is critical
  43. User Engagement & SEO benefits! • Popular way to share

    content • Strong user engagement • Helps with SEO • Easy embed options • Hugely expensive payloads!
  44. Web components Lite Youtube Embed by Paul Irish This component:

    • Loads a placeholder image • On hover warms the connection to youtube • On click, swaps the image for the player code
  45. Web components Lite Youtube Embed by Paul Irish This component:

    • Loads a placeholder image • On hover warms the connection to youtube • On click, swaps the image for the player code
  46. Web components Lite Youtube Embed by Paul Irish This component:

    • Loads a placeholder image • On hover warms the connection to youtube • On click, swaps the image for the player code
  47. SEO impact • Google is good at recognising embedded videos!

    • Doesn’t recognise components so well • Use structured data alongside custom components • VideoObject schema https://schema.org/VideoObject
  48. Web fonts • A key part of a dynamic, attractive

    web • Brand “personality”, can brighten up dull sites • Customisation comes at a cost!
  49. • woff2 is all we need • Trim the markup

    • Delete extra font files
  50. Font subsetting • Removing all characters we won’t use •

    Glyphhanger, install via npm or pip • Convert to woff2 while we’re at it
  51. What happens if someone uses a character not in my

    font set? • Browser tries all the fonts defined in the font stack, in order • If the character is not found in any of them, fall back to the system font • If the system font has nothing, a placeholder box or empty space will show
  52. • MS Outlook converts :) :| and :( into smileys

    via Wingdings • Those Wingding character codes use the slots for J / K / L • No Wingdings on your system? Fall back to J / K / L in the next available font
  53. • Faster fonts, unblock rendering thread sooner • LCP is

    probably an image, but is in a queue • It’s critical to understand the data points you are looking at! Is this data telling me what I think it is?
  54. • When dealing with image issues, have we other blocking

    resources? • Improving font loading can unblock threads, allowing faster image loading • Holistic view - top line metrics rarely influenced by solely one thing
  55. ADDY OSMANI • Chrome engineering lead • Web performance •

    New browser features https://twitter.com/addyosmani RICK VISCOMI • Web Perf DevRel at Chrome • Optimisations for CWV • CrUX report data
 https://twitter.com/rick_viscomi WEB.DEV • All aspects of web dev • Sections focused on perf metrics
 https://web.dev/ SPATIE • Media Library • Lighthouse PHP • Self-host Google Fonts
 https://spatie.be/
  56. Takeaways? Images • Pre-sized correctly • Reserve space in the

    markup • Use native browser features, remove polyfills Fonts • Subsetting with Glyphanger • Avoid google fonts, self-host Ads • Reserve space (avoid CLS) • Avoid 2-click penalty! Labelling and positioning Videos • Use facades • SEO impact! Structured data