diff --git a/routes/_components/LazyImage.html b/routes/_components/LazyImage.html
index fe3c5d0d..2f71d5fe 100644
--- a/routes/_components/LazyImage.html
+++ b/routes/_components/LazyImage.html
@@ -1,15 +1,14 @@
 <div class="lazy-image" style={computedStyle} >
-  {#if displaySrc}
-    <img
-      class={className}
-      aria-hidden={ariaHidden}
-      {alt}
-      {title}
-      {width}
-      {height}
-      src={displaySrc}
-    />
-  {/if}
+  <img
+    class={className}
+    aria-hidden={ariaHidden}
+    {alt}
+    {title}
+    {width}
+    {height}
+    src={displaySrc}
+    ref:node
+  />
 </div>
 <style>
   .lazy-image {
@@ -23,20 +22,15 @@
   export default {
     async oncreate () {
       mark('LazyImage oncreate()')
-      let { src, fallback } = this.get()
       try {
-        await decodeImage(src)
-        this.set({ displaySrc: src })
+        await decodeImage(this.refs.node)
       } catch (e) {
-        if (fallback) {
-          this.set({ displaySrc: fallback })
-        }
+        this.set({ error: true })
       }
       stop('LazyImage oncreate()')
     },
     data: () => ({
-      displaySrc: void 0,
-      hidden: false,
+      error: false,
       fallback: void 0,
       background: '',
       width: void 0,
@@ -53,7 +47,8 @@
           height && `height: ${height}px;`,
           background && `background: ${background};`
         ].filter(Boolean).join('')
-      }
+      },
+      displaySrc: ({ error, src, fallback }) => ((error && fallback) || src)
     }
   }
 </script>
\ No newline at end of file
diff --git a/routes/_components/NonAutoplayImg.html b/routes/_components/NonAutoplayImg.html
index 6fb175e8..a9866ee3 100644
--- a/routes/_components/NonAutoplayImg.html
+++ b/routes/_components/NonAutoplayImg.html
@@ -7,6 +7,7 @@
   {height}
   src={displaySrc}
   on:mouseover="onMouseOver(event)"
+  ref:node
 />
 <style>
   .non-autoplay-zoom-in {
@@ -19,15 +20,12 @@
 <script>
   import { mouseover } from '../_utils/events'
   import { decodeImage } from '../_utils/decodeImage'
-  import { ONE_TRANSPARENT_PIXEL } from '../_static/media'
   import { classname } from '../_utils/classname'
 
   export default {
     async oncreate () {
-      let { staticSrc } = this.get()
       try {
-        await decodeImage(staticSrc)
-        this.set({ displaySrc: staticSrc })
+        await decodeImage(this.refs.node)
         this.fire('imgLoad')
       } catch (e) {
         this.fire('imgLoadError', e)
@@ -35,26 +33,24 @@
     },
     methods: {
       onMouseOver (mouseOver) {
-        let { src, staticSrc, displaySrc } = this.get()
-        if (displaySrc !== ONE_TRANSPARENT_PIXEL) {
-          this.set({ displaySrc: mouseOver ? src : staticSrc })
-        }
+        this.set({ mouseOver })
       }
     },
     events: {
       mouseover
     },
     data: () => ({
-      displaySrc: ONE_TRANSPARENT_PIXEL,
       alt: '',
-      title: ''
+      title: '',
+      mouseOver: false
     }),
     computed: {
       computedClass: ({ className, src, staticSrc, isLink }) => (classname(
         className,
         src !== staticSrc && 'non-autoplay-zoom-in',
         isLink && 'is-link'
-      ))
+      )),
+      displaySrc: ({ src, staticSrc, mouseOver }) => (mouseOver ? src : staticSrc)
     }
   }
 </script>
\ No newline at end of file
diff --git a/routes/_utils/decodeImage.js b/routes/_utils/decodeImage.js
index b6617779..0efbc12c 100644
--- a/routes/_utils/decodeImage.js
+++ b/routes/_utils/decodeImage.js
@@ -1,13 +1,9 @@
-export function decodeImage (src) {
-  if (typeof Image.prototype.decode === 'function') {
-    let img = new Image()
-    img.src = src
+export function decodeImage (img) {
+  if (typeof img.decode === 'function') {
     return img.decode()
   }
 
   return new Promise((resolve, reject) => {
-    let img = new Image()
-    img.src = src
     img.onload = resolve
     img.onerror = reject
   })