Posted in

Improving Page Speed and Core Web Vitals with IntersectionObserver in CodeIgniter 4

Page Speed depends reducing your page load time from 9.6s to under 2.0s and passing Core Web Vitals requires both backend optimizations and efficient frontend strategies. The IntersectionObserver API is a smart way to defer loading of offscreen elements (like images, iframes, or heavy scripts), improving metrics like Largest Contentful Paint (LCP), First Input Delay (FID), and Cumulative Layout Shift (CLS).

Page Speed using intersectionObserver in CodeIgniter 4
Source: https://www.pexels.com/photo/high-speed-night-train-in-motion-33059163/

Below is a streamlined guide to implement lazy loading using IntersectionObserver in your CodeIgniter 4 project.

Why Use IntersectionObserver API to increase Page Speed?

  • Efficient Lazy Loading: Loads images or resources only when they are close to entering the viewport.
  • Better User Experience: Faster initial render, since not all elements are fetched at once.
  • Improved Core Web Vitals: Reduces LCP and mitigates layout shifts by controlling loading behavior.

Implementation Process in CodeIgniter 4

1. Render “Lazy” Images in Your Views

Update your image tags to use a placeholder src and move the real image source to a data-src attribute.

<!-- In your CodeIgniter 4 view file -->
<img class="lazy" src="/images/placeholder.jpg" data-src="/images/real-image.jpg" alt="Descriptive Alt">
  • /images/placeholder.jpg: Small, low-quality placeholder or a blank image.
  • data-src: The actual image you want to load lazily.

2. Add the IntersectionObserver Script

Add the script below just before your closing </body> tag for deferred execution:

<script>
document.addEventListener("DOMContentLoaded", function() {
  const lazyImages = document.querySelectorAll('img.lazy');
  if ('IntersectionObserver' in window) {
    let imgObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          const img = entry.target;
          img.src = img.dataset.src;
          img.classList.remove('lazy');
          imgObserver.unobserve(img);
        }
      });
    }, {
      rootMargin: '200px 0px', // preload before they enter the viewport
      threshold: 0.01
    });
    lazyImages.forEach(function(img) {
      imgObserver.observe(img);
    });
  } else {
    // Fallback for unsupported browsers
    lazyImages.forEach(function(img) {
      img.src = img.dataset.src;
      img.classList.remove('lazy');
    });
  }
});
</script>

Key Points:

  • Switches real image into src as elements approach the viewport.
  • The rootMargin of 200px preloads images slightly before scrolling into view for better visual experience.
  • Removes .lazy class to avoid repeated processing.

3. Additional Optimizations to make better Page Speed

  • Compress Images: Use modern formats (WebP), reduce file sizes.
  • Minify CSS/JS: Avoid render-blocking resources.
  • Defer Non-Essential Scripts: Move heavy scripts to load after critical content.
  • Use Efficient Fonts: Limit to minimum font weights/styles.
  • Server-side Enhancements: Enable GZIP compression, set far-future cache headers, and use a CDN for static assets.

Summary Table: Steps and Impact

StepImplementationCore Web Vital Improved
Lazy load images/ElsIntersectionObserverLCP, FID, CLS
Compress & Optimize ImagesTinyPNG, WebP, etc.LCP
Defer/Async JS<script defer>FID, LCP
Minimize CSS/JSMinifiers, splittingFID, LCP
CDN/Cache Static ContentCDN, server headersAll

Example in CodeIgniter 4

Suppose you have a controller and a view for a portfolio/gallery:

Controller (app/Controllers/Gallery.php):

public function index()
{
    $data['images'] = [
        '/images/1.jpg',
        '/images/2.jpg',
        '/images/3.jpg',
    ];
    return view('gallery', $data);
}

View (app/Views/gallery.php):

<?php foreach ($images as $image): ?>
  <img class="lazy" src="/images/placeholder.jpg" data-src="<?= esc($image) ?>" alt="Gallery Image">
<?php endforeach; ?>
<!-- Place IntersectionObserver JS here (see script above) -->

Final Tips

  • Regularly run speed tests (Google PageSpeed Insights/Lighthouse).
  • Check Core Web Vitals in Google Search Console.
  • Continuously monitor and optimize as content and plugins evolve.

By effectively using IntersectionObserver for lazy-loading, along with complementary frontend and backend optimizations, you can significantly boost your site performance and meet Core Web Vitals standards.