Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Bug 1187878 - Cache Intl DateTime formatters for better performance
Browse files Browse the repository at this point in the history
  • Loading branch information
Zibi Braniecki committed Aug 4, 2015
1 parent ccafde9 commit 738910d
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 42 deletions.
3 changes: 0 additions & 3 deletions apps/sms/views/conversation/test/unit/conversation_test.js
Expand Up @@ -3273,9 +3273,6 @@ suite('conversation.js >', function() {
}

setup(function() {
this.sinon.stub(Utils.date.format, 'localeFormat', function() {
return 'date_stub';
});
this.sinon.stub(MessageManager, 'retrieveMMS', function() {
return {};
});
Expand Down
12 changes: 12 additions & 0 deletions apps/sms/views/shared/js/time_headers.js
Expand Up @@ -8,6 +8,8 @@
init: function th_init() {
onvisibilityChange();
document.addEventListener('visibilitychange', onvisibilityChange);
window.addEventListener('timeformatchange', ontimeFormatChange);
window.addEventListener('languagechange', onlanguageChange);
},
startScheduler: function th_startScheduler() {
var now = Date.now(),
Expand Down Expand Up @@ -77,5 +79,15 @@
}
}

function ontimeFormatChange() {
Utils.resetDateFormatters();
TimeHeaders.updateAll();
}

function onlanguageChange() {
Utils.resetDateFormatters();
TimeHeaders.updateAll();
}

exports.TimeHeaders = TimeHeaders;
}(this));
111 changes: 72 additions & 39 deletions apps/sms/views/shared/js/utils.js
Expand Up @@ -19,13 +19,47 @@
var Utils = {
date: {
shared: new Date(),
get format() {
// Remove the accessor
delete Utils.date.format;
// Late initialization allows us to safely mock the mozL10n object
// without creating race conditions or hard script dependencies
return (Utils.date.format = new navigator.mozL10n.DateTimeFormat());
}
formatters: {
'time': {
options: {
hour: 'numeric',
minute: 'numeric',
},
formatter: null
},
'full': {
options: {
month: '2-digit',
day: '2-digit',
year: 'numeric',
},
formatter: null
},
'full-wt': {
options: {
month: '2-digit',
day: '2-digit',
year: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
formatter: null
},
'day': {
options: {
weekday: 'long',
},
formatter: null
},
'day-wt': {
options: {
weekday: 'long',
hour: 'numeric',
minute: 'numeric',
},
formatter: null
},
},
},
escapeRegex: function ut_escapeRegex(str) {
if (typeof str !== 'string') {
Expand All @@ -35,26 +69,43 @@
},
getFormattedHour: function ut_getFormattedHour(time) {
this.date.shared.setTime(+time);
return this.date.shared.toLocaleString(navigator.languages, {
hour12: navigator.mozHour12,
hour: 'numeric',
minute: 'numeric',
});
return this._getFormatter('time', false).format(this.date.shared);
},
getDayDate: function re_getDayDate(time) {
this.date.shared.setTime(+time);
this.date.shared.setHours(0, 0, 0, 0);
return this.date.shared.getTime();
},
_getFormatter: function ut_getFormatter({options, withTime}) {
resetDateFormatters: function ut_resetDateFormatters() {
// remove cached formatters.
// It should happen on timeformatchange and languagechange
for (var type in this.date.formatters) {
this.date.formatters[type].formatter = null;
}
},
_getFormatter: function ut_getFormatter(type, withTime) {
if (withTime) {
options.hour12 = navigator.mozHour12;
options.hour = 'numeric';
options.minute = 'numeric';
type += '-wt';
}
return new Intl.DateTimeFormat(navigator.languages, options);

// Cache the formatter for better performance
if (!this.date.formatters[type].formatter) {
var options = Object.assign(
{},
this.date.formatters[type].options
);
if (options.hour) {
options.hour12 = navigator.mozHour12;
}
this.date.formatters[type].formatter = Intl.DateTimeFormat(
navigator.languages,
options
);
}
return this.date.formatters[type].formatter;
},
setHeaderDate: function ut_setHeaderDate({time, element, withTime}) {

var formatter;
var today = Utils.getDayDate(Date.now());
var otherDay = Utils.getDayDate(time);
Expand All @@ -68,14 +119,7 @@

if (dayDiff < 0) {
// future time
formatter = this._getFormatter({
options: {
month: '2-digit',
day: '2-digit',
year: 'numeric',
},
withTime: withTime
});
formatter = this._getFormatter('full', withTime);
element.removeAttribute('data-l10n-id');
element.textContent = formatter.format(this.date.shared);
return;
Expand All @@ -100,23 +144,12 @@
element.setAttribute('data-l10n-id', 'yesterday');
}
} else if (dayDiff < 6) {
formatter = this._getFormatter({
options: {
weekday: 'long'
},
withTime: withTime
});
// day
formatter = this._getFormatter('day', withTime);
element.removeAttribute('data-l10n-id');
element.textContent = formatter.format(this.date.shared);
} else {
formatter = Utils._getFormatter({
options: {
month: '2-digit',
day: '2-digit',
year: 'numeric',
},
withTime: withTime
});
formatter = this._getFormatter('full', withTime);
element.removeAttribute('data-l10n-id');
element.textContent = formatter.format(this.date.shared);
}
Expand Down
1 change: 1 addition & 0 deletions apps/sms/views/shared/test/unit/mock_utils.js
Expand Up @@ -11,6 +11,7 @@ var MockUtils = {
getDayDate: Utils.getDayDate,
setHeaderDate: Utils.setHeaderDate,
getFormattedHour: Utils.getFormattedHour,
_getFormatter: Utils._getFormatter,
// real code needed here to map types
typeFromMimeType: Utils.typeFromMimeType,
escapeRegex: Utils.escapeRegex,
Expand Down
1 change: 1 addition & 0 deletions apps/sms/views/shared/test/unit/utils_test.js
Expand Up @@ -70,6 +70,7 @@ suite('Utils', function() {
test('([String|Number|Date])', function() {
[true, false].forEach(function(isMozHour12) {
navigator.mozHour12 = isMozHour12;
Utils.resetDateFormatters();

var formatter = new Intl.DateTimeFormat(navigator.languages, {
hour12: isMozHour12,
Expand Down

0 comments on commit 738910d

Please sign in to comment.