Skip to content

Commit 930a18b

Browse files
authored
Reuse the same IntersectionObserver for all components #25 (#71)
1 parent 0d20a57 commit 930a18b

File tree

3 files changed

+33
-32
lines changed

3 files changed

+33
-32
lines changed

src/components/LazyLoadComponent.spec.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ describe('LazyLoadComponent', function() {
6666
isIntersectionObserverAvailable.mockImplementation(() => true);
6767
window.IntersectionObserver = jest.fn(function() {
6868
this.observe = jest.fn(); // eslint-disable-line babel/no-invalid-this
69+
this.unobserve = jest.fn(); // eslint-disable-line babel/no-invalid-this
6970
});
7071

7172
const lazyLoadComponent = mount(
@@ -93,6 +94,7 @@ describe('LazyLoadComponent', function() {
9394
isIntersectionObserverAvailable.mockImplementation(() => true);
9495
window.IntersectionObserver = jest.fn(function() {
9596
this.observe = jest.fn(); // eslint-disable-line babel/no-invalid-this
97+
this.unobserve = jest.fn(); // eslint-disable-line babel/no-invalid-this
9698
});
9799

98100
const lazyLoadComponent = mount(

src/components/PlaceholderWithoutTracking.jsx

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,64 +3,61 @@ import ReactDOM from 'react-dom';
33
import { PropTypes } from 'prop-types';
44
import isIntersectionObserverAvailable from '../utils/intersection-observer';
55

6+
const checkIntersections = entries => {
7+
entries.forEach(entry => {
8+
if (entry.isIntersecting) {
9+
entry.target.onVisible();
10+
}
11+
});
12+
};
13+
14+
const LAZY_LOAD_OBSERVERS = {};
15+
16+
const getObserver = threshold => {
17+
LAZY_LOAD_OBSERVERS[threshold] =
18+
LAZY_LOAD_OBSERVERS[threshold] ||
19+
new IntersectionObserver(checkIntersections, {
20+
rootMargin: threshold + 'px',
21+
});
22+
23+
return LAZY_LOAD_OBSERVERS[threshold];
24+
};
25+
626
class PlaceholderWithoutTracking extends React.Component {
727
constructor(props) {
828
super(props);
929

10-
const supportsObserver =
30+
this.supportsObserver =
1131
!props.scrollPosition &&
1232
props.useIntersectionObserver &&
1333
isIntersectionObserverAvailable();
1434

15-
this.LAZY_LOAD_OBSERVER = { supportsObserver };
16-
17-
if (supportsObserver) {
35+
if (this.supportsObserver) {
1836
const { threshold } = props;
1937

20-
this.LAZY_LOAD_OBSERVER.observer = new IntersectionObserver(
21-
this.checkIntersections,
22-
{ rootMargin: threshold + 'px' }
23-
);
38+
this.observer = getObserver(threshold);
2439
}
2540
}
2641

27-
checkIntersections(entries) {
28-
entries.forEach(entry => {
29-
if (entry.isIntersecting) {
30-
entry.target.onVisible();
31-
}
32-
});
33-
}
34-
3542
componentDidMount() {
36-
if (
37-
this.placeholder &&
38-
this.LAZY_LOAD_OBSERVER &&
39-
this.LAZY_LOAD_OBSERVER.observer
40-
) {
43+
if (this.placeholder && this.observer) {
4144
this.placeholder.onVisible = this.props.onVisible;
42-
this.LAZY_LOAD_OBSERVER.observer.observe(this.placeholder);
45+
this.observer.observe(this.placeholder);
4346
}
4447

45-
if (
46-
this.LAZY_LOAD_OBSERVER &&
47-
!this.LAZY_LOAD_OBSERVER.supportsObserver
48-
) {
48+
if (!this.supportsObserver) {
4949
this.updateVisibility();
5050
}
5151
}
5252

5353
componentWillUnmount() {
54-
if (this.LAZY_LOAD_OBSERVER && this.LAZY_LOAD_OBSERVER.observer) {
55-
this.LAZY_LOAD_OBSERVER.observer.unobserve(this.placeholder);
54+
if (this.observer) {
55+
this.observer.unobserve(this.placeholder);
5656
}
5757
}
5858

5959
componentDidUpdate() {
60-
if (
61-
this.LAZY_LOAD_OBSERVER &&
62-
!this.LAZY_LOAD_OBSERVER.supportsObserver
63-
) {
60+
if (!this.supportsObserver) {
6461
this.updateVisibility();
6562
}
6663
}

src/components/PlaceholderWithoutTracking.spec.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ describe('PlaceholderWithoutTracking', function() {
197197
isIntersectionObserverAvailable.mockImplementation(() => true);
198198
window.IntersectionObserver = jest.fn(function() {
199199
this.observe = jest.fn(); // eslint-disable-line babel/no-invalid-this
200+
this.unobserve = jest.fn(); // eslint-disable-line babel/no-invalid-this
200201
});
201202
const onVisible = jest.fn();
202203
const component = renderPlaceholderWithoutTracking({
@@ -211,6 +212,7 @@ describe('PlaceholderWithoutTracking', function() {
211212
isIntersectionObserverAvailable.mockImplementation(() => true);
212213
window.IntersectionObserver = jest.fn(function() {
213214
this.observe = jest.fn(); // eslint-disable-line babel/no-invalid-this
215+
this.unobserve = jest.fn(); // eslint-disable-line babel/no-invalid-this
214216
});
215217
const offset = 100000;
216218
const onVisible = jest.fn();

0 commit comments

Comments
 (0)