Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Add CSS variables custom metrics #181

Merged
merged 4 commits into from
Jul 30, 2020

Conversation

LeaVerou
Copy link
Member

@LeaVerou LeaVerou commented Jul 29, 2020

Details here: LeaVerou/css-almanac#1 (comment)

Please note that this is written assuming a recent version of Chrome. If WPT runs an older one, please let me know so I can make changes.

Progress on HTTPArchive/almanac.httparchive.org#898

@pmeenan
Copy link
Member

pmeenan commented Jul 29, 2020

@LeaVerou WPT auto-updates to the latest stable automatically and is running the current version.

@LeaVerou
Copy link
Member Author

@pmeenan Yup, I finally managed to run custom metrics on WPT and verified it is indeed running Chrome 84 :)

@rviscomi rviscomi self-assigned this Jul 29, 2020
@rviscomi rviscomi requested review from rviscomi and dooman87 July 29, 2020 16:41
@rviscomi
Copy link
Member

@LeaVerou are there any good test cases you could share from the WPT results? Here's one from Smashing Magazine, but I'm not sure if this exercises the code sufficiently: https://www.webpagetest.org/custom_metrics.php?test=200729_EE_9aad73ca91dfdb7136100742b2412302&run=1&cached=0

For example, in the computed array results, should we expect element and children to be empty? At a quick glance I never actually saw these populated in any items.

{
  "element": {},
  "children": [],
  "declarations": {
    "--bio-image-border-color": {
      "value": "#fff"
    },
    "--bio-image-border-radius": {
      "value": "11px"
    },
    "--bio-image-border-width": {
      "value": "5px"
    }
  }
}

Is there anyone you can recommend to review this from the CSS custom properties perspective? I'll give it a thorough review from the WPT/HA integration perspective. So far the results look reasonable.

One suggestion I have is to combine this with the css.js file created by @dooman87 in #175, once that's merged.

@rviscomi rviscomi assigned LeaVerou and dooman87 and unassigned rviscomi Jul 29, 2020
@LeaVerou
Copy link
Member Author

For example, in the computed array results, should we expect element and children to be empty? At a quick glance I never actually saw these populated in any items.

No, that is certainly not normal, I will investigate.

Is there anyone you can recommend to review this from the CSS custom properties perspective?

@tabatkins would be the perfect person for this, but not sure if he has the time to be involved.

One suggestion I have is to combine this with the css.js file

I thought we could keep that for smaller metrics, and keep the Sass and CSS vars ones in their own files, since they are fairly large-ish (200-300 loc). Would that be ok?

@rviscomi
Copy link
Member

I thought we could keep that for smaller metrics, and keep the Sass and CSS vars ones in their own files, since they are fairly large-ish (200-300 loc). Would that be ok?

SGTM.

Copy link
Member

@rviscomi rviscomi left a comment

Choose a reason for hiding this comment

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

LGTM modulo empty element feedback.

@LeaVerou
Copy link
Member Author

LeaVerou commented Jul 30, 2020

FWIW this seems to be a WPT issue, the code runs fine from a console import("https://leaverou.github.io/css-almanac/runtime/var-tree.js"). Investigating why this happens.

LGTM modulo empty element feedback.

It's not just the empty element, the empty children is far more concerning.

@LeaVerou
Copy link
Member Author

Alright, turns out that was actually an easy fix, I just wasn't using my own serialization function, so the replacer argument that removed empty arrays and serialized elements into nice tagName.class1.class2#id sequences wasn't running.
In terms of output, the largest tree I have seen by far is on my website, quite ironically (and predictably, I suppose), here it is: https://gist.github.com/LeaVerou/25854b1d91480c9b949893c608383574

@rviscomi
Copy link
Member

Tested your site on WPT: https://www.webpagetest.org/custom_metrics.php?test=200730_V9_a35832e21be04e79bee4559aa1bc0794&run=1&cached=0. The newly fixed children property does make the output really large and I see how deeply nested it can get. I think this may make the analysis more difficult.

For your queries that depend on the computed object, do you have a good sense for how you would go about extracting insights and aggregating them over the corpus? Would a flatter structure make analysis any easier in your opinion, or would that lose any granularity?

@LeaVerou
Copy link
Member Author

It’s not newly fixed, it’s just that the previous output included it when empty (and it is frequently empty). I did mention that the output can get large with overly liberal selectors using custom properties (a In my website’s case) but that this should be very rare in the wild. Preserving nesting is the whole point of building a dependency graph, otherwise we could just go on from the stylesheet info.
There is one potential optimization however. Notice that in the huge tree generated on my website there are many identical entries on the same nesting level. Those add nothing to the analysis, and bloat the output. Do you have any ideas on how I could compress/eliminate them?


if (ancestor) {
let o = map.get(ancestor);
o.children.push(obj)
Copy link
Member

Choose a reason for hiding this comment

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

Do you have any ideas on how I could compress/eliminate them?

First thing that comes to mind is serialize the obj, save it in a Set, and test to see if each new object already exists before appending to o.children.

Or check the children array itself:

if (!o.children.find(child => JSON.stringify(child) == JSON.stringify(obj)))

The object properties may not be serialized in the same order, so this may not be a very robust option.

Copy link
Member

Choose a reason for hiding this comment

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

@LeaVerou I'll merge this as-is to make sure that we get it into the sync tomorrow. If you're able to optimize this before the end of the month, feel free to file a PR and we'll try to fit it in.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for merging!

First thing that comes to mind is serialize the obj, save it in a Set, and test to see if each new object already exists before appending to o.children.

The structure is built recursively, so at the time of that push, obj is not necessarily in its final state. But I could do something along those lines after the tree is built.

@rviscomi rviscomi merged commit 21a8221 into HTTPArchive:master Jul 30, 2020
@tabatkins
Copy link

While I can't commit to anything large, I can do small reviews. I can't tell from this thread what I'm being asked to review, tho. A little help?

@LeaVerou
Copy link
Member Author

Thanks Tab!
Did you see this comment?
It has both the algorithm and sample data.

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

Successfully merging this pull request may close these issues.

5 participants