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

Query API for alfa-dom #1413

Merged
merged 18 commits into from
May 25, 2023
Merged

Query API for alfa-dom #1413

merged 18 commits into from
May 25, 2023

Conversation

rcj-siteimprove
Copy link
Contributor

@rcj-siteimprove rcj-siteimprove commented May 4, 2023

Part of #1037

First attempt at creating a query API for querying the DOM. For now, two common queries has been extracted and put into the new Query namespace in alfa-dom and the results are now cached which should give a slight performance improvement.

The function will populate and cache a map from id to element on first invocation
@rcj-siteimprove rcj-siteimprove self-assigned this May 4, 2023
@rcj-siteimprove rcj-siteimprove added the major Backwards-incompatible change that touches public API label May 4, 2023
@rcj-siteimprove rcj-siteimprove changed the title First stab at Query API for alfa-dom Query API for alfa-dom May 8, 2023
@rcj-siteimprove rcj-siteimprove marked this pull request as ready for review May 10, 2023 09:51
@rcj-siteimprove rcj-siteimprove requested review from a team and Jym77 May 10, 2023 09:51
Copy link
Contributor

@Jym77 Jym77 left a comment

Choose a reason for hiding this comment

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

Great work. Some small polish.

packages/alfa-aria/src/node.ts Outdated Show resolved Hide resolved
packages/alfa-dom/src/node/document.ts Outdated Show resolved Hide resolved
packages/alfa-dom/src/node/document.ts Show resolved Hide resolved
packages/alfa-dom/src/node/query/element-id-map.ts Outdated Show resolved Hide resolved
packages/alfa-dom/src/node/query/index.ts Outdated Show resolved Hide resolved
packages/alfa-dom/src/node/query/index.ts Outdated Show resolved Hide resolved
@rcj-siteimprove rcj-siteimprove requested a review from Jym77 May 22, 2023 12:35
Copy link
Contributor

@Jym77 Jym77 left a comment

Choose a reason for hiding this comment

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

We should also use the new cached map for aria-labelledby resolution at

// Since there are a lot of elements in the document, but very few in the
// aria-labelledby, it is more efficient to grab them in DOM order (in a
// single traversal) and then sort by tokens order rather than grab the ids
// one by one in the correct order.
const references = root
.elementDescendants()
.filter(hasId(equals(...ids)))
.sortWith((a, b) =>
Comparable.compareNumber(
// the previous filter ensure that the id exists
ids.indexOf(a.id.getUnsafe()),
ids.indexOf(b.id.getUnsafe())
)
);
(and it should also simplify that code by not needing to sort since we'll poke the map in the correct order)

packages/alfa-aria/src/node.ts Outdated Show resolved Hide resolved
packages/alfa-aria/src/node.ts Outdated Show resolved Hide resolved
@rcj-siteimprove
Copy link
Contributor Author

We should also use the new cached map for aria-labelledby resolution at

// Since there are a lot of elements in the document, but very few in the
// aria-labelledby, it is more efficient to grab them in DOM order (in a
// single traversal) and then sort by tokens order rather than grab the ids
// one by one in the correct order.
const references = root
.elementDescendants()
.filter(hasId(equals(...ids)))
.sortWith((a, b) =>
Comparable.compareNumber(
// the previous filter ensure that the id exists
ids.indexOf(a.id.getUnsafe()),
ids.indexOf(b.id.getUnsafe())
)
);

(and it should also simplify that code by not needing to sort since we'll poke the map in the correct order)

There's also a follow up task on #1037 on getting rid of all usages of .elementDescendants() so it would be picked up there too. Should we keep it as part of that follow up task?

@rcj-siteimprove rcj-siteimprove requested a review from Jym77 May 23, 2023 12:07
@Jym77
Copy link
Contributor

Jym77 commented May 23, 2023

We should also use the new cached map for aria-labelledby resolution at

// Since there are a lot of elements in the document, but very few in the
// aria-labelledby, it is more efficient to grab them in DOM order (in a
// single traversal) and then sort by tokens order rather than grab the ids
// one by one in the correct order.
const references = root
.elementDescendants()
.filter(hasId(equals(...ids)))
.sortWith((a, b) =>
Comparable.compareNumber(
// the previous filter ensure that the id exists
ids.indexOf(a.id.getUnsafe()),
ids.indexOf(b.id.getUnsafe())
)
);

(and it should also simplify that code by not needing to sort since we'll poke the map in the correct order)

There's also a follow up task on #1037 on getting rid of all usages of .elementDescendants() so it would be picked up there too. Should we keep it as part of that follow up task?

That's a bit different (I think).
The aria-labelledby computation is actually doing a convoluted getElementIdMap, not just a elementDescendants. It is a bit hidden because it is already a bit optimised. But given that this PR is about introducing getElementIdMap (the renaming of elementDescendants is a side effect), I feel this fits here 🤔

The aria-labelledby computation is essentially doing:
document => element descendants => filter by id being one of the wanted one => sort by order of id in the attribute.
The third step is essentially a multiple getElementById and should benefit from the map:
document => idMap => pick the wanted ones, in order.

So, I feel it's more about using the new map that replacing the elementDescendants call (i.e. lust using Query.elementDescendant wouldn't be enough).

Jym77
Jym77 previously approved these changes May 23, 2023
@rcj-siteimprove rcj-siteimprove requested a review from Jym77 May 25, 2023 13:05
@rcj-siteimprove rcj-siteimprove added this pull request to the merge queue May 25, 2023
Merged via the queue into main with commit 8d10413 May 25, 2023
@rcj-siteimprove rcj-siteimprove deleted the cache-elements-by-id branch May 25, 2023 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
major Backwards-incompatible change that touches public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants