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

Silverstripe and Core Web Vitals

Tim
September 30, 2021

Silverstripe and Core Web Vitals

StripeCon '21 talk covering Google's Core Web Vitals, and implementing solutions within Silverstripe's Requirements class

Tim

September 30, 2021
Tweet

Other Decks in Technology

Transcript

  1. • What are ‘core web vitals’? • Testing and reporting

    • Basic strategies • Silverstripe requirements • Other useful tools • Implementing in the real-world Tim Burt github.com/DorsetDigital
  2. “Evaluating page experience for a better web” Tim Burt github.com/DorsetDigital

    https://developers.google.com/search/blog/2020/05/evaluating-page-experience
  3. “Evaluating page experience for a better web” Tim Burt github.com/DorsetDigital

    https://developers.google.com/search/blog/2020/05/evaluating-page-experience
  4. “Evaluating page experience for a better web” Tim Burt github.com/DorsetDigital

    https://developers.google.com/search/blog/2020/05/evaluating-page-experience
  5. “Evaluating page experience for a better web” Tim Burt github.com/DorsetDigital

    https://developers.google.com/search/blog/2020/05/evaluating-page-experience
  6. “Evaluating page experience for a better web” Tim Burt github.com/DorsetDigital

    https://developers.google.com/search/blog/2020/05/evaluating-page-experience
  7. LCP – Largest Contentful Paint Tim Burt github.com/DorsetDigital https://web.dev/vitals/ “The

    Largest Contentful Paint (LCP) metric reports the render time of the largest image or text block visible within the viewport, relative to when the page first started loading.”
  8. FID – First Input Delay Tim Burt github.com/DorsetDigital https://web.dev/vitals/ “FID

    measures the time from when a user first interacts with a page (i.e. when they click a link, tap on a button, or use a custom, JavaScript-powered control) to the time when the browser is actually able to begin processing event handlers in response to that interaction.”
  9. CLS – Cumulative Layout Shift Tim Burt github.com/DorsetDigital https://web.dev/vitals/ “CLS

    is a measure of the largest burst of layout shift scores for every unexpected layout shift that occurs during the entire lifespan of a page. A layout shift occurs any time a visible element changes its position from one rendered frame to the next.”
  10. • Chrome dev tools • Lighthouse • WebPageTest Tim Burt

    github.com/DorsetDigital • Chrome user experience report • Pagespeed Insights • Search Console ‘Lab’ tools ‘Field’ tools
  11. • Eliminate redundant code • Deliver images in the right

    format and specify dimensions • Lazy-load whenever possible • Prioritise visible content Tim Burt github.com/DorsetDigital Here are the headlines!
  12. Community modules Tim Burt github.com/DorsetDigital Enhanced Requirements module https://github.com/DorsetDigital/silverstripe-enhanced-requirements WebP

    capability detection https://github.com/BiffBangPow/silverstripe-webp-detection Image formatter module https://github.com/tractorcow/silverstripe-image-formatter
  13. Images Tim Burt github.com/DorsetDigital Image format and sizing <picture> <source

    type="image/webp" srcset="$Image.Format('webp').URL"> <img alt="$Title" class="img-fluid" src="$Image.URL" width="$Image.Width" height="$Image.Height"> </picture> Use the <picture> tag <div class="hero" style="background-image: url(' <% if $WebPSupport%> $BackgroundImage.ScaleMaxWidth(1920).Format('webp').URL <% else %> $BackgroundImage.ScaleMaxWidth(1920).URL <% end_if %> ')"></div> Use detection for background images
  14. Images Tim Burt github.com/DorsetDigital Lazy loading <picture> <source type="image/webp" srcset="$Image.Format('webp').URL">

    <img alt="$Title" class="img-fluid" src="$Image.URL" loading=”lazy” width="$Image.Width" height="$Image.Height"> </picture> Native support
  15. Images Tim Burt github.com/DorsetDigital Lazy loading <picture> <source type="image/webp" srcset="$Image.Format('webp').URL">

    <img alt="$Title" class="img-fluid" data-src="$Image.URL" src=”” loading=”lazy” width="$Image.Width" height="$Image.Height"> </picture> Supporting Safari & IE if ('loading' in HTMLImageElement.prototype) { //Populate the src attribute with the content of data-src and let the browser do its thing const images = document.querySelectorAll('img[loading="lazy"]'); images.forEach(img => { img.src = img.dataset.src; }); } else { // Dynamically import the LazySizes library to manage the loading logic const script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js'; document.body.appendChild(script); }
  16. Eliminate redundant code Tim Burt github.com/DorsetDigital • Be careful about

    including default framework / library builds • Break up resources into page and function-specific blocks • Defer when you can
  17. Prioritise visible content Tim Burt github.com/DorsetDigital Consider moving core functionality

    inline Requirements::css('themes/main/client/dist/css/core.css', '', ['inline' => true]); Requirements::javascript('themes/main/client/dist/javascript/core.js', ['inline' => true]); (Uses enhanced requirements module)
  18. Preload and Push! Tim Burt github.com/DorsetDigital Give the browser a

    hand protected function init() { parent::init(); $preload = HTML::createTag('link', [ 'rel' => 'preconnect', 'href' => 'https://use.typekit.net' ]); $preload .= HTML::createTag('link', [ 'rel' => 'preconnect', 'href' => 'https://p.typekit.net', 'crossorigin' => 'anonymous' ]); Requirements::insertHeadTags($preload); Requirements::css('https://use.typekit.net/eor1njj.css', '', ['preload' => true]); Requirements::javascript('https://cdnjs.cloudflare.com/ajax/libs/gsap/3.7.0/gsap.min.js', ['type' => false]); Requirements::javascript('https://cdnjs.cloudflare.com/ajax/libs/gsap/3.7.0/ScrollTrigger.min.js', ['type' => false]); Requirements::css('themes/main/client/dist/css/common.css', '', ['push' => true]); Requirements::javascript('themes/main/client/dist/javascript/lazyload_config.js', ['inline' => true, 'type' => false]); Requirements::javascript('themes/main/client/dist/javascript/core.js', ['inline' => true]); Requirements::javascript('themes/main/client/dist/javascript/common.js', ['type' => false, 'async' => true, 'defer' => true]); Requirements::css('themes/main/client/dist/css/core.css', '', ['inline' => true]); } (Uses enhanced requirements module)
  19. Don’t take my word for it! Tim Burt github.com/DorsetDigital •

    No two sites are the same • There is no ‘silver bullet’ solution • Adjust, test, repeat • Revisit once your client has been let loose!