Skip to content

Commit

Permalink
Sort the classes that appear in attribution selectors to reduce cardi…
Browse files Browse the repository at this point in the history
…nality (#518)

* Sort class names in getSelector()

* Remove debug comment

* Review feedback

* Review feedback 2

* Partially reverting last change

* Simplify code and add test case

---------

Co-authored-by: Philip Walton <[email protected]>
  • Loading branch information
tunetheweb and philipwalton authored Sep 27, 2024
1 parent be41ea5 commit ffa8ed5
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 15 deletions.
22 changes: 11 additions & 11 deletions src/lib/getSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@ const getName = (node: Node) => {
: name.toUpperCase().replace(/^#/, '');
};

export const getSelector = (node: Node | null | undefined, maxLen?: number) => {
const MAX_LEN = 100;

export const getSelector = (node: Node | null | undefined) => {
let sel = '';

try {
while (node && node.nodeType !== 9) {
while (node?.nodeType !== 9) {
const el: Element = node as Element;
const part = el.id
? '#' + el.id
: getName(el) +
(el.classList &&
el.classList.value &&
el.classList.value.trim() &&
el.classList.value.trim().length
? '.' + el.classList.value.trim().replace(/\s+/g, '.')
: '');
if (sel.length + part.length > (maxLen || 100) - 1) return sel || part;
: [getName(el), ...Array.from(el.classList).sort()].join('.');
if (sel.length + part.length > MAX_LEN - 1) {
return sel || part;
}
sel = sel ? part + '>' + sel : part;
if (el.id) break;
if (el.id) {
break;
}
node = el.parentNode;
}
} catch (err) {
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/onLCP-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ describe('onLCP()', async function () {
assertStandardReportsAreCorrect([lcp]);

assert(lcp.attribution.url.endsWith('/test/img/square.png?delay=500'));
assert.equal(lcp.attribution.element, 'html>body>main>p>img');
assert.equal(lcp.attribution.element, 'html>body>main>p>img.bar.foo');
assert.equal(
lcp.attribution.timeToFirstByte +
lcp.attribution.resourceLoadDelay +
Expand Down Expand Up @@ -515,7 +515,7 @@ describe('onLCP()', async function () {
assertStandardReportsAreCorrect([lcp]);

assert(lcp.attribution.url.endsWith('/test/img/square.png?delay=500'));
assert.equal(lcp.attribution.element, 'html>body>main>p>img');
assert.equal(lcp.attribution.element, 'html>body>main>p>img.bar.foo');

// Specifically check that resourceLoadDelay falls back to `startTime`.
assert.equal(
Expand Down Expand Up @@ -565,7 +565,7 @@ describe('onLCP()', async function () {

assert(lcp.attribution.url.endsWith('/test/img/square.png?delay=500'));
assert.equal(lcp.navigationType, 'prerender');
assert.equal(lcp.attribution.element, 'html>body>main>p>img');
assert.equal(lcp.attribution.element, 'html>body>main>p>img.bar.foo');

// Assert each individual LCP sub-part accounts for `activationStart`
assert.equal(
Expand Down
2 changes: 1 addition & 1 deletion test/views/lcp.njk
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
{% if not imgDelay %}
{% set imgDelay = 500 %}
{% endif %}
<img elementtiming="main-image" {% if imgHidden %}hidden{% endif %} src="/test/img/square.png?delay={{ imgDelay }}">
<img class="foo bar" elementtiming="main-image" {% if imgHidden %}hidden{% endif %} src="/test/img/square.png?delay={{ imgDelay }}">
</p>
<p>Text below the image</p>

Expand Down

0 comments on commit ffa8ed5

Please sign in to comment.