Browser engine versioning standard, allowing breaking changes, moving the web more forward without the cruft

I think it’d be neat if there was a standard that allowed browser engines to move forward with breaking changes (or any changes) under the concept of “versions”.

Websites could specify which version of features they use. Engines could by default ship with the latest version. If a website is using an older version of features, then the browser prompts the user to install those older features.

This could allow, for example, things like the problematic new EcmaScript class fields to be fixed in a way that newer websites could specify that they use that version of the engine, while older browser continue to use a previous version.

The only thing back-ported to older versions are security fixes (and bug fixes if vendors care enough).

How would that look like? Maybe a root-level entry in manifest.json or something could specify a webVersion field, or something.

As specs move forward, a snapshot of all the specs is created at some version number. This includes the spec’d state for HTML, CSS, DOM, EcmaScript, etc.

This would help to reduce the size of browser engines while bringing the web forward. Eventually, hen old websites are no longer visited and old features are no longer used, the average user will not download that version of the engine. They’ll only by default have the latest version with latest features, and sometimes they’ll need to accept a version download for websites still using older versions.

Perhaps a browser would ship with the most common versions still in use. There’d be some statistical threshold for determining which versions to ship with by default. Etc.

New versions doesn’t mean removing old features (though it might). A new versions might remove bad features of the web, or only make some fixes to bad parts.

A main downside of this would be that more code has to be maintained by vendors.

Anyway, I am dreaming of a better landscape.

1 Like

I’m not sure that a prompt to install an older version of the engine when visiting older sites is a good user experience for the web. Would people even understand what is being asked?

If the prompt said something like

This website requires older browser features to be installed. Proceed?

it would be understandable.

Maybe it would have more information, like

This website requires browser features v3 to be installed. Proceed?

How can we bring the web forward without all the cruft? It isn’t scalable to simply keep adding more and more web features. Just imagine if we continue at this pace how the web will be in 20 years.

1 Like

We deprecated Flash. Surely we can do this with builtin features too.

Removing features is one thing. I am also suggesting maybe there is a way to manage the (older) features, to allow them to be optionally installable. Perhaps it would be based on snapshots of the browser engine. Rather than modifying browser implementations so that the code has a bunch of conditional checks, it would instead download snapshots of the engine code, where a previous version may contain entirely different code that may have existed prior to a total refactor (for example).

I have a feeling that browser vendors would not want to do this. I remember a blink-dev discussion where a legacy feature was used by 0.08% (IIRC) of web pages, and they were hesitating to remove it. Compatibility with the legacy web is like a law of physics to them, unbreakable.

Are you aware of how long it’s taking to remove Flash? Or how long it took to remove Java for that matter? It took about five years (2013-2018) to remove Java applets, and Flash is still on the tail end of its three-year deprecation timeline scheduled to finalize December 31 of this year. (For context, removal of both of these were a massive, genuine necessity to protect end users, not just little nice-to-haves for browsers.) Even on the JS side, it was a struggle to ensure that let[x] = 1 could be repurposed from indexed assignment to a variable declaration, and removing arguments.caller itself was a monstrous task that started back in ES5 and took until ES2017 for them to finally be able to pull the plug.

Removing features is nearly impossible on the web, and even the biggest hacks generally have to be maintained. And not only that, browsers will still have to implement them for possibly years to come. Tf you want to see how well it works out in practice, just look at how well Firefox’s old JS versioning attempt worked out (spoiler alert: it didn’t and they dropped support for it only a few versions in, before it even really took off).

Keep in mind 0.08% of websites is still almost 1.5 million websites. And that’s just websites, not web pages. 0.08% of the web is a lot of web, and do you really want to unilaterally break millions of pages and likely annoy or anger millions of users?

You know how in JavaScript new features enable the removal of others by means of introducing a new mode (f.e. “use strict”, or modules)?

Maybe we need two things:

  • A standard way for browsers to introduce new modes (not just for JavaScript, but for HTML/CSS) that can introduce new features while dropping others.
  • An official way to deprecate the old features (old modes) after some time (even if that happens to be spec’d to 3 or 5 years).

Could that be possible?

do you really want to unilaterally break millions of pages and likely annoy or anger millions of users?

Well I’d like to avoid it, but maybe that’s part of the problem.

Libraries need to accept that some people dislike changes, but changes are required to bring libraries to a new and better future. Maybe the web needs that, and can accept that some few portion of people will not like it.

Maybe the annoyance to that fraction of users will ultimately make them happier and everyone else happier in the longer term?

We used to have that in doctypes. Now with <!DOCTYPE html> there is no version information anymore. Maybe we should bring back doctype versions, ex <!DOCTYPE html 80> or something.

Even with doctype versioning or the earlier proposed alert of “You need to install X features is it ok to proceed?” these both have the same fundamental failures.

  1. You still don’t remove the feature. It’s still present just in a different “mode”.
  2. In the latter case, you are putting the onus on the user to understand what is going on. That is simply infeasible given how vague these would need to be in order to be remotely achievable.
  3. Even IF by some extreme measure this was rolled out, it just makes the web more complicated. This creates more pathways in the engines to do their jobs. The more pathways you have, the more difficult it is to add new things. So you’ll end up stagnating the platform rather than speed up development.

It’s just not a good idea. We need less pathways not more. Less pathways allows for users and developers to have clear expectations when taking advantage of the platform.

@easrng DOCTYPE is not enough, that covers only ML syntax. The versioning idea would cover all browser APIs.

Well the whole point is old pathways could be left behind, with their issues. Initially, there may be a bunch of organization needed to update a browser code base to make it suitable for versioning the parts. But eventually, new versions may be cleanly updated with minimal changes needed to old versions, or critical patches applied to re-usable code that will be used in multiple versions.

The key is that most code follows existing specs, which don’t change too much unless there’s a serious issue with them. So APIs could be made to be re-usable so old versions can use stuff that new versions have carried over into their set of APIs.

For example, some older version may have both HTMLHttpRequest and fetch, and a new version would have only fetch, but the old version’s fetch is the same one from the new version, re-using the same code.

Engineers will figure how to put re-usable code into a common place, to share across versions.

I imagine version changes need to represent major changes. For example, going from Custom Elements v0 to v1 was fairly major. It would be easy to leave one for an older version and the new one in a new version, but it is not like we would want to have 10 versions of custom elements just because we have a versioning system in place. We’d still want to spec things as we do currently, aiming for longevity.

There will not be different versions of fetch across versions, unless they are very major differences (like CE v0 vs CE v1). The main differences across versions would be absolutely necessary small changes, while entire distinct old APIs are removed or distinct new APIs are added, but we would avoid incrementally changing an API all the time just to make it more ideal if it already works.

In other words, the changes would be like from XMLHttpRequest to fetch, but not something where fetch morphs over time. The browser API versioning system would still use stable specs for their APIs, not continually morphing specs.

Specs would continue as they do today: aiming for stable changes that should last a long time. This gives us mostly the opportunity to drop APIs that we’ve proved over decades that we can drop.

In the end, selecting the sets of APIs that go into versions becomes mostly a matter of choosing which APIs go or don’t go into versions, and in the worst case having to ensure that small changes in APIs are branched across versions in very rare occasions. Critical bug fixes would be “back ported” simply by patching those fixes in the shared code that all versions use.

I’m trying to imagine something that makes things better for both web devs and browser devs. I guess it is sort of like feature layers. A “version” is mainly a set of features where the features are spec’d according to long-term standards like currently, a spec author would not be changing an API spec every month in breaking ways. Maybe even the time between Web API versions could be a few years, once people have had enough time to realize problems and new solutions.