Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions packages/gatsby-image/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const convertProps = props => {

// Cache if we've seen an image before so we don't bother with
// lazy-loading & fading in on subsequent mounts.
const imageCache = {}
const imageCache = Object.create({})
const inImageCache = props => {
const convertedProps = convertProps(props)
// Find src
Expand All @@ -40,7 +40,7 @@ const activateCacheForImage = props => {
}

let io
const listeners = []
const listeners = new WeakMap()

function getIO() {
if (
Expand All @@ -51,15 +51,15 @@ function getIO() {
io = new window.IntersectionObserver(
entries => {
entries.forEach(entry => {
listeners.forEach(l => {
if (l[0] === entry.target) {
// Edge doesn't currently support isIntersecting, so also test for an intersectionRatio > 0
if (entry.isIntersecting || entry.intersectionRatio > 0) {
io.unobserve(l[0])
l[1]()
}
if (listeners.has(entry.target)) {
const cb = listeners.get(entry.target)
// Edge doesn't currently support isIntersecting, so also test for an intersectionRatio > 0
if (entry.isIntersecting || entry.intersectionRatio > 0) {
io.unobserve(entry.target)
listeners.delete(entry.target)
cb()
}
})
}
})
},
{ rootMargin: `200px` }
Expand All @@ -70,8 +70,17 @@ function getIO() {
}

const listenToIntersections = (el, cb) => {
getIO().observe(el)
listeners.push([el, cb])
const observer = getIO()

if (observer) {
observer.observe(el)
listeners.set(el, cb)
}

return () => {
observer.unobserve(el)
listeners.delete(el)
}
}

const noscriptImg = props => {
Expand Down Expand Up @@ -159,7 +168,7 @@ class Image extends React.Component {
IOSupported = false
}

const hasNoScript = !(this.props.critical && !this.props.fadeIn)
const hasNoScript = !(props.critical && !props.fadeIn)

this.state = {
isVisible,
Expand Down Expand Up @@ -187,9 +196,15 @@ class Image extends React.Component {
}
}

componentWillUnmount() {
if (this.cleanUpListeners) {
this.cleanUpListeners()
}
}

handleRef(ref) {
if (this.state.IOSupported && ref) {
listenToIntersections(ref, () => {
this.cleanUpListeners = listenToIntersections(ref, () => {
const imageInCache = inImageCache(this.props)
if (
!this.state.isVisible &&
Expand Down