Edit in JSFiddle

const app = (() => {
  const imgSmall = document.querySelector('.img-small')

  const loadImage = () => {
    const img = new Image()

    img.src = imgSmall.src
    img.addEventListener('load', (e) => {
      imgSmall.classList.add('loaded')
    }, false)

    const imgLarge = new Image()

    imgLarge.src = imgSmall.dataset.large
    imgLarge.addEventListener('load', (e) => {
      imgLarge.classList.add('loaded')
    }, false)

    imgSmall.parentNode.appendChild(imgLarge)
  }

  return {
    loadImage
  }

})()

app.loadImage()
<section class="banner">
  <div class="placeholder"></div>
  <img
    class="img-small"
    src="https://cdn-images-1.medium.com/freeze/max/27/1*sg-uLNm73whmdOgKlrQdZA.jpeg?q=20"
    data-large="https://cdn-images-1.medium.com/max/1800/1*sg-uLNm73whmdOgKlrQdZA.jpeg"
   >
</section>
.banner {
  position: relative;
  overflow: hidden;
}

.placeholder {
  padding-bottom: 66.6%;
}

img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  opacity: 0;
  transition: opacity 1s linear;
}

img.loaded {
  opacity: 1;
}

.img-small {
  filter: blur(50px);
  -webkit-filter: blur(50px);
}