mdn / browser-compat-data

This repository contains compatibility data for Web technologies as displayed on MDN
https://developer.mozilla.org
Creative Commons Zero v1.0 Universal
4.91k stars 1.98k forks source link

Research: Schema comparison caniuse and BCD #4051

Closed Elchi3 closed 4 years ago

Elchi3 commented 5 years ago

We would like to do some research on how the data and schema of caniuse compares to the data of BCD.

For example, a feature in caniuse and a feature in BCD: https://github.com/Fyrd/caniuse/blob/master/features-json/css-any-link.json https://github.com/mdn/browser-compat-data/blob/master/css/selectors/any-link.json

Caniuse right now has 516 features in https://github.com/Fyrd/caniuse/tree/master/features-json. They are of different granularity: sometimes it is a single feature like the any-link selector, sometimes it is a whole feature-set like "CSS Grid". In BCD, we have a hierarchical structure which attempts to always go down to the individual features, because that's what makes our data useful for re-use for the machines in e.g. in static code analysis, or for displaying in IDEs and reference docs, etc.

A while ago, I started looking into the coverage part of caniuse and started to map features to BCD entries, to see how there is much overlap or not. There actually is some and so the following table might be helpful for doing the schema / data comparison and research (it is not complete, but a research probe). These are 200 features that map (out of the 516 in total. Again, this probe isn't complete, I bet that 80% or so of caniuse would probably at least map to BCD features).

caniuse BCD
abortcontroller.json api.AbortController
accelerometer.json api.Accelerometer, api.GravitySensor
addeventlistener.json api.EventTarget.addEventListener
alternate-stylesheet.json html.elements.link.rel.alternate_stylesheet
ambient-light.json api.AmbientLightSensor
array-find-index.json javascript.builtins.Array.findIndex
array-find.json javascript.builtins.Array.find
array-includes.json javascript.builtins.Array.includes
arrow-functions.json javascript.functions.arrow_functions
async-clipboard.json api.Clipboard
async-functions.json javascript.statements.async_function
async-iterations-and-generators.json javascript.statements.for_of.async_iterators
atob-btoa.json api.WindowOrWorkerGlobalScope.atop, api.WindowOrWorkerGlobalScope.btoa
audio-api.json api.AudioContext
audio.json html.elements.audio
audiotracks.json api.AudioTrack
background-attachment.json css.properties.background-attachment
background-clip-text.json css.properties.background-clip.text
background-img-opts.json css.properties.background-clip
background-position-x-y.json css.properties.background-position-x
background-repeat-round-space.json css.properties.background-repeat.round_space
background-sync.json api.SyncManager
battery-status.json api.BatteryManager
beacon.json api.Navigator.sendBeacon
bigint.json javascript.builtins.BigInt
blobbuilder.json api.BlobBuilder, api.Blob
bloburls.json api.URL.createObjectURL
border-image.json css.properties.border-image
border-radius.json css.properties.border-radius
broadcastchannel.json api.BroadCastChannel
brotli.json http.headers.Content-Encoding.br
calc.json css.types.calc
canvas-text.json api.CanvasRenderingContext2D.fillText
canvas.json html.element.canvas
ch-unit.json css.types.length.ch
channel-messaging.json api.MessageChannel
childnode-remove.json api.ChildNode.remove
classlist.json api.Element.classList
clear-site-data-header.json http.headers.Clear-Site-Data
client-hints-dpr-width-viewport.json http.headers.Accept-CH (etc)
clipboard.json api.ClipboardEvent
comparedocumentposition.json api.Node.compareDocumentPosition
console-basic.json api.Console
console-time.json api.Console.time
const.json javascript.statements.const
constraint-validation.json api.HTMLSelectElement.setCustomValidity etc
contenteditable.json api.HTMLElement.contentEditable
contentsecuritypolicy.json http.headers.Content-Security-Policy
contentsecuritypolicy2.json http.headers.Content-Security-Policy
cors.json http.headers.Access-Control-Allow-Origin
createimagebitmap.json api.WindowOrWorkerGlobalScope.createImageBitmap
credential-management.json api.Credential etc
cryptography.json api.Crypto
css-all.json css.properties.all
css-animation.json css.properties.animation
css-any-link.json css.selectors.any-link
css-appearance.json css.properties.appearance
css-at-counter-style.json css.at-rules.counter-style
css-backdrop-filter.json css.properties.backdrop-filter
css-background-offsets.json css.properties.background-position.4_value_syntax
css-backgroundblendmode.json css.properties.background-blend-mode
css-boxdecorationbreak.json css.properties.box-decoration-break
css-boxshadow.json css.properties.box-shadow
css-caret-color.json css.properties.caret-color
css-case-insensitive.json css.selectors.attribute.case_sensitive_modifier
css-clip-path.json css.properties.clip-path
css-color-adjust.json css.properties,-webkit-print-color-adjust
css-conic-gradients.json css.types.image.gradients.conic-gradient
css-counters.json css.properties.counter-reset (etc)
css-crisp-edges.json css.properties.image-rendering
css-default-pseudo.json css.selectors.default
css-descendant-gtgt.json css.selectors.descendant
css-dir-pseudo.json css.selectors.dir
css-display-contents.json css.properties.display.content
css-element-function.json css.types.image.element
css-env-function.json css.properties.custom-property.env
css-featurequeries.json css.at-rules.supports
css-first-letter.json css.selectors.first-letter
css-first-line.json css.selectors.first-line
css-fixed.json css.properties.position.fixed
css-focus-visible.json css.selectors.-moz-focusring
css-focus-within.json css.selectors.focus-within
css-font-rendering-controls.json css.at-rules.font-face.font-display
css-font-stretch.json css.properties.font-stretch
css-gencontent.json css.selectors.before, css.selectors.after
css-gradients.json css.types.image.gradients
css-grid.json css.properties.grid
css-hanging-punctuation.json css.properties.hanging-punctuation
css-has.json css.selectors.has
css-hyphens.json css.properties.hyphens
css-image-orientation.json css.properties.image-orientation
css-in-out-of-range.json css.selectors.out-of-range
css-indeterminate-pseudo.json css.selectors.indeterminate
css-initial-letter.json css.properties.initial-letter
css-initial-value.json css.types.global_keywords.initial
css-letter-spacing.json css.properties.letter-spacing
css-logical-props.json css.properties.margin-inline-start
css-marker-pseudo.json css.selectors.marker
css-masks.json css.properties.mask
css-matches-pseudo.json css.selectors.any
css-motion-paths.json css.properties.offset-path
css-namespaces.json css.at-rules.namespace
css-not-sel-list.json css.selectors.not.selector_list
css-nth-child-of.json css.selectors.nth-child.of_syntax
css-opacity.json css.properties.opacity
css-optional-pseudo.json css.selectors.optional
css-placeholder-shown.json css.selectors.placeholder-shown
css-read-only-write.json css.selectors.read-only
css-rebeccapurple.json css.properties.color.rebeccapurple
css-resize.json css.properties.resize
css-scroll-behavior.json css.properties.scroll-behavior
css-selection.json css.selectors.selection
css-snappoints.json css.properties.scroll-snap-type
css-sticky.json css.properties.position.sticky
css-table.json css.properties.display.table_value
css-text-align-last.json css.properties.text-align.last
css-text-indent.json css.properties.text-indent
css-text-justify.json css.properties.text-justify
css-text-orientation.json css.properties.text-orientation
css-textshadow.json css.properties.text-shadow
css-touch-action.json css.properties.touch-action
css-transitions.json css.properties.transitions
css-unicode-bidi.json css.properties.unicode-bidi
css-variables.json css.properties.custom-property
css-widows-orphans.json css.properties.widows
css-writing-mode.json css.properties.writing-mode
css-zoom.json css.properties.zoom
css3-boxsizing.json css.properties.box-sizing
css3-colors.json css.properties.color
css3-cursors-grab.json css.properties.cursor.grab
css3-cursors-newer.json css.properties.cursor.zoom
css3-cursors.json css.properties.cursor
css3-tabsize.json css.properties.tab-size
currentcolor.json css.properties.color.currentcolor
datalist.json html.elements.datalist
datauri.json http.data-url
details.json html.elements.details
es6-class.json javascript.classes
es6-generators.json javascript.statements.generator_function
es6-number.json javascript.builtins.Number.EPSILON (and more)
es6-string-includes.json javascript.builtins.String.includes
flexbox.json css.properties.flex
font-family-system-ui.json css.properties.font-family.system-ui
font-feature.json css.properties.font-feature-settings
font-kerning.json css.properties.font-kerning
font-size-adjust.json css.properties.font-size-adjust
font-unicode-range.json css.at-rules.font-face.unicode-range"
font-variant-alternates.json css.properties.font-variant-alternates
font-variant-east-asian.json css.properties.font-variant-east-asian
fontface.json css.at-rules.font-face
gamepad.json api.Gamepad
link-rel-dns-prefetch.json html.elements.link.rel.dns-prefetch
link-rel-preconnect.json html.elements.link.rel.preconnect
link-rel-prefetch.json html.elements.link.rel.prefetch
link-rel-preload.json html.elements.link.rel.preload
link-rel-prerender.json html.elements.link.rel.dns-prerender
localecompare.json javascript.builtins.String.localeCompare
object-fit.json css.properties.object-fit
object-observe.json javascript.builtins.Object.observe
object-values.json javascript.builtins.Object.values
picture.json html.elements.picture
ping.json html.elements.a.ping
pointer-events.json css.properties.pointer-events
progress.json html.elements.progress
promises.json javascript.builtins.Promise
proxy.json javascript.builtins.Proxy
publickeypinning.json http.headers.Public-Key-Pins
referrer-policy.json http.headers.Referrer-Policy
rel-noopener.json html.elements.link.rel.noopener
rel-noreferrer.json html.elements.link.rel.noreferrer
rest-parameters.json javascript.functions.rest_parameters
ruby.json html.elements.ruby
run-in.json css.properties.display.run-in
same-site-cookie-attribute.json http.headers.Set-Cookie.SameSite
script-async.json html.elements.script.async
script-defer.json html.elements.script.defer
srcset.json html.elements.img.srcset
stricttransportsecurity.json http.headers.Strict-Transport-Security
style-scoped.json html.elements.style.scoped
template-literals.json javascript.grammar.template_literals
template.json html.elements.template
text-decoration.json css.properties.text-decoration-style
text-emphasis.json css.properties.text-emphasis
text-overflow.json css.properties.text-overflow
text-size-adjust.json css.properties.text-size-adjust
transforms2d.json css.properties.transform
transforms3d.json css.properties.transform.3d
typedarrays.json javascript.builtins.Int8Array
upgradeinsecurerequests.json http.headers.csp.upgrade-insecure-requests
variable-fonts.json css.properties.font-variation-settings
video.json html.elements.video
wasm.json javascript.builtins.WebAssembly
wbr-element.json html.elements.wbr
webgl.json api.WebGLRenderingContext
webgl2.json api.WebGL2RenderingContext
webvr.json api.VRDisplay
will-change.json css.properties.will-change
word-break.json css.properties.word-break
wordwrap.json css.properties.overflow-wrap
x-frame-options.json http.headers.X-Fame-Options

The last BCD release had 11380 total features, so BCD is much more granular and probably covers a lot more of the web platform (although our data is not fully complete, see the year goal for 2019). For that reason, caniuse might be interested in importing or using the BCD data side by side with their own data. So, we need to look into how the two data schemas compare and if it is possible, for example, to compute a caniuse data entry from BCD data.

So, this task is mostly about writing up a schema comparison and making a plan for next steps.

Elchi3 commented 5 years ago

Browsers in BCD and in caniuse

Browsers that map (in bold: tier 1 browsers):

caniuse BCD
ie ie
edge edge
firefox firefox
chrome chrome
safari safari
opera opera
ios_saf safari_ios
android webview_android
op_mobile opera_android
and_chrome chrome_android
and_ff firefox_android
and_uc uc_android, uc_chinese_android
samsung samsunginternet_android
and_qq qq_android

Browsers that don't map:

caniuse BCD
op_mini ---
bb ---
ie_mob ---
baidu ---
kaios ---
--- nodejs

(updated to remove edge_mobile, which will soon be gone from BCD)

Elchi3 commented 5 years ago

Browser version differences

For browsers that are in both, BCD and in caniuse:

caniuse BCD
ie: 5.5, 6, 7, 8, 9, 10, 11 ie: 1, 2, 4, 5, 5.5, 6, 7, 8, 9, 10, 11
edge: 12, 13, 14, 15, 16, 17, 18, 75 edge: 12, 13, 14, 15, 16, 17, 18
firefox: 2-68 firefox: 1-71
chrome: 4-77 chrome: 1-77
safari: 3.1, 3.2, 4, 5, 5.1, 6, 6.1, 7, 7.1, 8, 9, 9.1, 10, 10.1, 11, 11.1, 12, 12.1, TP safari: 1, 1.1, 1.2, 1.3, 2, 3, 4, 4.1, 5, 5.1, 6, 6.1, 7, 8, 9, 9.1, 10, 10.1, 11, 11.1, 12, 12.1,
opera: 9, 9.5-9.6, 10.0-10.1, 10.5, 10.6, 11, 11.1, 11.5, 11.6, 12, 12.1, 15-58 opera: 2, 3, 3.5, 3.6, 4, 5, 5.1, 6, 7, 7.1, 7.2, 7.5, 8, 8.5, 9, 9.1, 9.2, 9.5, 9.6, 10, 10.1, 10.5, 10.6, 11, 11.1, 11.5, 11.6, 12, 12.1, 15-62
ios_saf: 3.2, 4.0-4.1, 4.2-4.3, 5.0-5.1, 6.0-6.1, 7.0-7.1, 8, 8.1-8.4, 9.0-9.2, 9.3, 10.0-10.2, 10.3, 11.0-11.2, 11.3-11.4, 12.0-12.1, 12.2 (a few versions are treated as one) safari_ios: 1, 2, 3, 3.1, 3.2, 4, 4.2, 4.3, 5, 5.1, 6, 6.1, 7, 7.1, 8, 8.1, 8.4, 9, 9.1, 9.2, 9.3, 10, 10.1, 10.2, 10.3, 11, 11.1, 11.3, 12, 12.2
android: 2.1, 2.2, 2.3, 3, 4, 4.1, 4.2-4.3, 4.4, 4.4.3-4.4.4, 67 webview_android: 1, 1.1, 1.5, 1.6, 2, 2.2, 2.3, 3, 4, 4.1, 4.2, 4.4, 4.4.3, 37-76
op_mobile: 10, 11, 11.1, 11.5, 12, 12.1, 46 opera_android: 10.1, 11, 11.1, 11.5, 12, 12.1, 14, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
and_chrome: 74 chrome_android: 18, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76
and_ff: 66 firefox_android: 4, 5, 6, 7, 8, 9, 10, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68
samsung: 4, 5.0-5.4, 6.2-6.4, 7.2-7.4, 8.2, 9.2 samsunginternet_android: 1.0, 1.5, 1.6, 2.0, 2.1, 3.0, 3.2, 4.0, 4.2, 5.0, 5.2, 5.4, 6.0, 6.2, 6.4, 7.0, 7.2, 7.4, 8.0, 8.2, 9.0, 9.2
and_uc: 11.8 uc_android, uc_chinese_android: (entirely different but unmaintained)
and_qq: 1.2 qq_android: 8, 7.2.1, 7.3.1, 7.5, 7.5.1, 7.6.1, 7.8, 8.1.3, 8.2

Observations:

Elchi3 commented 5 years ago

Comparing core compat data structures

For readability, I've taken IE to illustrate this, but note that caniuse always lists every version number for a browser and adds a support modifier like "u", "n", "a", etc.

Indicating no support

Caniuse:

"ie":{
  "5.5":"n",
  "6":"n",
  "7":"n",
  "8":"n",
  "9":"n",
  "10":"n",
  "11":"n"
},

BCD

"ie": {
  "version_added": false
},

Indicating simple support

Caniuse:

 "ie":{
   "5.5":"n",
   "6":"n",
   "7":"n",
   "8":"n",
   "9":"y",
   "10":"y",
   "11":"y"
},

BCD:

"ie": {
  "version_added": "9"
},

Indicating unknown support

Caniuse:

 "ie":{
   "5.5":"u",
   "6":"u",
   "7":"u",
   "8":"u",
   "9":"u",
   "10":"u",
   "11":"u"
},

BCD:

"ie": {
  "version_added": null
},

Indicating support behind a flag and later enabled by default

Caniuse:

 "ie":{
   "5.5":"n",
   "6":"n",
   "7":"n",
   "8":"n",
   "9":"n d #1",
   "10":"n d #1",
   "11":"y"
},
 "notes_by_num":{
  "1":"Can be enabled in IE by setting the about:config preference foo.bar.enabled to true",
}

BCD:

"ie": [
  {
    "version_added": "11"
  },
  {
    "version_added": "9",
    "flags": [
      {
        "name": "foo.bar.enabled",
        "type": "preference",
        "value_to_set": "true"
      }
    ]
  }
],

Indicating partial support

Caniuse:

 "ie":{
   "5.5":"n",
   "6":"n",
   "7":"n",
   "8":"n",
   "9":"a #1",
   "10":"a #1",
   "11":"y"
},
 "notes_by_num":{
  "1":"Partial support refers to foo bar.",
}

BCD:

"ie": [
  {
    "version_added": "11"
  },
  {
    "version_added": "9",
    "partial_support": true,
    "notes": "Does not support foo bar."
  }
],

Indicating prefixed support

Caniuse:

 "ie":{
   "5.5":"n",
   "6":"n",
   "7":"n",
   "8":"n",
   "9":"y x",
   "10":"y x",
   "11":"y"
}

BCD:

"ie": [
  {
    "version_added": "11"
  },
  {
    "version_added": "9",
    "prefix": "-ms"
  }
],

Indicating support via polyfill

Caniuse:

 "ie":{
   "5.5":"n",
   "6":"n",
   "7":"n",
   "8":"n",
   "9":"p",
   "10":"p",
   "11":"p"
}

BCD has no data structure for this. We often fall back to notes for things not in our data model, but afaik haven't done so for polyfills.

"ie": {
  "version_added": false
},

Indicating support removal

Caniuse:

 "ie":{
   "5.5":"n",
   "6":"n",
   "7":"n",
   "8":"n",
   "9":"y",
   "10":"y",
   "11":"n"
}

BCD:

"ie": {
  "version_added": "9",
  "version_removed": "11"
},
Elchi3 commented 5 years ago

Comparing meta data structures

Both data structures come with certain meta data that sometimes map directly or indirectly. Some things don't map at all, though.

caniuse BCD
title ("CSS :any-link selector") description ("\:any-link\")
description ("The :any-link CSS pseudo-class matches all elements that match :link or :visited") --- (mdn-short-descriptions is a separate alpha npm package)
spec spec_url
status ("wd", "ls") status.standard_track (true,false)
links (array{url,title}) --- (mdn_url)
bugs --- (notes)
categories --- (tree hierarchy)
usage_perc_y ---
usage_perc_a ---
ucprefix ---
parent --- (tree hierarchy)
keywords ---
ie_id ---
chrome_id ---
firefox_id ---
webkit_id ---
shown ---
--- status.experimental
--- status.deprecated
wbamberg commented 5 years ago

Very interesting @Elchi3 ! I had a few random observations.

polyfills

I found this issue today because I was reading https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500 again, and especially @torgo 's comment, and went looking to see if anyone had already filed a bug in browser-compat-data about this. It seems like such a good idea, because BCD is exactly the context where someone might want to know about polyfills, and IMO if we could integrate this we could just remove all those Wiki polyfills, which currently fill me with so much sadness.

So it's interesting that caniuse represents polyfills. Unless I mistaken though, the "p" notation doesn't give you a way to link to a particular polyfill, which seems like it would be most useful.

BCD issue for this: https://github.com/mdn/browser-compat-data/issues/3280.

bugs

We've also talked about explicitly supporting bug links: https://github.com/mdn/browser-compat-data/issues/126 although it foundered a bit on whether we should restrict it to implementation bugs for unsupported features (i.e. the bug that tracks the feature's development). But I thought this comment was really good.

keywords

I think these help a lot with usability in caniuse: if you don't know the exact name of a thing, you can search and and have a good chance of finding it.

We have a persistent request for the ability to show BCD for a collection of related things (see e.g. https://discourse.mozilla.org/t/browser-compatibility-tables-for-api-overviews/33832) and perhaps something like this would be able to deliver that. For example in that Discourse post there was chat about displaying compat for "web components" and caniuse handles this rather well: https://caniuse.com/#search=web%20components.

I worry that it will become a big mess like tags in the Wiki, but perhaps not, since we have a review step (and could even have a list of allowed tags that are updated separately from the data).

Elchi3 commented 4 years ago

This research lead to a collaboration: https://hacks.mozilla.org/2019/09/caniuse-and-mdn-compat-data-collaboration/

Closing as no further research is planned for the moment.