Edit in JSFiddle

// Eseguo il codice quando il DOM è completamente caricato.
document.addEventListener("DOMContentLoaded", function() {

  // Dichiaro la variabile che conterrà le imamgini marcate con .lazy
  var lazyLoadImages;
  
  // Controllo se l'IntersectionObserver è supportato nel browser.
  if ("IntersectionObserver" in window) {
  
    // Recupero tutte le immagini marcata con la classe .lazy
    lazyLoadImages = document.querySelectorAll(".lazy");
    
    // Inizializzo l'oggetto IntersectionObserver.
    var imageObserver = new IntersectionObserver(function(entries, observer) {
    
      // Codice di callback da eseguire ogni volta che l'observer entra in funzione.
      entries.forEach(function(entry) {
      
        // Controllo se l'immagine è entrata nel viewport.
        if (entry.isIntersecting) {
        
          // Ottengo l'oggetto image.
          var image = entry.target;
          
          // rimuovo la classe .lazy dall'immagine.
          image.classList.remove("lazy");
          
          // Rimuovo il bind dell'observer.
          imageObserver.unobserve(image);
        }
      });
    });
    
    // Ciclo le immagini .lazy.
    lazyLoadImages.forEach(function(image) {
    
      // Per ogni immagine effettuo il bind dell'observer.
      imageObserver.observe(image);
    });
    
  } else {
  
    // Se l'oggetto IntersectionObserver non è supportato dal browser corrente, esegui il codice javascript che utilizza gli event listener.
    
    // Dichiaro la variabile di timeout.
    var lazyLoadThrottleTimeout;
    
    // Recupero tutte le immagini marcata con la classe .lazy
    lazyLoadImages = document.querySelectorAll(".lazy");
    
    // La funzione principale in binding agli eventi.
    function lazyLoad () {
    	
      // Controllo se devo annullare il timeout.
      if(lazyLoadThrottleTimeout) {
      	clearTimeout(lazyLoadThrottleTimeout);
      }
      
      // Configuro il timeout
      lazyLoadThrottleTimeout = setTimeout(function() {
      
        // Ottengo il valore del margine superiore della finestra.
        var scrollTop = window.pageYOffset;
        
        // Ciclo le immagini .lazy
        lazyLoadImages.forEach(function(img) {
        
          // Controllo se l'immagine corrente è entrata nel viewport.
          if(img.offsetTop < (window.innerHeight + scrollTop)) {
          
            // Sposto il valore di data-src dentro src.
            img.src = img.dataset.src;
            
            // rimuovo la classe .lazy dall'immagine.
            img.classList.remove('lazy');
          }
        });
        
        // Controllo se le immagini .lazy sono finite.
        if(0 == lazyLoadImages.length) {
        
          // Rimuovo gli event listener.
          document.removeEventListener("scroll", lazyLoad);
          window.removeEventListener("resize", lazyLoad);
          window.removeEventListener("orientationChange", lazyLoad);
        }
      }, 20);
    }
    
    // Effettuo il bind degli event listener.
    document.addEventListener("scroll", lazyLoad);
    window.addEventListener("resize", lazyLoad);
    window.addEventListener("orientationChange", lazyLoad);
  }
})
<div id="container">
  <h3>Implementazione della tecnica del Lazy Loading tramite la proprietà background-image via CSS</h3>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam at ligula non lorem facilisis finibus. Suspendisse turpis lacus, tempus sit amet dignissim sit amet, pretium non sem. Ut malesuada purus ac magna placerat, tempus commodo turpis consectetur. Nunc vitae metus vehicula nunc congue varius. Suspendisse egestas urna non finibus feugiat. Vestibulum maximus, nunc et tempus convallis, dui ante vestibulum est, in lobortis purus sapien eget lacus. Suspendisse cursus enim non quam mollis imperdiet. Pellentesque convallis eget nunc vitae fringilla. Fusce interdum, velit semper varius aliquet, eros sapien facilisis erat, iaculis vulputate erat arcu vel neque. Suspendisse dignissim hendrerit lorem. Etiam metus ex, finibus vitae iaculis vitae, iaculis non ex. Phasellus commodo id ante id consequat. Nunc consectetur viverra lacus non fringilla. Pellentesque nec nisl vulputate, sagittis nisl id, venenatis nisi. Nunc malesuada tellus a elit suscipit tempor.</p>
  <p>Nam lacinia tortor quis volutpat lacinia. Aliquam in orci in nunc vehicula maximus. Phasellus elementum nulla augue, at aliquam sem pulvinar dapibus. Vivamus molestie venenatis risus pulvinar interdum. Phasellus blandit tortor eget nulla sagittis auctor. Cras sed leo in velit lobortis euismod. Suspendisse non ante tellus.</p>
  <div id="bg-image" class="lazy"></div>
  <p>Nam lacinia tortor quis volutpat lacinia. Aliquam in orci in nunc vehicula maximus. Phasellus elementum nulla augue, at aliquam sem pulvinar dapibus. Vivamus molestie venenatis risus pulvinar interdum. Phasellus blandit tortor eget nulla sagittis auctor. Cras sed leo in velit lobortis euismod. Suspendisse non ante tellus.</p>
</div>
* {
  font-family: sans-serif;
}

#container {
  font-size: 20px;
  line-height: 30px;
  max-width: 400px;
}

#bg-image.lazy {
   background-image: none;
   background-color: #F1F1FA;
}
#bg-image {
  background-image: url("https://picsum.photos/400/300?image=1083");
  max-width: 400px;
  height: 300px;
}