Floati now manages its own memory, and it gives memory back. A browse across an encyclopedia, a code-hosting site, a news site and a framework's docs site peaks about 53 percent lower than before, and once the pages are closed the engine holds about 78 percent less. Pages that leave tangles of JavaScript objects behind no longer keep them forever, memory is returned when you switch away or your computer runs low, and DevTools can now show you, live, what every page is holding. JavaScript also got much faster: our measured score against the reference JavaScript runtime on 42 real-world workloads went from 50 to 80.
Floati has its own memory allocator. The allocator is the part of a program that hands out and takes back small pieces of memory; the one Floati used before kept freed memory for itself forever, so the browser only ever grew. The new one keeps each freed piece next to where it came from, notices when a whole region is empty, and hands it back to your computer. Blocks larger than 32 KB are managed the same way, and a growing buffer extends in place instead of copying itself. It is as fast as the old one on our 42 JavaScript workloads.
Memory & reading
Closed pages let go of their JavaScript. JavaScript objects often point at each other in circles (a component and the event handler that points back at it), and Floati counts references, which on its own never frees a circle. Floati now finds such circles when a page closes, and while a page is idle, and frees everything nothing else can reach. After a browse, what a large encyclopedia leaves behind went from 82 MB to 30 MB and a second news site from 40 MB to 6 MB.
Memory & reading
Memory goes back when you are not looking. Ten seconds after Floati goes to the background, and whenever your Mac or PC reports it is running low, Floati returns unused memory to the system instead of waiting to be asked.
Memory & reading
A memory witness is built in. Floati continuously samples where memory is allocated and which page asked for it, at no measurable cost, so it always knows what each page is holding. This is how we found most of this release's savings: one engine table alone was holding 425 MB.
Tabs & interface
DevTools shows memory per page. The Memory panel opens on a new Page memory view: what this page holds, what pages you already left are still holding, the code that allocated it, and a Free memory now button. Other browsers only estimate memory per process; this is per page and live.
JavaScript & JIT
Regular expressions run about three times faster. Patterns are now compiled to a compact program instead of being walked as a tree, and common pieces such as a run of digits are matched in one tight loop. Case-insensitive matching now follows the standard exactly: [A-Z] with the i flag matches lowercase letters, accented capitals match their lowercase forms, and a group repeated in a loop starts each pass empty, as in the reference browser.
JavaScript & JIT
Object.keys, Object.values and Object.entries are faster on ordinary objects: the list of keys is computed once per object shape and reused.
JavaScript & JIT
JavaScript performance, measured, went from 50 to 80. The score compares Floati with a reference JavaScript runtime on 42 real-world workloads and is recomputed for every release; numeric code, sorting and generators now match or beat the reference JavaScript runtime, and the remaining gaps are in class-heavy and closure-heavy code.
Memory & reading
Methods found on prototypes are cached. Calling a method an object inherits (every class method, every built-in such as push or indexOf) used to search the prototype chain each time; each call site now remembers where it found the method and checks in one step that nothing changed. super calls and inherited getters are cached the same way.
JavaScript & JIT
Short-lived objects cost nothing in hot loops. When a loop creates an object that never leaves it (new Point(x, y) used and thrown away), Floati's native compiler keeps its fields in registers and never allocates it, a technique known as escape analysis; on our benchmark this beats the reference JavaScript engine.
JavaScript & JIT
Sorting with a comparator runs as machine code, and comparators of the form a.key - b.key sort by the key directly: sorting numbers is about six times faster than the reference JavaScript runtime on our benchmark.
JavaScript & JIT
Loops that use try/catch, for...of over arrays and generators, typeof checks and global variables now run in the native compiler instead of falling back to the interpreter; a loop over a generator runs as one fused loop.
JavaScript & JIT
Map and Set are rebuilt as an ordered hash table (one array of entries in insertion order plus a compact index), about three times faster for lookups and inserts, and their methods no longer look themselves up on every call.
JavaScript & JIT
Two correctness fixes: for-in over an array or a string now lists its indexes (it listed nothing), and assigning to a const now throws a TypeError in every mode, as the standard requires (it was silently allowed).