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

Supported browser versions #6805

Open
3 of 5 tasks
Gudahtt opened this issue Jul 4, 2019 · 19 comments
Open
3 of 5 tasks

Supported browser versions #6805

Gudahtt opened this issue Jul 4, 2019 · 19 comments

Comments

@Gudahtt
Copy link
Member

Gudahtt commented Jul 4, 2019

We should be explicit about which browser versions we support, and take steps to ensure we remain compatible.

Currently we state on our website that we are compatible with Chrome, Firefox, and Brave, but we don't specify any minimum required browser versions. Opera is listed as well, but that version is very outdated. We don't regularly test which browsers the application works on either, relying instead upon bug reports for compatibility with older browsers.

There was a previous issue for documenting which browsers we support (#3343), but that was closed with an adjustment of our Babel configuration file to support all browser versions with at least 0.25% global usage (according to browserlist), excluding IE 11 and Opera Mini. However, this includes some very old browser versions, more than we'd care to support in practice.

Instead we should document explicitly which browsers we support, and add tests to ensure we stay compatible (perhaps to run nightly, so we don't overly burden CI). Then we can get rid of the Babel transformations and polyfills we no longer need. We should also update the manifests to state the minimum browser version, so users don't accidentally install the extension on an unsupported browser.

Steps:

  • Choose minimum supported browser versions
  • Document the supported browser versions
  • Remove Babel transformations and polyfills used for compatibility with unsupported browsers
  • Add nightly tests for minimum supported browser versions
  • Update manifests to include minimum browser version
Gudahtt added a commit to Gudahtt/metamask-extension that referenced this issue Jul 4, 2019
While working on MetaMask#6805, I noticed that many variables were being used
before they were declared. Technically this worked fine in practice
because we were using the `transform-es2015-block-scoping` Babel plugin,
which transforms `let` and `const` to `var`, which is hoisted. However,
after removing that Babel transformation, many things broke.

All instances of variables or classes being used before declared have
been fixed.

The `no-use-before-define` eslint rule has been added to catch these
cases going forward. The rule is disabled for function declarations for
the moment, because those are always hoisted. We could disable that too
if we want to, but it's purely stylistic and would require a lot more
changes.
Gudahtt added a commit to Gudahtt/metamask-extension that referenced this issue Jul 4, 2019
The Babel config had previously supported all browsers with greater than
0.25% global usage (according to `browserlist`). This resulted in
`babel-preset-env` including plugins sufficient to support the following
minimum browser versions:

```
{
  "chrome": "49",
  "android": "4.4",
  "edge": "16",
  "firefox": "52",
  "ios": "9.3",
  "safari": "11"
}
```

Instead, the babel config now explicitly supports chrome >= 58 and
firefox >= 53. Chrome and Firefox are the only browsers we currently
publish to, and these were the minimum versions with no additional Babel
transformations.

The minimum browser versions we support should be re-evaluated later,
after we have added tests and documentation.

The `stage-0` Babel preset has also been replaced with the specific
Babel plugins that we depend upon. We don't use most of `stage-0`, so
this allowed us to remove many unnecessary transformations. We had to
remove this preset soon anyway, because all of the stage presets are
deprecated in Babel 7.

The `stage-0` preset consisted of these plugins:
```
"transform-do-expressions"
"transform-function-bind"
"transform-class-constructor-call"
"transform-export-extensions"
"transform-class-properties"
"transform-decorators"
"syntax-dynamic-import"
"syntax-trailing-function-commas"
"transform-async-generator-functions"
"transform-async-to-generator"
"transform-exponentiation-operator"
"transform-object-rest-spread"
```

Of that list, only 'transform-class-properties' and 'transform-object-
rest-spread' were required. 'transform-async-to-generator' was being
used (as we are using async/await), but our browser targets all support
async/await, so that could be removed. The remainder of the plugins were
completely unused.

Removing some of these transformations exposed bugs in `uglify-es` that
only presented themselves in the production build. `gulp-uglify-es` has
been updated to a version that uses `terser` instead of `uglify-es`,
which has resolved these issues.

Relates to MetaMask#6805
Gudahtt added a commit that referenced this issue Jul 5, 2019
While working on #6805, I noticed that many variables were being used
before they were declared. Technically this worked fine in practice
because we were using the `transform-es2015-block-scoping` Babel plugin,
which transforms `let` and `const` to `var`, which is hoisted. However,
after removing that Babel transformation, many things broke.

All instances of variables or classes being used before declared have
been fixed.

The `no-use-before-define` eslint rule has been added to catch these
cases going forward. The rule is disabled for function declarations for
the moment, because those are always hoisted. We could disable that too
if we want to, but it's purely stylistic and would require a lot more
changes.
@Gudahtt
Copy link
Member Author

Gudahtt commented Jul 6, 2019

Choose minimum supported browser versions
Here are the factors to consider that I've thought of so far

  • User impact
    • How many users would be affected?
    • How many users would be unable or unwilling to switch to a supported browser?
  • Support / Quality Assurance
    • More browser versions to test means more QA and support
      • We could have a two-tiered system, where "tier 1" platforms (e.g. last 2 versions of each browser) get are included in typical QA efforts, but for "tier 2" platforms (e.g. older versions) we rely upon bug reports from users. It would still be more work than dropping support though.
  • Development / Maintenance
    • Transformations and polyfills are required to support features we use on older platforms
      • Complicates build process
      • Slows down build process
      • Increases final bundle size
    • Many of the tools and libraries we use may not work on older platforms. Taking care to ensure things are compatible takes time, and is often not considered by new contributors
    • Certain new JavaScript features come with improvements to the development experience (e.g. async stack traces). Supporting older browsers might mean not benefiting from these improvements
    • Certain new features might be easier/faster to build if we didn't have to worry about supporting older platforms
  • Product
    • Certain new JavaScript features come with performance improvements
  • Security
    • Older browsers generally aren't secure. Supporting older browsers could be seen as encouraging their use, or at least enabling it. Maybe that's something we shouldn't do on principle.
    • There may be additional security implications we don't know about

I don't know the answer to many of those questions. I do have one strong preference though: that we only support browser versions with async / await support. The async-to-generator transformation required to support browsers without async functions means that we won't have async strack traces, even on newer browsers. Async strack traces can be incredibly useful for certain errors. Using async / await comes with some nifty performance enhancements too.

So that puts us at Chrome 55 and Firefox 52.

That still leaves us with a number of Babel transformations though; 6 for Firefox and one for Chrome. To get zero preset-env transformations, we need to go to Chrome 58 and Firefox 53.

Next I'm going to test the extension on older browsers, to get a sense for whether it works correctly at the moment. We should probably drop support for any older browsers that are already incompatible.

@Gudahtt
Copy link
Member Author

Gudahtt commented Jul 9, 2019

Our usage metrics indicate that nearly everybody is using versions of Firefox >= 53, or Chromium > 58 (where 'Chromium' includes Google Chrome, Chromium, and any browsers based off of Chromium). Out of ~380k visits recorded since July 1st, a single visit was made using Firefox 50, and 176 were unable to be identified (0.047% of visits at worst, assuming all the unknown visits were from older versions).

Overall it looks like ~93.7% of visits were made using most recent 2 versions or greater (e.g. beta/canary or development builds) of Chromium or Firefox.

@Gudahtt
Copy link
Member Author

Gudahtt commented Jul 9, 2019

Firefox has an extended support release, which is currently at version 60. There is no equivalent for Chromium - they only support the latest release.

If we wanted to adopt a more aggressive policy of only supporting browser versions that are actively maintained, I'd suggest we set the Firefox ESR release as the minimum for Firefox, and take the last 2 version for Chromium. That would include between 94-96% of traffic, according to the usage statistics I collected earlier. That still leaves 4% of users on outdated browsers though - that's not insignificant.

Gudahtt added a commit to Gudahtt/metamask-extension that referenced this issue Jul 15, 2019
The Babel config had previously supported all browsers with greater than
0.25% global usage (according to `browserlist`). This resulted in
`babel-preset-env` including plugins sufficient to support the following
minimum browser versions:

```
{
  "chrome": "49",
  "android": "4.4",
  "edge": "16",
  "firefox": "52",
  "ios": "9.3",
  "safari": "11"
}
```

Instead, the babel config now explicitly supports chrome >= 58 and
firefox >= 53. Chrome and Firefox are the only browsers we currently
publish to, and these were the minimum versions with no additional Babel
transformations.

The minimum browser versions we support should be re-evaluated later,
when we have added tests and documentation.

The plugin 'transform-async-to-generator' has also been removed. It was
used to translate async/await, but our browser targets all support
async/await.

Removing some of these transformations exposed bugs in `uglify-es` that
only presented themselves in the production build. `gulp-uglify-es` has
been updated to a version that uses `terser` instead of `uglify-es`,
which has resolved these issues.

Relates to MetaMask#6805
Gudahtt added a commit that referenced this issue Jul 18, 2019
Set the minimum browser version supported in the extension manifest.
Currently we only ship the extension on Chrome and Firefox, so the
minimum version has been set for those two browsers.

Relates to #6805
@Gudahtt Gudahtt added this to the UI Sprint 16 [July 8] milestone Jul 18, 2019
Gudahtt added a commit that referenced this issue Jul 18, 2019
Set the minimum browser version supported in the extension manifest.
Currently we only ship the extension on Chrome and Firefox, so the
minimum version has been set for those two browsers.

Relates to #6805
Gudahtt added a commit that referenced this issue Jul 18, 2019
The Babel config had previously supported all browsers with greater than
0.25% global usage (according to `browserlist`). This resulted in
`babel-preset-env` including plugins sufficient to support the following
minimum browser versions:

```
{
  "chrome": "49",
  "android": "4.4",
  "edge": "16",
  "firefox": "52",
  "ios": "9.3",
  "safari": "11"
}
```

Instead, the babel config now explicitly supports chrome >= 58 and
firefox >= 53. Chrome and Firefox are the only browsers we currently
publish to, and these were the minimum versions with no additional Babel
transformations.

The minimum browser versions we support should be re-evaluated later,
when we have added tests and documentation.

The plugin 'transform-async-to-generator' has also been removed. It was
used to translate async/await, but our browser targets all support
async/await.

Removing some of these transformations exposed bugs in `uglify-es` that
only presented themselves in the production build. `gulp-uglify-es` has
been updated to a version that uses `terser` instead of `uglify-es`,
which has resolved these issues.

Relates to #6805
@bdresser bdresser added this to the UI Sprint 18 [Aug 5] milestone Aug 5, 2019
@bdresser
Copy link
Contributor

@tmashuang @Gudahtt is this close to the finish line?

@Gudahtt
Copy link
Member Author

Gudahtt commented Aug 15, 2019 via email

@leafcutterant
Copy link

I hope this is the right place to report this.

MM 7.0+ can be installed only on Firefox 60.0+. Due to this, Firefox forks that haven't progressed to 60.0+ (e.g. Waterfox) can't use the latest MM. Any chance of this changing?

@Gudahtt
Copy link
Member Author

Gudahtt commented Sep 11, 2019

@leafcutterant Sure, this is a good place to discuss this.

I do have some hesitance because we'd like to move to newer minimum versions if possible, to allow ourselves to use newer browser APIs. We also don't generally want to encourage the use of older browsers that aren't getting security updates. But if it doesn't cause us too much trouble and you think there's a legitimate need, we can definitely consider it.

Thanks for bringing Waterfox to our attention - I wasn't aware that this browser existed, or that it was stuck on Firefox 56. From glancing at their issue tracker, it looks like it'll be a while before they're able to update (if ever).

Could you elaborate on why you use Waterfox, or why you think it's important to support? We don't see very many users using Waterfox.

@leafcutterant
Copy link

leafcutterant commented Sep 11, 2019

@Gudahtt, sure, thank your for listening!

First of all, let me explain the rationale of using Firefox forks: a few years ago Mozilla started to put limitations on what kind of addons you're able to add to your browser. These limitations grew more and more egregious over time, and the effort needed to hack around them increased. This got to a point where now it's hard-coded in the browser that any addon not downloaded from the Mozilla extension store can't be used. They have exclusive control over what can and cannot be installed in your own browser. Some people are okay with this. I'm definitely not, and I hope that you and most others in crypto feel the same. Centralization is dangerous.

But bls sir wher go now? FF ESR? Thanks, I prefer to get critical fixes on time. FF developer/beta/nightly? I'd rather choose stability. Anyone who wanted to retain the freedom they got used to, but wanted a browser that works, turned to FF forks. Many exist. None are perfect. Waterfox stands out with their hard-line commitment to 1) privacy, 2) user freedom and 3) usability. Almost everything that phones home, sends user data anywhere or aids surveillance has been removed from the code base. Users can modify any setting and install any extensions, even non-WebExt addons, which is a huge boon. It's currently up-to-date to FF 60.9 wrt security. Among FF forks, it is quite up-to-date with the upstream, breaks the least things, and has the largest social following and contributor base if we don't count Tor Browser.

Waterfox matters because it's a libre safe haven. Just like with cryptocurrencies, overall not many people may use it, but its existence is important.

@Gudahtt
Copy link
Member Author

Gudahtt commented Sep 11, 2019

Thanks for explaining! I'm glad to hear that it's still getting security updates. Some of those reasons are certainly compelling.

I'll set the minimum version to 56.2, which should be compatible with "Waterfox Classic" (i.e. the stable version). It looks like we can keep using v56 a while longer without adding any additional transpiling. I'm using 56.2 instead of 56.0 to prevent MetaMask from being installed on Firefox for Android 56.0 (which is missing a feature we use).

I can't make any promises on keeping it here though. When the day comes that we want to use a new browser API, we'll bump up the minimum version again. Hopefully the "Waterfox Current" release stabilizes soon. It looks like they have an alpha release based on Firefox v68.

@Gudahtt
Copy link
Member Author

Gudahtt commented Jul 27, 2020

I've just reviewed the metrics for this month so far, and it turns out that very few users are using Chromium 58.x or 59.x. Of the identifiable browsers present in our metrics, only a single visit is from a user within that range.

Given that, it should be fine for us to increase the minimum supported Chrome version to 60, so that we no longer need to transpile Object rest/spread.

@whymarrh
Copy link
Contributor

whymarrh commented Sep 3, 2020

Yeah I would suggest we bump our minimum Chromium version to at least support rest parameters and the spread syntax.

@Gudahtt
Copy link
Member Author

Gudahtt commented Dec 8, 2020

Motivated by a new incompatibility we've discovered in a dependency (see #10014), I've taken another look at our metrics to see how many users are using browsers based on Chromium v62 or lower, and the answer is "not many". Of the browser forks I was able to identify an equivalent Chromium fork for (using map-to-chrome), a total of one user was on a browser based on a Chromium version below v63 (Yandex 16.6.1.7469 specifically). There is a surprising amount of usage of Chromium v63-based browsers, but practically nothing below that. This is from looking at the last 1 month of metrics.

Based on that, I think we can safely increase the minimum Chrome version to 63.

@Gudahtt
Copy link
Member Author

Gudahtt commented Jan 14, 2021

@leafcutterant I wanted to give you a heads up that we're considering dropping support of Waterfox Classic. It's becoming increasingly difficult to support it as more of our dependencies start to include ES6 syntax that Waterfox Classic doesn't support. We'd have to start transpiling all of our dependencies in order to continue supporting it well, and nobody is eager to make our already slow and complex build system even slower and more complicated.

We will continue to support non-Classic version of Waterfox (what they're now calling "Waterfox Third Generation").

@Gudahtt
Copy link
Member Author

Gudahtt commented Jan 15, 2021

I've taken a look at our metrics, and they indicate that less than 0.7% of our monthy active Firefox users are using versions less than v68. I'm going to propose that we move the minimum version up to v68 for Firefox. Firefox v68 is the previous Extended Support Release. so it's the oldest Firefox version that isn't very behind on security patches and it's the lowest version with fairly large user-base (>3% of Firefox users).

By moving the minimum version to v68, we can stop worrying about async iterators in our dependencies making the extension crash on these older browsers. It would ensure our lockdown script runs properly too, which will help reduce our Sentry error volume.

Gudahtt added a commit that referenced this issue Jan 15, 2021
Firefox v68 is the _previous_ Extended Support Release. We are
increasing this because our current minimum version doesn't support
async iterators, so some of our dependencies cause the extension to
crash.

Our metrics show that usage of Firefox versions older than this is
quite low (under 0.7% of Firefox users in the past month). These older
versions are also _very behind_ on security updates. Using the Extended
Support Release also makes it easier for us to test the minimum
version, and ensure our extension remains compatible with it.

Relates to #6805
darkwing pushed a commit that referenced this issue Jan 21, 2021
Firefox v68 is the _previous_ Extended Support Release. We are
increasing this because our current minimum version doesn't support
async iterators, so some of our dependencies cause the extension to
crash.

Our metrics show that usage of Firefox versions older than this is
quite low (under 0.7% of Firefox users in the past month). These older
versions are also _very behind_ on security updates. Using the Extended
Support Release also makes it easier for us to test the minimum
version, and ensure our extension remains compatible with it.

Relates to #6805
@rekmarks
Copy link
Member

rekmarks commented Sep 1, 2021

Following the principles / heuristics previously laid out in this issue, we will be bumping our minimum Chrome version from 63 to 66 in an upcoming release. For details, see #11995.

@Gudahtt
Copy link
Member Author

Gudahtt commented Nov 25, 2021

I don't have access to our metrics right now, but I'd like to propose that we start tracking the previous ESR release for Firefox, and support ~2 years of Chromium versions. That should provide plenty of time for slow-to-update corporate policies, browser forks, and users that infrequently update. These days it's not safe to use a browser that old anyway.

Right now that means bumping to v78 for each browser, which is done in #12847

@Gudahtt
Copy link
Member Author

Gudahtt commented Nov 25, 2021

I don't know of any data source for the equivalent Chrome version for browser forks - the old data source I used (map-to-chrome) is no longer being updated. So for popular browser forks like Yandex and Coc Coc, I don't know which versions this change would exclude.

But I did try excluding the most recent version of each of these browsers. That shows that this change would affect at most 1% of the userbase.

  • ~0.56% of our users are on Chrome versions below v78
  • ~0.097% of users are on Firefox versions below v78
  • ~0.092% of users are on Mobile Safari, somehow???
  • ~0.2% of traffic is from browsers I can't identify the compatibility of.

@Gudahtt
Copy link
Member Author

Gudahtt commented Jan 20, 2023

Looking at our metrics, usage below v78 has dropped off to nearly zero, aside from a conspicuously high number of users on Firefox v75 specifically (though still under 0.1% of our users overall)

Taking a look today at what I proposed as a policy way back:

I'd like to propose that we start tracking the previous ESR release for Firefox, and support ~2 years of Chromium versions. That should provide plenty of time for slow-to-update corporate policies, browser forks, and users that infrequently update.

Today that would bring us up to Chrome v88 and Firefox v91. This would affect roughly 1% of current users (distribution by browser is roughly 3:2:1 ratio of Opera:Firefox:Chrome)

Gudahtt added a commit that referenced this issue Mar 13, 2024
A document about browser support guidelines has been added. This
document describes our browser support policy, and the notification
requirement when updating the minimum supported browser versions.

Relates to #6805
Gudahtt added a commit that referenced this issue Mar 14, 2024
## **Description**

A document about browser support guidelines has been added. This
document describes our browser support policy, and the notification
requirement when updating the minimum supported browser versions. This
is not a new policy, it just wasn't written down before now.

## **Related issues**

Relates to #6805

## **Manual testing steps**

N/A

## **Screenshots/Recordings**

N/A

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've clearly explained what problem this PR is solving and how it
is solved.
- [x] I've linked related issues
- [x] I've included manual testing steps
- [x] I've included screenshots/recordings if applicable
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
- [x] I’ve properly set the pull request status:
  - [x] In case it's not yet "ready for review", I've set it to "draft".
- [x] In case it's "ready for review", I've changed it from "draft" to
"non-draft".

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants