Skip to content

Commit

Permalink
Fix blur-up preview image not working on initial page load (#14816)
Browse files Browse the repository at this point in the history
Previously this effect only worked for AJAX-based page loads. This change allows the effect to (mostly) work on initial load when the JS isn't yet loaded. If JS is already loaded then the original behaviour is preserved.

This increases the head size by 160 bytes but decreases the size of each image element by 103 bytes.

The head is only downloaded on initial page load (not AJAX loads), so if the visitor encounters 2 or more images during their visit then this change was worth it.
  • Loading branch information
YoshiWalsh authored and wardpeet committed Jul 4, 2019
1 parent 13abb7c commit c4a7c40
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 60 deletions.
1 change: 1 addition & 0 deletions packages/gatsby-remark-images/.gitignore
@@ -1,5 +1,6 @@
/constants.js
/gatsby-browser.js
/gatsby-ssr.js
/index.js
/__tests__/*
tests
Expand Up @@ -11,9 +11,8 @@ exports[`it handles goofy nesting properly 1`] = `
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"test\\"
title=\\"\\"
title=\\"test\\"
src=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg\\"
srcset=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg, not-a-real-dir/images/this-image-already-has-a-link.jpeg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
Expand All @@ -32,9 +31,8 @@ exports[`it leaves images that are already linked alone 1`] = `
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"img\\"
title=\\"\\"
title=\\"img\\"
src=\\"not-a-real-dir/image/my-image.jpg\\"
srcset=\\"not-a-real-dir/image/my-image.jpg, not-a-real-dir/image/my-image.jpg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
Expand All @@ -46,23 +44,23 @@ exports[`it leaves linked HTML img tags alone 1`] = `
"<a href=\\"https://example.org\\">
<span class=\\"gatsby-resp-image-wrapper\\" style=\\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 300px;\\">
<span class=\\"gatsby-resp-image-background-image\\" style=\\"padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw&apos;); background-size: cover; display: block;\\"></span>
<img class=\\"gatsby-resp-image-image\\" style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\" alt=\\"this image already has a link\\" title=\\"\\" src=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg\\" srcset=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg, not-a-real-dir/images/this-image-already-has-a-link.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
<img class=\\"gatsby-resp-image-image\\" alt=\\"this image already has a link\\" title=\\"this image already has a link\\" src=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg\\" srcset=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg, not-a-real-dir/images/this-image-already-has-a-link.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
</span>
</a>"
`;
exports[`it leaves single-line linked HTML img tags alone 1`] = `
"<span class=\\"gatsby-resp-image-wrapper\\" style=\\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 300px;\\">
<span class=\\"gatsby-resp-image-background-image\\" style=\\"padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw&apos;); background-size: cover; display: block;\\"></span>
<img class=\\"gatsby-resp-image-image\\" style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\" alt=\\"this image already has a link\\" title=\\"\\" src=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg\\" srcset=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg, not-a-real-dir/images/this-image-already-has-a-link.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
<img class=\\"gatsby-resp-image-image\\" alt=\\"this image already has a link\\" title=\\"this image already has a link\\" src=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg\\" srcset=\\"not-a-real-dir/images/this-image-already-has-a-link.jpeg, not-a-real-dir/images/this-image-already-has-a-link.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
</span>"
`;
exports[`it transforms HTML img tags 1`] = `
"<span class=\\"gatsby-resp-image-wrapper\\" style=\\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 300px;\\">
<a class=\\"gatsby-resp-image-link\\" href=\\"not-a-real-dir/image/my-image.jpeg\\" style=\\"display: block\\" target=\\"_blank\\" rel=\\"noopener\\">
<span class=\\"gatsby-resp-image-background-image\\" style=\\"padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw&apos;); background-size: cover; display: block;\\"></span>
<img class=\\"gatsby-resp-image-image\\" style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\" alt=\\"my image\\" title=\\"\\" src=\\"not-a-real-dir/image/my-image.jpeg\\" srcset=\\"not-a-real-dir/image/my-image.jpeg, not-a-real-dir/image/my-image.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
<img class=\\"gatsby-resp-image-image\\" alt=\\"my image\\" title=\\"my image\\" src=\\"not-a-real-dir/image/my-image.jpeg\\" srcset=\\"not-a-real-dir/image/my-image.jpeg, not-a-real-dir/image/my-image.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
</a>
</span>"
`;
Expand All @@ -71,7 +69,7 @@ exports[`it transforms HTML img tags with query strings 1`] = `
"<span class=\\"gatsby-resp-image-wrapper\\" style=\\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 300px;\\">
<a class=\\"gatsby-resp-image-link\\" href=\\"not-a-real-dir/image/my-image.jpeg\\" style=\\"display: block\\" target=\\"_blank\\" rel=\\"noopener\\">
<span class=\\"gatsby-resp-image-background-image\\" style=\\"padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw&apos;); background-size: cover; display: block;\\"></span>
<img class=\\"gatsby-resp-image-image\\" style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\" alt=\\"my image\\" title=\\"\\" src=\\"not-a-real-dir/image/my-image.jpeg\\" srcset=\\"not-a-real-dir/image/my-image.jpeg, not-a-real-dir/image/my-image.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
<img class=\\"gatsby-resp-image-image\\" alt=\\"my image\\" title=\\"my image\\" src=\\"not-a-real-dir/image/my-image.jpeg\\" srcset=\\"not-a-real-dir/image/my-image.jpeg, not-a-real-dir/image/my-image.jpeg\\" sizes=\\"(max-width: 650px) 100vw, 650px\\">
</a>
</span>"
`;
Expand All @@ -94,7 +92,6 @@ exports[`it transforms image references in markdown 1`] = `
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"alt text\\"
title=\\"Ref Image Title\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
Expand Down Expand Up @@ -123,9 +120,8 @@ exports[`it transforms images in markdown 1`] = `
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"image\\"
title=\\"\\"
title=\\"image\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
srcset=\\"not-a-real-dir/images/my-image.jpeg, not-a-real-dir/images/my-image.jpeg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
Expand All @@ -152,9 +148,8 @@ exports[`it transforms images in markdown with query strings 1`] = `
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"image\\"
title=\\"\\"
title=\\"image\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
srcset=\\"not-a-real-dir/images/my-image.jpeg, not-a-real-dir/images/my-image.jpeg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
Expand All @@ -181,9 +176,8 @@ exports[`it uses tracedSVG placeholder when enabled 1`] = `
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"image\\"
title=\\"\\"
title=\\"image\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
srcset=\\"not-a-real-dir/images/my-image.jpeg, not-a-real-dir/images/my-image.jpeg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
Expand Down Expand Up @@ -211,7 +205,6 @@ exports[`showCaptions display alt as caption if specified first in showCaptions
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"some alt\\"
title=\\"some title\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
Expand Down Expand Up @@ -243,7 +236,6 @@ exports[`showCaptions display alt as caption if specified in showCaptions array
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"some alt\\"
title=\\"some title\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
Expand Down Expand Up @@ -275,9 +267,8 @@ exports[`showCaptions display alt as caption if title was not found and showCapt
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"some alt\\"
title=\\"\\"
title=\\"some alt\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
srcset=\\"not-a-real-dir/images/my-image.jpeg, not-a-real-dir/images/my-image.jpeg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
Expand Down Expand Up @@ -307,7 +298,6 @@ exports[`showCaptions display title as caption if specified first in showCaption
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"some alt\\"
title=\\"some title\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
Expand Down Expand Up @@ -339,7 +329,6 @@ exports[`showCaptions display title as caption if specified in showCaptions arra
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"some alt\\"
title=\\"some title\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
Expand Down Expand Up @@ -371,7 +360,6 @@ exports[`showCaptions display title as caption when showCaptions === true 1`] =
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"some alt\\"
title=\\"some title\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
Expand Down Expand Up @@ -403,9 +391,8 @@ exports[`showCaptions fallback to alt as caption if specified second in showCapt
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"some alt\\"
title=\\"\\"
title=\\"some alt\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
srcset=\\"not-a-real-dir/images/my-image.jpeg, not-a-real-dir/images/my-image.jpeg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
Expand Down Expand Up @@ -435,7 +422,6 @@ exports[`showCaptions fallback to title as caption if specified second in showCa
></span>
<img
class=\\"gatsby-resp-image-image\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\\"
alt=\\"my image\\"
title=\\"some title\\"
src=\\"not-a-real-dir/images/my-image.jpeg\\"
Expand Down
10 changes: 10 additions & 0 deletions packages/gatsby-remark-images/src/constants.js
@@ -1,3 +1,13 @@
exports.DEFAULT_OPTIONS = {
maxWidth: 650,
wrapperStyle: ``,
backgroundColor: `white`,
linkImagesToOriginal: true,
showCaptions: false,
withWebp: false,
tracedSVG: false,
}

exports.imageClass = `gatsby-resp-image-image`
exports.imageWrapperClass = `gatsby-resp-image-wrapper`
exports.imageBackgroundClass = `gatsby-resp-image-background-image`
24 changes: 18 additions & 6 deletions packages/gatsby-remark-images/src/gatsby-browser.js
@@ -1,10 +1,13 @@
const {
DEFAULT_OPTIONS,
imageClass,
imageBackgroundClass,
imageWrapperClass,
} = require(`./constants`)

exports.onRouteUpdate = () => {
exports.onRouteUpdate = ({ pluginOptions }) => {
const options = Object.assign({}, DEFAULT_OPTIONS, pluginOptions)

const imageWrappers = document.querySelectorAll(`.${imageWrapperClass}`)

// https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
Expand All @@ -19,17 +22,26 @@ exports.onRouteUpdate = () => {

const onImageLoad = () => {
backgroundElement.style.transition = `opacity 0.5s 0.5s`
backgroundElement.style.opacity = 0
imageElement.style.transition = `opacity 0.5s`
onImageComplete()
}

const onImageComplete = () => {
backgroundElement.style.opacity = 0
imageElement.style.opacity = 1
imageElement.style.color = `inherit`
imageElement.style.boxShadow = `inset 0px 0px 0px 400px ${
options.backgroundColor
}`
imageElement.removeEventListener(`load`, onImageLoad)
imageElement.removeEventListener(`error`, onImageComplete)
}

imageElement.style.opacity = 0
imageElement.addEventListener(`load`, onImageLoad)
imageElement.addEventListener(`error`, onImageComplete)
if (imageElement.complete) {
backgroundElement.style.opacity = 0
} else {
imageElement.style.opacity = 0
imageElement.addEventListener(`load`, onImageLoad)
onImageComplete()
}
}
}
26 changes: 26 additions & 0 deletions packages/gatsby-remark-images/src/gatsby-ssr.js
@@ -0,0 +1,26 @@
import React from "react"

const { imageClass } = require(`./constants`)

exports.onRenderBody = ({ setHeadComponents }) => {
const style = `
.${imageClass} {
width: 100%;
height: 100%;
margin: 0;
vertical-align: middle;
position: absolute;
top: 0;
left: 0;
color: transparent;
}`
.replace(/\s*\n\s*/g, ``)
.replace(/: /g, `:`)
.replace(/ \{/g, `{`)

setHeadComponents([
<style type="text/css" key="gatsby-remark-images-styles">
{style}
</style>,
])
}
33 changes: 4 additions & 29 deletions packages/gatsby-remark-images/src/index.js
@@ -1,4 +1,5 @@
const {
DEFAULT_OPTIONS,
imageClass,
imageBackgroundClass,
imageWrapperClass,
Expand All @@ -24,18 +25,7 @@ module.exports = (
{ files, markdownNode, markdownAST, pathPrefix, getNode, reporter, cache },
pluginOptions
) => {
const defaults = {
maxWidth: 650,
wrapperStyle: ``,
backgroundColor: `white`,
linkImagesToOriginal: true,
showCaptions: false,
pathPrefix,
withWebp: false,
tracedSVG: false,
}

const options = _.defaults(pluginOptions, defaults)
const options = _.defaults(pluginOptions, { pathPrefix }, DEFAULT_OPTIONS)

const findParentLinks = ({ children }) =>
children.some(
Expand Down Expand Up @@ -163,26 +153,12 @@ module.exports = (
overWrites.alt ? overWrites.alt : node.alt ? node.alt : defaultAlt
)

const title = node.title ? node.title : ``

const imageStyle = `
width: 100%;
height: 100%;
margin: 0;
vertical-align: middle;
position: absolute;
top: 0;
left: 0;
box-shadow: inset 0px 0px 0px 400px ${options.backgroundColor};`.replace(
/\s*(\S+:)\s*/g,
`$1`
)
const title = node.title ? node.title : alt

// Create our base image tag
let imageTag = `
<img
class="${imageClass}"
style="${imageStyle}"
alt="${alt}"
title="${title}"
src="${fallbackSrc}"
Expand All @@ -200,7 +176,7 @@ module.exports = (
// override options if it's an object, otherwise just pass through defaults
options.withWebp === true ? {} : options.withWebp,
pluginOptions,
defaults
DEFAULT_OPTIONS
),
reporter,
})
Expand All @@ -223,7 +199,6 @@ module.exports = (
/>
<img
class="${imageClass}"
style="${imageStyle}"
src="${fallbackSrc}"
alt="${alt}"
title="${title}"
Expand Down

0 comments on commit c4a7c40

Please sign in to comment.