Merge pull request #871 from sharetribe/improve-listingpage-lazy-loading

Improve listingpage lazy loading
This commit is contained in:
Vesa Luusua 2018-07-20 12:05:11 +03:00 committed by GitHub
commit fbdc110c7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 12 deletions

View file

@ -12,6 +12,10 @@ way to update this template, but currently, we follow a pattern:
---
## v1.2.1
* [fix] Lazy load map only if the map is near current viewport.
[#871](https://github.com/sharetribe/flex-template-web/pull/871)
## v1.2.0
* [change] Use Google's static map on ListingPage.
This is a reaction to pricing change of Google Maps APIs.

View file

@ -531,8 +531,9 @@
height: calc(100vh - 193px);
width: 100%;
/* Static map: max-width is 640px */
/* Static map: dimensions are 640px */
max-width: 640px;
max-height: 640px;
background-color: #eee;
@media (--viewportMedium) {

View file

@ -87,6 +87,10 @@ export const lazyLoadWithDimensions = (Component, options) => {
// First render default wait after mounting (small wait for styled paint)
const RENDER_WAIT_MS = 100;
// Scrolling and other events that affect to viewport location have this safety margin
// for lazy loading
const NEAR_VIEWPORT_MARGIN = 50;
class LazyLoadWithDimensionsComponent extends ReactComponent {
constructor(props) {
super(props);
@ -95,9 +99,9 @@ export const lazyLoadWithDimensions = (Component, options) => {
this.state = { width: 0, height: 0 };
this.handleWindowResize = this.handleWindowResize.bind(this);
this.isElementInViewport = this.isElementInViewport.bind(this);
this.setDimensions = throttle(this.setDimensions.bind(this), THROTTLE_WAIT_MS);
this.handleWindowResize = throttle(this.handleWindowResize.bind(this), THROTTLE_WAIT_MS);
this.isElementNearViewport = this.isElementNearViewport.bind(this);
this.setDimensions = this.setDimensions.bind(this);
}
componentDidMount() {
@ -106,8 +110,8 @@ export const lazyLoadWithDimensions = (Component, options) => {
window.addEventListener('orientationchange', this.handleWindowResize);
this.defaultRenderTimeout = window.setTimeout(() => {
if (this.isElementInViewport()) {
this.handleWindowResize();
if (this.isElementNearViewport(0)) {
this.setDimensions();
}
}, RENDER_WAIT_MS);
}
@ -120,7 +124,9 @@ export const lazyLoadWithDimensions = (Component, options) => {
}
handleWindowResize() {
this.setDimensions();
if (this.isElementNearViewport(NEAR_VIEWPORT_MARGIN)) {
this.setDimensions();
}
}
setDimensions() {
@ -130,15 +136,14 @@ export const lazyLoadWithDimensions = (Component, options) => {
});
}
isElementInViewport() {
isElementNearViewport(safetyBoundary) {
if (this.element) {
const rect = this.element.getBoundingClientRect();
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
(rect.top >= 0 && rect.top <= viewportHeight + safetyBoundary) ||
(rect.bottom >= -1 * safetyBoundary && rect.bottom <= viewportHeight)
);
}
return false;