Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i18n: format bytes with consistent fractional width #11489

Merged
merged 5 commits into from
Oct 3, 2020
Merged

i18n: format bytes with consistent fractional width #11489

merged 5 commits into from
Oct 3, 2020

Conversation

acutmore
Copy link
Contributor

Summary
This changes how numbers with the 'byte' itemType are formatted when viewed.

Previously 2.5 and 1 when formatted with a granularity of 0.1 would be shown as 2.5 KiB and 1 KiB. Now they would be formatted as 2.5 KiB and 1.0 KiB.

This consistency can make it easier for some people when comparing sizes in a column as the decimal places will be aligned.

Related Issues/PRs

Fixes #11422

return `${kbs}${NBSP2}KiB`;
}

/**
* @param {number} size
* @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correcting this little typo while I was in the area

if (granularity >= 1) {
return this._numberFormatter;
}
const numberOfFractionDigits = -Math.floor(Math.log10(granularity));
Copy link
Contributor Author

@acutmore acutmore Sep 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having just Math.log10 on its own might be sufficient, the added Math.floor allows for granularities like 0.2 to also work.

@acutmore
Copy link
Contributor Author

'smoke_2_ToT' failed when testing http://localhost:10200/oopif.html with

"The page loaded too slowly to finish within the time limit. Results may be incomplete."

Presuming this means there is a chance these changes have introduced a performance regression. Might be that creating lots of new Intl.NumberFormat is more expensive than I had pressured. One idea would be to cache them?

@brendankenny
Copy link
Member

That's almost certainly just a test flake, see #11341.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Just a few notes.

Honestly this PR makes me think this._numberFormatter shouldn't be saved at all, since all of these format*() functions also have a granularity param. But that can wait for a future PR :)

'/script3.js(www.notexample.com)24 KiB8.8 KiB',
'50 KiB0 KiB',
'60 KiB0 KiB',
'/script1.js(www.cdn.com)24.0 KiB8.8 KiB',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are probably existing cases in the report where we don't want the extra .0 (like where the audit has already rounded to the nearest integer), but hopefully that will encourage audits to use granularity when that's what they really need :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good point. I was also wondering whether to special case zero, keeping it as 0 KiB rather than 0.0 KiB.

_byteFormatterForGranularity(granularity) {
let numberOfFractionDigits = 0;
if (granularity < 1) {
// assumes granularities above 1 will not contain fractional parts, i.e. will never be 1.5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this an old comment? granularity > 1 will never get inside this conditional

Copy link
Contributor Author

@acutmore acutmore Sep 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I probably need to re-word/move this comment. The assumption is related to the if its inside of, only checking the fractional part of the granularity if it is below 1.
EDIT: I've moved the comment up out of the if in 930c176. Hoping that makes things a bit clearer.

Comment on lines 75 to 80
return new Intl.NumberFormat(this._numberDateLocale, {
maximumFractionDigits: numberOfFractionDigits,
minimumFractionDigits: numberOfFractionDigits,
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case some of the other formatting options get changed up in the constructor, we should use them here, too. I don't know why someone might change maximumSignificantDigits or something, but better to keep things robust :)

Something like

Suggested change
return new Intl.NumberFormat(this._numberDateLocale, {
maximumFractionDigits: numberOfFractionDigits,
minimumFractionDigits: numberOfFractionDigits,
});
return new Intl.NumberFormat(this._numberDateLocale, {
...this._numberDateLocale.resolvedOptions(),
maximumFractionDigits: numberOfFractionDigits,
minimumFractionDigits: numberOfFractionDigits,
});

should work correctly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, sorry, that should have been this._numberFormatter.resolvedOptions()

@@ -89,4 +89,31 @@ describe('util helpers', () => {
timestamp.includes('Apr 29, 2017')
);
});

describe('_byteFormatterForGranularity', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than testing the internal implementation, can you move these tests to using the external i18n.formatBytesToKiB (which is less likely to change in the future)? That would also allow exercising the rounding part, so e.g. granularity: 0.5 really would be tested as rounding to 0.5.

Copy link
Contributor Author

@acutmore acutmore Sep 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing! I'll push a change for this asap.
EDIT: pushed d44662d

@googlebot

This comment has been minimized.

@googlebot googlebot added cla: no and removed cla: yes labels Oct 3, 2020
@acutmore
Copy link
Contributor Author

acutmore commented Oct 3, 2020

rebased from lighthouseVersion 6.4.0 onto lighthouseVersion 6.4.1

@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

ℹ️ Googlers: Go here for more info.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great, thanks @acutmore!

@acutmore
Copy link
Contributor Author

acutmore commented Oct 3, 2020

thanks @brendankenny. Also as a first time contributor to Lighthouse just wanted to say project documentation was really good. All very clear about how to get setup, run the tests locally and contribute a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Always display decimal places in JS library size comparison
5 participants