Skip to content

Commit

Permalink
Optimize toISODateString and toISOMonthString
Browse files Browse the repository at this point in the history
These functions get called repeatedly when computing modifiers, which
happens any time components like DayPickerRangeController receives
props.

By manually building this string instead of relying on moment's format
function, we can get better performance. In my profiling, this cuts the
time spent in DayPickerRangeController#componentWillReceiveProps from
~50ms to ~40ms.
  • Loading branch information
lencioni committed May 30, 2019
1 parent 888f650 commit 2d7fd47
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 7 deletions.
8 changes: 5 additions & 3 deletions src/utils/toISODateString.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import moment from 'moment';

import toMomentObject from './toMomentObject';

import { ISO_FORMAT } from '../constants';

export default function toISODateString(date, currentFormat) {
const dateObj = moment.isMoment(date) ? date : toMomentObject(date, currentFormat);
if (!dateObj) return null;

return dateObj.format(ISO_FORMAT);
// Template strings compiled in strict mode uses concat, which is slow. Since
// this code is in a hot path and we want it to be as fast as possible, we
// want to use old-fashioned +.
// eslint-disable-next-line prefer-template
return dateObj.year() + '-' + String(dateObj.month() + 1).padStart(2, '0') + '-' + String(dateObj.date()).padStart(2, '0');
}
8 changes: 5 additions & 3 deletions src/utils/toISOMonthString.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import moment from 'moment';

import toMomentObject from './toMomentObject';

import { ISO_MONTH_FORMAT } from '../constants';

export default function toISOMonthString(date, currentFormat) {
const dateObj = moment.isMoment(date) ? date : toMomentObject(date, currentFormat);
if (!dateObj) return null;

return dateObj.format(ISO_MONTH_FORMAT);
// Template strings compiled in strict mode uses concat, which is slow. Since
// this code is in a hot path and we want it to be as fast as possible, we
// want to use old-fashioned +.
// eslint-disable-next-line prefer-template
return dateObj.year() + '-' + String(dateObj.month() + 1).padStart(2, '0');
}
6 changes: 6 additions & 0 deletions test/utils/toISODateString_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ describe('toISODateString', () => {
expect(dateString).to.equal('1991-07-13');
});

it('matches moment format behavior', () => {
const testDate = moment('1991-07-13');
const dateString = toISODateString(testDate);
expect(dateString).to.equal(testDate.format(ISO_FORMAT));
});

it('converts iso date string to ISO date string', () => {
const testDate = moment('1991-07-13');
const dateString = toISODateString(testDate.format(ISO_FORMAT));
Expand Down
4 changes: 3 additions & 1 deletion test/utils/toISOMonthString_spec.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import moment from 'moment';
import { expect } from 'chai';

import { ISO_FORMAT, ISO_MONTH_FORMAT } from '../../src/constants';
import { ISO_FORMAT } from '../../src/constants';
import toISOMonthString from '../../src/utils/toISOMonthString';

const ISO_MONTH_FORMAT = 'YYYY-MM';

describe('#toISOMonthString', () => {
describe('arg is a moment object', () => {
it('returns month in ISO_MONTH_FORMAT format', () => {
Expand Down

0 comments on commit 2d7fd47

Please sign in to comment.