Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Responsive images and how to implement them in Neos

Responsive images and how to implement them in Neos

Rendering images with optimal quality and minimal payload size is surprisingly complex because of the range of user-devices and network conditions. The talk will cover the standards behind responsive images and show the implementation in vanilla Neos and with Sitegeist.Kaleidoscope.

Usertracking aside images are the major payload of recent websites and while the standards regarding image rendering in HTML are not overly complex the details get complicated fast. Especially in a CMS like Neos where most of the work has to be automated.

In the main part of the talk I will give an overview about the relevant html-standards for responsive images like img.sizes, img.srcset and picture + source, how those actually work and should be used for optimal user experience. Following that I will demonstrate how this is implemented using off the shelf Neos and compare this to the optimized workflow we implemented with our package Sitegeist.Kaleidoscope.

Sitegeist

April 29, 2022
Tweet

More Decks by Sitegeist

Other Decks in Programming

Transcript

  1. Real Values.
    Responsive images and how to implement them
    HTML & Sitegeist.Kaleidoscope
    Martin Ficzel
    Photo by Malcolm Lightbody on Unsplash

    View Slide

  2. Real Values.
    Martin Ficzel
    ● Backend Developer
    ● fi[email protected]
    ● twitter/slack: @kopfaufholz
    ● Neos Team-Member
    Atomic-Fusion, AFX, Fusion-Forms
    ● Sitegeist.Monocle,
    Sitegeist.Kaleidoscope,
    Sitegeist.MagicWand

    View Slide

  3. Real Values.
    Quick Poll: Who are you ?
    ● Who is Backend Developer
    ● Who is Integrator
    ● Who is Frontend Developer
    ● Who is Project Management
    ● Who has not raised the hand yet
    󰢧
    󰢨
    󰢨

    View Slide

  4. Real Values.
    Responsive images and how to implement them
    ● Why is that relevant
    ● The relevant HTML standards
    ● CMS specific challenges & the
    solution we ended up with
    ● Questions

    View Slide

  5. Real Values.
    Why is that relevant!
    4 Reasons

    View Slide

  6. Real Values.
    1. Devices
    600 > 6000 px

    View Slide

  7. Real Values.
    2. Bandwidth
    https://op.europa.eu/webpub/eca/special-reports/broadband-12-2018/de/
    Rural areas
    General

    View Slide

  8. Real Values.
    3. Timing
    ● Images are requested during parsing
    ● At the same time as CSS and JS
    ● Browsers only know about the HTML at that
    stage

    View Slide

  9. Real Values.
    4. Payload
    ● HTML 10 > 100 KB
    ● CSS 10 > 100 KB
    ● JS 100 > 500 KB
    ● Images 1000 > 2500 KB
    * unscientific guestimation

    View Slide

  10. Real Values.
    You can mess up performance in many ways
    but you cannot achieve great performance
    without caring for responsive-images!

    View Slide

  11. Real Values.
    Responsive images in HTML
    a simplified overview

    View Slide

  12. Real Values.
    1992 - HTML 1.0

    View Slide

  13. Real Values.
    HTML 2.0 - 4.0
    src="example.jpg"
    alt="Image showing things"
    title="Example image"
    width="600" height="400"
    />

    View Slide

  14. Real Values.
    The long sleep
    ● One highres image will be fine for
    all once bandwidth becomes cheap
    ● Then Smartphones and Tablets
    became popular
    ● And mobile use became common

    View Slide

  15. Real Values.
    JS - Experiments
    src="…placeholder…"
    data-src-200="example-200.jpg"
    data-src-400="example-400.jpg"
    data-src-600="example-600.jpg"
    />
    🪄

    View Slide

  16. Real Values.
    1x
    2x
    Multiple Resolutions

    View Slide

  17. Real Values.
    1x
    2x
    Multiple Resolutions
    src="example.jpg"
    srcset="example-600.jpg 2x, example-300.jpg 1x, exa
    />
    candidate-url descriptor

    View Slide

  18. Real Values.
    Multiple Resolutions

    View Slide

  19. Real Values.
    Multiple Sizes

    View Slide

  20. Real Values.
    Multiple Sizes

    View Slide

  21. Real Values.
    600w
    800w
    1000w
    1200w
    Multiple Sizes

    View Slide

  22. Real Values.
    600w
    800w
    1000w
    1200w
    src="example.jpg"
    sizes="(max-width: 320px) 280px, … , … , 50vw"
    srcset="example-320w.jpg 320w, example-480w.jpg 48
    />
    media-query
    size-hint
    candidate-url width-descriptor
    Multiple Sizes
    default

    View Slide

  23. Real Values.
    - Art direction
    Case 1, same cat different crops

    View Slide

  24. Real Values.
    - Art direction
    🌙 ☀
    Case 2: Different cat depending on use case

    View Slide

  25. Real Values.
    - Art direction

    media="(orientation: landscape)"
    srcset="..." sizes="..." width="..." height="..
    media="(orientation: portrait)"
    srcset="..." sizes="..." width="..." height=".


    View Slide

  26. Real Values.
    - Multiple formats

    View Slide

  27. Real Values.
    - Multiple formats

    type="image/webp"
    srcset="..." sizes="..." width="..." height="..
    type="image/avif"
    srcset="..." sizes="..." width="..." height="

    /picture>

    View Slide

  28. Real Values.
    Cat loading behavior

    View Slide

  29. Real Values.
    Image loading behavior
    src="example.jpg"
    loading="eager"
    loading="lazy"
    />
    Request when close to viewport
    Or never
    Request immediately during parsing

    View Slide

  30. Real Values.
    Cat appearance behavior

    View Slide

  31. Real Values.
    Image appearance behavior
    CSS
    Request immediately during parsing
    src="example.jpg"
    width="600"
    height="400"
    style="aspect-ratio: 4/3;"
    />

    View Slide

  32. Real Values.
    Future ● Smarter Browsers?
    ○ Consider current bandwidth
    ○ Consider CSS for lazy images
    ● Successor for JPEG / PNG?
    of cat images

    View Slide

  33. Real Values.
    Responsive images are not
    that hard

    View Slide

  34. Real Values.
    Non trivial to
    implement
    ● Editors can select images with
    different aspects
    ● Content Elements may be used in
    different contexts
    ● Separation of Integration and
    Presentation requires error prone
    communication of many urls

    View Slide

  35. Real Values.
    Hard to verify
    ● You can only spot low resolutions
    ● Offices have fast networks
    ● Browsers other than Firefox stick to
    highres Versions

    View Slide

  36. Real Values.
    Sitegeist.Kaleidoscope
    responsive images for Neos

    View Slide

  37. Real Values.
    Quick Poll: Who knows Kaleidoscope ?
    ● Who has heard about Kaleidoscope
    ● Who actually tested it
    ● Who uses it all the time
    󰢧
    󰢨
    󰢨

    View Slide

  38. Real Values.
    the idea
    ● Avoid creating dozens of urls
    ● Decide on dimensions in
    presentation
    ● Make mistakes visible
    ● In other aspects stay close to
    HTML

    View Slide

  39. Real Values.
    AssetImageSource
    imageSource = Sitegeist.Kaleidoscope:AssetImageSource
    {
    asset = ${q(node).property("image")}
    title = ${q(node).property("title")}
    alt = ${q(node).property("alternateText")}
    }

    View Slide

  40. Real Values.
    Kaleidoscope:Image
    imageSource={props.imageSource}
    srcset="600w, 800w, 1200w, 1600w, 2400w"
    sizes="(max-width: 800px) 100vw, (max-width: 1200
    width="600"
    loading="eager"
    format="webp"

    View Slide

  41. Real Values.
    Kaleidoscope:Picture
    media="(orientation: portrait)"
    width="400" height="400"
    srcset="400w, 800w, 1200w"
    sizes="50vw"
    />
    imageSource={props.otherImageSource}
    edia=”(orientation: landscape) and (max-wi
    00w, 8000w"

    View Slide

  42. Real Values.
    DummyImageSource
    imageSource = Sitegeist.Kaleidoscope:DummyImageSource {
    backgroundColor = '00ff00'
    baseWidth = 400
    baseHeight = 250
    }

    View Slide

  43. Real Values.

    View Slide

  44. Real Values.

    View Slide

  45. Real Values.
    Tips and Tricks

    View Slide

  46. Real Values.
    Eager loading in keyvisuals
    keyvisual = Vendor.Site:Fragment.Keyvisual {
    prototype(Sitegeist.Kaleidoscope:Image) {
    loading = 'eager'
    }
    prototype(Sitegeist.Kaleidoscope:Picture) {
    loading = 'eager'
    }
    }

    View Slide

  47. Real Values.
    Eager loading first content
    content = Neos.Neos:ContentCollection {
    nodePath = "main"
    content.iterationName = "mainContentIterator"
    prototype(Sitegeist.Kaleidoscope:Image) {
    loading = ${mainContentIterator.isFirst ? 'eager' : 'lazy
    }
    prototype(Sitegeist.Kaleidoscope:Picture) {
    loading = ${mainContentIterator.isFirst ? 'eager' : 'la

    View Slide

  48. Real Values.
    renderer = Neos.Fusion:Case {
    inMain {
    condition = ${q(node).parent().is('[instanceof Vendor.Site:
    renderer = Vendor.Site:Component.MainImage {
    imageSource = ${props.imageSource}
    }
    }
    inGrid {
    condition = ${q(node).parent().is('[instanceof Vendor.Sit
    renderer = Vendor.Site:Component.GridImage {
    imageSource = ${props.imageSource}
    One content, many presentations

    View Slide

  49. Real Values.
    Enforcing dummy images
    # Root.fusion
    prototype(Sitegeist.Kaleidoscope:Image) {
    [email protected] = Sitegeist.Kaleidoscope:DummyImage
    baseWidth = ${value.width()}
    baseHeight = ${value.height()}
    }
    }
    prototype(Sitegeist.Kaleidoscope:Picture) {
    [email protected] = Sitegeist.Kaleidoscope:DummyIm
    baseWidth = ${value.width()}
    baseHeight = ${value.height()}

    View Slide

  50. Real Values.
    What to take home

    View Slide

  51. Real Values.
    ● no rocket engineering
    ● not trivial and easy to mess up
    ● Tooling is needed
    ● like Sitegeist.Kaleidoscope

    View Slide

  52. Real Values.
    Questions?

    View Slide

  53. Real Values.
    Thank you!
    cat images from the internet:
    Pixabay, Unsplash, Rawpixel, Pexels, Wikipedia

    View Slide