Skip to content

Commit

Permalink
fix(ViewportProvider): allow to update cache for fallback once per
Browse files Browse the repository at this point in the history
second

It is actually possibe that the fallback needs to be accessed more than
once per session, e.g. when the listener count gets down to 0 and
increases afterwards again.
In this case the state should be recreated, but not for every component
that requests it.
The assumtion is, that this mostly happens on mount and the collector
should soon take over, therefore we define a limit of maximum one
request per second, to be up  to date but don't implement a performance
issue.

Fixes #10
  • Loading branch information
garthenweb committed Aug 20, 2019
1 parent 0235692 commit 1deba6f
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 7 deletions.
15 changes: 9 additions & 6 deletions lib/ViewportProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import ViewportCollector, {
getClientDimensions,
getClientScroll,
} from './ViewportCollector';
import { createPerformanceMarker } from './utils';
import { createPerformanceMarker, now } from './utils';

interface IProps {
experimentalSchedulerEnabled?: boolean;
Expand All @@ -23,26 +23,28 @@ interface IListener extends IViewportChangeOptions {
skippedIterations: number;
}

const getCurrentDefaultViewport = (() => {
const createFallbackViewportRequester = () => {
let defaultValue: IViewport;
let lastAccess = 0;
return (): IViewport => {
if (!defaultValue) {
if (!defaultValue || now() - lastAccess > 1000) {
defaultValue = {
scroll: getClientScroll(),
dimensions: getClientDimensions(),
};
lastAccess = now();
}
return defaultValue;
};
})();
};

export const ViewportContext = React.createContext({
removeViewportChangeListener: (handler: TViewportChangeHandler) => {},
addViewportChangeListener: (
handler: TViewportChangeHandler,
options: IViewportChangeOptions,
) => {},
getCurrentViewport: getCurrentDefaultViewport,
getCurrentViewport: createFallbackViewportRequester(),
hasRootProviderAsParent: false,
version: '__VERSION__',
});
Expand Down Expand Up @@ -197,12 +199,13 @@ export default class ViewportProvider extends React.PureComponent<
}

private collector = React.createRef<ViewportCollector>();
private getCurrentDefaultViewport = createFallbackViewportRequester();
private contextValue = {
addViewportChangeListener: this.addViewportChangeListener,
removeViewportChangeListener: this.removeViewportChangeListener,
getCurrentViewport: () => {
if (!this.collector.current) {
return getCurrentDefaultViewport();
return this.getCurrentDefaultViewport();
}
return this.collector.current.getPropsFromState();
},
Expand Down
2 changes: 1 addition & 1 deletion lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export const cancelAnimationFrame = ((): ((handle: number) => void) => {
return clearTimeout;
})();

const now =
export const now =
typeof performance !== 'undefined' && performance.now
? performance.now.bind(performance)
: Date.now;
Expand Down

0 comments on commit 1deba6f

Please sign in to comment.