Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 1 | # UseCounter Wiki |
| 2 | |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 3 | UseCounter can measure the usage of HTML, CSS, and JavaScript (etc) features |
| 4 | across all channels and platforms in the wild. Feature usage is recorded per |
| 5 | page load and is anonymously aggregated. Note, measurements are only recorded |
| 6 | for HTTP/HTTPS pages. Usage on the new tab page, on data URLs or file URLs are |
| 7 | not. Usages in extensions is measured on a separate histogram. |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 8 | |
| 9 | UseCounter data can be biased against scenarios where user metrics analysis is |
| 10 | not enabled (e.g., enterprises). However, UseCounter data is essential for |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 11 | understanding adoption of [new and existing features](https://webstatus.dev/), [web compat decision making](https://www.chromium.org/blink/platform-predictability/compat-tools) |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 12 | and [the blink process for breaking changes](https://sites.google.com/a/chromium.org/dev/blink/removing-features), as it reflects the real Chrome usage with a wide fraction of coverage. |
| 13 | The results are publicly available on https://chromestatus.com/ and internally |
| 14 | (for Google employees) on [UMA dashboard](https://goto.google.com/uma-usecounter) |
| 15 | and [UKM dashboard](https://goto.google.com/ukm-usecounter) with more detailed |
| 16 | break-downs. |
| 17 | |
| 18 | |
| 19 | ## How to Add a UseCounter Feature |
| 20 | |
| 21 | UseCounter measures feature usage via UMA histogram and UKM. To add your |
| 22 | feature to UseCounter, simply: |
Wan-Teh Chang | a2185fc | 2021-02-04 22:38:20 | [diff] [blame] | 23 | + Add your feature to the |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 24 | [blink::mojom::WebDXFeature enum](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom) |
| 25 | or to the [blink::mojom::WebFeature enum](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom); |
| 26 | + Usage can be recorded via: |
| 27 | * \[[MeasureAs="WebDXFeature::\<enum value\>"]\] in the feature's IDL definition; Or |
| 28 | * \[[MeasureAs=\<WebFeature enum value\>]\] in the feature's IDL definition for WebFeature use counters; Or |
| 29 | * \[[Measure]\] in the feature's IDL definition for WebFeature use counters with an appropriately named use counter; Or |
Andrew Williams | 41ac63b1 | 2024-11-14 20:36:20 | [diff] [blame] | 30 | * `blink::UseCounter::CountWebDXFeature()` or `blink::UseCounter::Count()` for blink side features; Or |
| 31 | * `content::ContentBrowserClient::LogWeb[DX]FeatureForCurrentPage()` for browser side features. |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 32 | + Run [`update_use_counter_feature_enum.py`] to update the UMA mappings. |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 33 | |
| 34 | Example: |
| 35 | ```c++ |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 36 | enum WebDXFeature { |
| 37 | ... |
| 38 | kMyFeature = N, |
| 39 | ... |
| 40 | } |
| 41 | ``` |
| 42 | ``` |
| 43 | interface MyInterface { |
| 44 | ... |
| 45 | [MeasureAs="WebDXFeature::kMyFeature"] myIdlAttribute; |
| 46 | ... |
| 47 | } |
| 48 | ``` |
| 49 | OR |
| 50 | ```c++ |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 51 | enum WebFeature { |
| 52 | ... |
| 53 | kMyFeature = N, |
| 54 | ... |
| 55 | } |
| 56 | ``` |
| 57 | ``` |
| 58 | interface MyInterface { |
| 59 | ... |
| 60 | [MeasureAs=MyFeature] myIdlAttribute; |
| 61 | ... |
| 62 | } |
| 63 | ``` |
| 64 | OR |
| 65 | ```c++ |
| 66 | MyInterface::MyBlinkSideFunction() { |
| 67 | ... |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 68 | UseCounter::CountWebDXFeature(context, WebDXFeature::kMyFeature); |
| 69 | ... |
| 70 | } |
| 71 | ``` |
| 72 | OR |
| 73 | ```c++ |
| 74 | MyInterface::MyBlinkSideFunction() { |
| 75 | ... |
Wan-Teh Chang | a2185fc | 2021-02-04 22:38:20 | [diff] [blame] | 76 | UseCounter::Count(context, WebFeature::kMyFeature); |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 77 | ... |
| 78 | } |
| 79 | ``` |
| 80 | OR |
| 81 | ```c++ |
| 82 | MyBrowserSideFunction() { |
| 83 | ... |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 84 | GetContentClient()->browser()->LogWeb[DX]FeatureForCurrentPage( |
| 85 | render_frame_host, blink::mojom::Web[DX]Feature::kMyFeature); |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 86 | ... |
| 87 | } |
| 88 | ``` |
| 89 | |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 90 | All WebDXFeature use counters automatically get URL-keyed metrics collected for |
| 91 | them. But WebFeature and other types of counters do not collect URL-keyed |
| 92 | metrics by default. To opt your non-WebDXFeature feature use counter in to UKM |
| 93 | metrics collection, add your feature to |
Mason Freed | bef47320 | 2019-12-13 23:06:31 | [diff] [blame] | 94 | [UseCounterPageLoadMetricsObserver::GetAllowedUkmFeatures()](https://cs.chromium.org/chromium/src/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc) |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 95 | and get approval from the privacy/metrics owners. |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 96 | |
| 97 | You can quickly verify that your feature is added to UMA histograms and UKM by |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 98 | checking chrome://histograms/Blink.UseCounter.WebDXFeatures, |
| 99 | chrome://histograms/Blink.UseCounter.Features and chrome://ukm in your local |
| 100 | build. |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 101 | |
Andrew Williams | 41ac63b1 | 2024-11-14 20:36:20 | [diff] [blame] | 102 | To add a test for a use counter, there are several options: |
| 103 | + For use counters recorded from the renderer, |
| 104 | [internal WPTs](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/web_tests/wpt_internal/README.md) |
| 105 | expose the `internals.isUseCounted` and `internals.clearUseCounter` |
| 106 | functions for testing use counters recorded for a given document. |
| 107 | |
| 108 | + Chrome browser tests can verify that use counters were recorded by using a |
| 109 | `base::HistogramTester` to check whether the "Blink.UseCounter.Features" |
| 110 | histogram was emitted to for the bucket corresponding to the new WebFeature. |
| 111 | If the use counter is recorded from the renderer, |
| 112 | `content::FetchHistogramsFromChildProcesses()` can be used to make this |
| 113 | use counter activity visible to the browser process. |
| 114 | |
| 115 | + For use counters recorded from the browser process (e.g. by calling |
| 116 | `GetContentClient()->browser()->LogWebFeatureForCurrentPage()`), a content |
| 117 | browser test can be used by creating a subclass of |
| 118 | `ContentBrowserTestContentBrowserClient` that implements |
| 119 | `LogWebFeatureForCurrentPage`, creating an instance of it in |
| 120 | `SetUpOnMainThread`, and checking whether the instance's |
| 121 | `LogWebFeatureForCurrentPage` is called. One way to implement this is to |
| 122 | have `LogWebFeatureForCurrentPage` be defined as a `MOCK_METHOD` and then |
| 123 | use `EXPECT_CALL` to ensure that the method is called as expected with |
| 124 | the new WebFeature value. Note that the |
| 125 | `ContentBrowserTestContentBrowserClient` instance should be destroyed in |
| 126 | `TearDownOnMainThread`. |
| 127 | |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 128 | ## Analyze UseCounter Histogram Data |
| 129 | |
| 130 | ### Public Data on https://chromestatus.com |
| 131 | |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 132 | Usage of JavaScript and HTML features is publicly available |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 133 | [here](https://chromestatus.com/metrics/feature/popularity). |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 134 | Usage of CSS properties is publicly available |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 135 | [here](https://chromestatus.com/metrics/css/popularity). |
| 136 | |
| 137 | The data reflects features' daily usage (count of feature hits / count of total |
| 138 | page visits): |
| 139 | + On all platforms: Android, Windows, Mac, ChromeOS, and Linux. |
| 140 | + On "official" channels: stable, beta, and dev. |
| 141 | + For the most dominant milestone. |
| 142 | |
| 143 | |
Robert Kaplow | b3f2df2 | 2023-09-21 20:52:37 | [diff] [blame] | 144 | ### Internal UMA tools |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 145 | |
Robert Kaplow | b3f2df2 | 2023-09-21 20:52:37 | [diff] [blame] | 146 | See (https://goto.google.com/uma-usecounter) for internal tooling. |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 147 | |
Robert Kaplow | b3f2df2 | 2023-09-21 20:52:37 | [diff] [blame] | 148 | Some metrics of interest: |
Johnny Stenback | fc32f1c0 | 2024-08-03 00:15:46 | [diff] [blame] | 149 | + "Blink.UseCounter.WebDXFeatures" for web platform features as defined in the |
| 150 | [web platform dx repository](https://github.com/web-platform-dx/web-features/). |
| 151 | + "Blink.UseCounter.Features" for generic Web Platform use counters (some of which are mapped to WebDXFeature use counters). |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 152 | + "Blink.UseCounter.CSSProperties" for CSS properties. |
| 153 | + "Blink.UseCounter.AnimatedCSSProperties" for animated CSS properties. |
| 154 | + "Blink.UseCounter.Extensions.Features" for HTML and JacaScript features on |
| 155 | extensions. |
| 156 | |
Luna Lu | d1e8057 | 2019-06-05 20:58:16 | [diff] [blame] | 157 | ### UseCounter Feature in HTTP Archive |
| 158 | |
| 159 | HTTP Archive crawls the top 10K sites on the web and records everything from |
| 160 | request and response headers. The data is available on Google BigQuery. |
| 161 | |
| 162 | You can find pages that trigger a particular UseCounter using the following |
| 163 | script: |
| 164 | |
| 165 | ```sql |
| 166 | SELECT |
| 167 | DATE(yyyymmdd) AS date, |
| 168 | client AS platform, |
| 169 | num_url AS url_count, |
| 170 | pct_urls AS urls_percentile, |
| 171 | sample_urls AS url |
| 172 | FROM [httparchive:blink_features.usage] |
| 173 | WHERE feature = 'MyFeature' |
| 174 | ORDER BY url_percentile DESC |
| 175 | ``` |
| 176 | OR |
| 177 | |
| 178 | ```sql |
| 179 | SELECT |
| 180 | url |
| 181 | FROM [httparchive:pages.yyyy_mm_dd_mobile] |
| 182 | WHERE |
| 183 | JSON_EXTRACT(payload, '$._blinkFeatureFirstUsed.Features.MyFeature') IS NOT |
| 184 | NULL |
| 185 | LIMIT 500 |
| 186 | ``` |
| 187 | |
| 188 | You can also find pages that trigger a particular CSS property (during parsing): |
| 189 | |
| 190 | ```sql |
| 191 | SELECT |
| 192 | url |
| 193 | FROM [httparchive:pages.yyyy_mm_dd_mobile] |
| 194 | WHERE |
| 195 | JSON_EXTRACT(payload, '$._blinkFeatureFirstUsed.CSSFeatures.MyCSSProperty') |
| 196 | IS NOT NULL |
| 197 | LIMIT 500 |
| 198 | ``` |
| 199 | |
| 200 | To find pages that trigger a UseCounter and sort by page rank: |
| 201 | |
| 202 | ```sql |
| 203 | SELECT |
| 204 | IFNULL(runs.rank, 1000000) AS rank, |
| 205 | har.url AS url, |
| 206 | FROM [httparchive:latest.pages_desktop] AS har |
| 207 | LEFT JOIN [httparchive:runs.latest_pages] AS runs |
| 208 | ON har.url = runs.url |
| 209 | WHERE |
| 210 | JSON_EXTRACT(payload, '$._blinkFeatureFirstUsed.Features.MyFeature') IS NOT |
| 211 | NULL |
| 212 | ORDER BY rank; |
| 213 | ``` |
| 214 | |
| 215 | |
| 216 | ### UMA Usage on Fraction of Users |
| 217 | You may also see the fraction of users that trigger your feature at lease once a |
| 218 | day on [UMA Usage dashboard](https://goto.google.com/uma-usecounter-peruser). |
| 219 | |
| 220 | |
| 221 | ## Analyze UseCounter UKM Data |
| 222 | For privacy concerns, UKM data is available for Google employees only. |
Sun Yueru | 4637eec | 2023-06-16 16:02:01 | [diff] [blame] | 223 | Please see [this internal |
| 224 | documentation](https://goto.google.com/ukm-blink-usecounter) for details. |