TechLife Australia

Browser benchmarks

-

Browser benchmarks have been around for a good many years; you might remember SunSpider – released in 2007 and very much outdated now – which is still available. It’s been superseded by Mozilla Kraken in terms of providing a similar suite of tests, while JetStream, developed by Apple, is a dedicated JavaScript benchmark tool, with version 2.0 housing a Web Assembly benchmark; it’s in part based on the previous benchmark, Octane 2.0.

Both of these measure how quickly the JavaScript engine can manage a suite of basic tasks. By using a wide range of different types of loads, it protects the benchmark against engine optimizati­ons. If you look into the tests, you generally find they’re math-heavy, compiling libraries, testing crypto libraries, ray tracing, and compressio­n tests. As you’d expect, the newer the browser, the faster the results, but due to the more recent Web Assembly elements of JetStream 2, this benchmark failed to complete on “older” browsers, but that even includes the EdgeHTML browser that stalled on the final test. We added Internet Explorer 11, as it’s still supported, and the Blink-based keyboard-oriented Qute.

• A parser This constructs the document tree following the grammar rules. A token is requested from the lexer; if it matches a known rule, it’s added to the tree, else it’s stored and another token is requested. If no match is found for a stored token, an error is raised.

HTML is interestin­g in terms of languages. It has a loosely defined grammar, because it has to be backward compatible and fault tolerant, while it has to deal with dynamic code (via scripts) that can add tokens back in while it’s being parsed. This means its parser can’t use a systematic top-down or bottom-up approach to parsing. In the language world, people say it’s not a context-free grammar – we might call it other things, given half a chance.

To give you a taste of what a web parser has to deal with, let’s quickly look at a very rough day-in-the-life of an HTML lexer. It starts in its default “data state” mode, when a < is encountere­d that switches to “tag open state” mode. Characters a–z encountere­d next create a “start tag” token and a “tag name state.” This continues until a closing > is hit and “data state” mode is back. If a / is encountere­d after a < then an “end tag token” is created until the > is hit.

These tokens are passed to the HTML parser to be constructe­d into the document tree, as and when each suitable HTML tag is encountere­d, from to to and .

What we find more interestin­g than this is what the heck browsers do when they encounter not just badly formatted HTML documents, but downright illegally formatted documents. A browser parser has to be “fault tolerant,” else web pages would just fall over and fail to load. At a minimum, a browser needs to know what to do if a isn’t closed correctly, which happens all the time. Beyond this trivial example, it needs to know what to do if it encounters an unknown tag, an out-of-date tag, or tags used in a non-compliant manner.

There’s no official definition of how to handle erroneous HTML code, but Apple’s WebKit code has a number of interestin­g comments that explain its approach to various classic mistakes, including unclosed or incorrectl­y closed tags, badly nested tables, highly nested tags, and incorrectl­y terminated tags.

Ultimately, the HTML processed by the parser will result in a Document Object Model, aka a DOM tree.

Separately from the HTML, the CSS element of the page will also be parsed into a CSS Object Model tree. Unlike HTML, CSS is a context-free grammar, which makes it more difficult to break by silly humans. The parser has to process the CSS to determine the style of each element. This isn’t a CSS tutorial, so we’re not going to look into the details of the language here.

We’ve alluded to dynamic content and scripts. Really, don’t change much, but browsers are supposed to handle scripts synchronou­sly – parsing stops until the script has been executed. If networked resources are required, these need to be loaded, and everything should be halted until they have been. Script authors can add a to wait until the document is parsed before it’s executed.

However, WebKit and Gecko utilise speculativ­e parsing to read ahead and load any network-based resources, such as scripts, images, and CSS, to avoid stalls in page loading. This is smart, as scripts that request network-loaded style sheets cause issues if they can’t be reached.

Render tree

Things are starting to heat up. We know where things are in the page from the DOM tree created from the HTML. We also know how things should be styled from the CSS Object Model tree, created from the CSS. Each render object is a literal rectangula­r area of specified size

and position, with an attached style. Many objects are actually constructe­d from many rendered rectangles; the important thing to remember is that the render tree is constructe­d from the DOM tree.

We should point out that matching a style to a render object isn’t as straightfo­rward as you might think, depending on how rules are inherited. And how the browser has to process inherited style rules and match them to objects can take a great deal of traversing trees.

Now layout can begin. This is the process of calculatin­g exactly where those rectangles will go with the applied style. HTML is devised so layout can be done in a single pass, moving left to right and top to bottom. Layout can be recalculat­ed on a global level (such as a global style change or window resize), or if “child” objects flag that it needs recalculat­ing. Finally, the render tree can be “painted,” and is handled by the UI elements of the browser, because it’s reliant on the OS.

Powering the web

We’ve already mentioned that all modern browsers run JavaScript, with a JIT compiler for maximum speed. Each browser has its own JavaScript engine, and this enables you to “program the web” and create all the advanced interactiv­e online applicatio­ns. But JavaScript has its origins back in the 1990s, when no one really knew what it was going to be used for – so, say hello to Web Assembly.

Launched in 2015, it was available in most browsers by 2017, and was standardiz­ed at the end of 2019. It enables a low-level, cross-platform language that runs natively on the hardware via the browser. You can compile C/C++ and Rust to Wasm (Web Assembly). It runs in the same sandbox as JavaScript, so can be leveraged by its libraries for effectivel­y free speed-ups.

Web Assembly is available in all the mainstream browsers, and the fact that it runs on the native hardware should offer an indication of the speed-ups developers know it will deliver over interprete­d JavaScript.

At this point, you have an HTML5compl­iant webpage, with all the dynamic Web 2.0 spinning wheels you could ask for. The world (Google, Apple, Microsoft) appears to be settling on a WebKit/Blink-based browser world, which is good for compatibil­ity, and doesn’t stop others offering spin-offs. We dearly hope Mozilla retains the independen­ce of Firefox, but it feels like it’s now fighting an uphill battle. The browser wars will return.

 ??  ??
 ??  ?? Edge is dead, long live Edge (Blink-powered).
Edge is dead, long live Edge (Blink-powered).
 ??  ?? Browsing the web, 2005-style. Not fun.
Browsing the web, 2005-style. Not fun.

Newspapers in English

Newspapers from Australia