Skip to content

Commit c65e5c8

Browse files
authored
Merge pull request #72 from open-amdocs/scrollable-performance-refactor
2 parents 54e5b13 + 0655ac7 commit c65e5c8

2 files changed

Lines changed: 40 additions & 22 deletions

File tree

src/components/Scrollable/Scrollable.jsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@ export default class Scrollable extends React.PureComponent {
113113
const nextEvent = this.event.next,
114114
prevEvent = this.event.prev,
115115
changed = nextEvent.scrollHeight !== prevEvent.scrollHeight ||
116-
nextEvent.scrollWidth !== prevEvent.scrollWidth ||
117-
nextEvent.top !== prevEvent.top ||
118-
nextEvent.left !== prevEvent.left;
116+
nextEvent.scrollWidth !== prevEvent.scrollWidth ||
117+
nextEvent.top !== prevEvent.top ||
118+
nextEvent.left !== prevEvent.left;
119119

120120
// Ensures that updates (which are a potentially expensive operation)
121121
// are only executed if the applicable scroll properties have changed
122122
if (changed) {
123-
const el = this.container.current.parentElement;
124123
this.props.onUpdate(nextEvent);
124+
const el = this.container.current.parentElement;
125125
const vRatio = nextEvent.clientHeight / nextEvent.scrollHeight;
126126
const hRatio = nextEvent.clientWidth / nextEvent.scrollWidth;
127127

@@ -132,14 +132,8 @@ export default class Scrollable extends React.PureComponent {
132132
el.style.setProperty('--scrollable-vertical-ratio', vRatio);
133133
el.style.setProperty('--scrollable-horizontal-ratio', hRatio);
134134

135-
if( this.props.cssVarsOnTracks ) {
136-
this.vTrack.current.style.setProperty('--scrollable-scroll-top', nextEvent.top);
137-
this.hTrack.current.style.setProperty('--scrollable-scroll-left', nextEvent.left);
138-
}
139-
else {
140-
el.style.setProperty('--scrollable-scroll-top', nextEvent.top);
141-
el.style.setProperty('--scrollable-scroll-left', nextEvent.left);
142-
}
135+
(this.props.cssVarsOnTracks ? this.vTrack.current : el).style.setProperty('--scrollable-scroll-top', nextEvent.top);
136+
(this.props.cssVarsOnTracks ? this.hTrack.current : el).style.setProperty('--scrollable-scroll-left', nextEvent.left);
143137
});
144138
}
145139

src/components/Scrollable/Scrollable.test.js

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import {mount} from 'enzyme';
33
import sinon from 'sinon';
44
import {noop} from 'utility/memory';
5-
import Scrollable from './Scrollable';
5+
import Scrollable from './';
66
import {normalizeScrollPosition} from './Scrollable.utils';
77
import {SCROLLING_CLASS_REMOVAL_DELAY} from './Scrollable.constants';
88

@@ -18,6 +18,19 @@ describe('<Scrollable/>', () => {
1818
expect(wrapper.find('VerticalScrollbar')).toHaveLength(1);
1919
expect(wrapper.find('HorizontalScrollbar')).toHaveLength(1);
2020
});
21+
22+
it('should render a Scrollbar with custom vertical & horizontal scrollbars', () => {
23+
const wrapper = mount(
24+
<Scrollable>
25+
<Scrollable.VerticalScrollbar><div className='vsb-child'></div></Scrollable.VerticalScrollbar>
26+
<Scrollable.HorizontalScrollbar><div className='hsb-child'></div></Scrollable.HorizontalScrollbar>
27+
</Scrollable>
28+
);
29+
expect(wrapper.find('.scrollbar')).toHaveLength(1);
30+
expect(wrapper.find('ResizeObserver')).toHaveLength(1);
31+
expect(wrapper.find('.vsb-child')).toHaveLength(1);
32+
expect(wrapper.find('.hsb-child')).toHaveLength(1);
33+
});
2134
});
2235

2336
describe('Life Cycle', () => {
@@ -34,14 +47,26 @@ describe('<Scrollable/>', () => {
3447
expect(s.getSnapshotBeforeUpdate()).toEqual(s.container.current);
3548
});
3649

37-
it('componentDidUpdate()', () => {
38-
const s = new Scrollable({scrollOnDOMChange: false});
39-
s.container = {current: {scrollTop: 0}};
40-
s.updateScrollbars = sinon.spy();
41-
s.componentDidUpdate(null, null, {scrollTop: 50, scrollLeft: 50});
42-
expect(s.container.current.scrollTop).toEqual(50);
43-
expect(s.container.current.scrollLeft).toEqual(50);
44-
expect(s.updateScrollbars.callCount).toEqual(1);
50+
describe('componentDidUpdate', () => {
51+
it('scrollOnDOMChange prop "true"', () => {
52+
const s = new Scrollable({scrollOnDOMChange: true});
53+
s.container = {current: {scrollTop: 0, scrollLeft: 0}};
54+
s.updateScrollbars = sinon.spy();
55+
s.componentDidUpdate(null, null, {scrollTop: 50, scrollLeft: 50});
56+
expect(s.container.current.scrollTop).toEqual(0);
57+
expect(s.container.current.scrollLeft).toEqual(0);
58+
expect(s.updateScrollbars.callCount).toEqual(1);
59+
});
60+
61+
it('scrollOnDOMChange prop "false"', () => {
62+
const s = new Scrollable({scrollOnDOMChange: false});
63+
s.container = {current: {scrollTop: 0}};
64+
s.updateScrollbars = sinon.spy();
65+
s.componentDidUpdate(null, null, {scrollTop: 50, scrollLeft: 50});
66+
expect(s.container.current.scrollTop).toEqual(50);
67+
expect(s.container.current.scrollLeft).toEqual(50);
68+
expect(s.updateScrollbars.callCount).toEqual(1);
69+
});
4570
});
4671
});
4772

@@ -162,7 +187,6 @@ describe('<Scrollable/>', () => {
162187
expect(global.window.requestAnimationFrame.callCount).toEqual(1);
163188
global.window.requestAnimationFrame.args[0][0]();
164189
expect(toggle.callCount).toEqual(2);
165-
166190
expect(containerSetProperty.callCount).toEqual(2);
167191
expect(hTrackSetProperty.callCount).toEqual(1);
168192
expect(vTrackSetProperty.callCount).toEqual(1);

0 commit comments

Comments
 (0)