跳到正文
Hacker News-首页· BitPirate·· 3 小时前AI 评分14

Ladybird 浏览器 2026 年 10 月进展:多线程渲染、JS JIT 与 WebAssembly 引擎更新

This Month in Ladybird – October 2026

AI 导读

Ladybird 浏览器在 2026 年 10 月移除了主线程的样式与布局计算并引入 JavaScript JIT,同时替换了支持异常处理和 GC 的全新 WebAssembly 引擎。WPT 测试通过数在月底达到 2,184,722 个并超过 Safari Technology Preview,浏览器 UI 也迎来了全新设计。

正文 · 原文

Hello friends! In October, we moved style and layout off the main thread, built a JavaScript JIT, replaced our WebAssembly engine, redesigned the browser UI, and passed Safari Technology Preview on Web Platform Tests. :^)

Ladybird is entirely funded by companies and individuals who believe in the open web. You can see everyone supporting the project on our sponsors page, and we’re grateful to all of them. If you’re interested in sponsoring, please contact us.

Style and layout no longer wait for JavaScript

Browsers normally run JavaScript, style, and layout on one main thread, one at a time. While a script runs, the page can’t update. A few simple animations can keep going on the compositor, but everything else has to wait.

We moved style and layout to their own thread, and paint recording to another (#12377, #12400). They now run at the same time as JavaScript (#12396, #12432, #12460). If a script asks for layout information, like an element’s size, it waits until pending layout work is finished, so it never gets stale data.

Timeline of a long script. In September, the page doesn't update and doesn't respond to the mouse until the script ends. In October, render threads keep drawing new frames during the script, and :hover responds right away. Timeline of a long script. In September, the page doesn't update and doesn't respond to the mouse until the script ends. In October, render threads keep drawing new frames during the script, and :hover responds right away.

So two things now work during a long script:

  • CSS animations keep running while JavaScript is busy. This includes animations that change layout, like width and font-size (#12433, #12447, #12451).
  • :hover keeps working while JavaScript is busy. The render thread finds the element under the mouse, applies its hover styles, starts any transitions, updates the cursor, and draws a new frame. When the script ends, the main thread catches up and fires the hover events (#12530).

As far as we know, no other browser can do this today. Here’s a text animation while JavaScript blocks the main thread in 1.5 second bursts, with Ladybird in the top left:

And here’s :hover on a page running JavaScript for 250ms at a time, with Ladybird on the left and Chrome on the right:

You can also try it yourself. The button blocks the main thread for three seconds. Most browsers keep the square spinning, but freeze the bar and the hover target.

transform

width

Hover me

:hover

Idle

A JavaScript JIT

On Linux and macOS, LibJS now compiles hot JavaScript to machine code, on both x86-64 and AArch64 (#12613).

We decided against a JIT in the past, and did what we could to push and tune the interpreter instead. It’s already competitive, so making it twice as fast would be a huge effort, and that would only turn a 300ms hang into a 150ms hang, which you’d still notice. So we needed an optimizing JIT.

The design is deliberately boring: speculative optimization based on runtime type profiling, like other JavaScript engines. For now, we just want to go reasonably fast.

Flow diagram: code starts in the interpreter, moves to a profiling interpreter, then a background compiler, then runs as JIT code. If a guess was wrong, it goes back to the interpreter and gets recompiled. Flow diagram: code starts in the interpreter, moves to a profiling interpreter, then a background compiler, then runs as JIT code. If a guess was wrong, it goes back to the interpreter and gets recompiled.

While code warms up, we record things like which types and object shapes it sees (#12588). The compiled code uses those recordings to make guesses, like “this value is always an integer”, and inlines small functions (#12595, #12598).

To find bugs during development, we used a fuzzer that ran the same code in the JIT and the interpreter and compared the results (#12601).

A new WebAssembly engine

We replaced our C++ Wasm engine and Cranelift with a new engine that has its own interpreter and JIT (#12963). It supports newer parts of WebAssembly that the old engine didn’t, like exception handling and GC. On the JetStream 3 Wasm workloads both engines can run, it scores about 7x higher.

Flow diagram: validator, interpreter written in flap, and JIT. About 7x higher JetStream 3 Wasm score on workloads both engines run. Flow diagram: validator, interpreter written in flap, and JIT. About 7x higher JetStream 3 Wasm score on workloads both engines run.

In July, we built flap, a small language and compiler for writing LibJS’s interpreter. The Wasm interpreter is written in flap too, so one source builds it for x86-64, AArch64, and Windows x64. Hot functions move from there to the JIT, even in the middle of a running loop.

We’re making great progress on performance. JSLinux, an x86 PC emulator, now boots Alpine Linux to a shell in 1.8 seconds, while Chrome takes 1.5.

Benchmarks

Four charts of October benchmark scores: Speedometer 2 from 84 to 156, Speedometer 3 from 5.9 to 8.6, Octane up 4.7x with a jump when the JIT was turned on, and Wasm CoreMark up 2.5x with a jump at the new engine. Four charts of October benchmark scores: Speedometer 2 from 84 to 156, Speedometer 3 from 5.9 to 8.6, Octane up 4.7x with a jump when the JIT was turned on, and Wasm CoreMark up 2.5x with a jump at the new engine.

Web Platform Tests (WPT)

On October 26, we passed Safari Technology Preview on WPT. :^) We ended the month at 2,184,722 subtests, a gain of 75,650.

Line chart of WPT subtests passed in October. At the end of the month: Chrome 2,244,397, Firefox 2,189,315, Ladybird 2,184,722, Safari Technology Preview 2,172,990. Line chart of WPT subtests passed in October. At the end of the month: Chrome 2,244,397, Firefox 2,189,315, Ladybird 2,184,722, Safari Technology Preview 2,172,990.

Most of that gain came in five days, from about 2.12 million on October 22 to about 2.18 million on October 27. We pointed AI coding agents at WPT and asked them to fill in missing functionality. They made lots of small fixes, and those added up. Our biggest gains for the month were about 30,000 in /css and 10,000 in /editing.

A new browser UI

Ladybird's redesigned interface showing ladybird.org, with a row of tabs open on the websites of other browsers Ladybird's redesigned interface showing ladybird.org, with a row of tabs open on the websites of other browsers

Until now, our UI had grown organically, with tinkering here and there. This was the first time we sat down and mapped out a complete design. We kept it modest and quiet, so the attention stays on the page.

It covers tabs, toolbars, menus, and our own about: pages on macOS and Linux, in light, dark, and a violet dark theme for private windows (#13271, #13169, #12815).

Ladybird's Settings page, with a sidebar of sections, a search field, and toggles for startup, content, and browsing options Ladybird's Settings page, with a sidebar of sections, a search field, and toggles for startup, content, and browsing options The site settings popover in Ladybird, opened from the address bar, with controls for autoplay, dark mode, and content blocking The site settings popover in Ladybird, opened from the address bar, with controls for autoplay, dark mode, and content blocking

  • Tabs: you can pin tabs, search all open tabs, and restore your windows on launch (#12757, #13271).
  • Form controls got a new look, and date and time inputs got a picker (#13554).
  • Scrolling: smooth mouse wheel scrolling (#12593), elastic overscroll on macOS (#12624), touchpad momentum on other platforms (#12345), and scrollbars that hide until used (#12997).

Sites that work better

  • Google Slides: presentations open instead of showing an error (#12497).
  • GitHub: Mermaid diagrams render (#12383).
  • ChatGPT: the text box grows as you type (#13050).
  • nytimes.com and reuters.com get past their bot checks (#12718, #12188).
  • Instagram: videos show their first frame instead of staying blank (#12898).
  • Gmail: reloading no longer keeps the old page in memory (#12689, #12660).
  • x86CSS , an x86 emulator made of CSS, is now usable (#12911).

New browser features

  • Screen readers: we’ve added first support for VoiceOver on macOS and Orca on Linux (#9156). There’s still a lot of work to do here.
  • Spell checking in text fields on macOS (#12638).
  • Picture-in-Picture (#12542).
  • Links to text: links can scroll to a piece of text and highlight it, and you can create them from the context menu (#11121, #12744).
  • Permissions: sites can now ask for your location and microphone (#13336, #12604).
  • DevTools: Inspect Element (#13348), console autocomplete (#13355), and expandable objects in the console (#13360).
  • Smaller additions: Find in page can highlight all matches (#12434), ad blocking can be turned off per site from the toolbar (#12695), and we added Reload Without Cache (#13056).

More of the web platform

We rendered this page in Ladybird, using features that landed in October:

A grid of web features rendered by Ladybird: multi-column text, twelve numbered boxes in a grid-lanes masonry layout, MathML formulas, six boxes using different corner shapes, arrows following an offset path, labels anchored to all four sides of a box, and a heading with and without text-wrap: balance. A grid of web features rendered by Ladybird: multi-column text, twelve numbered boxes in a grid-lanes masonry layout, MathML formulas, six boxes using different corner shapes, arrows following an offset path, labels anchored to all four sides of a box, and a heading with and without text-wrap: balance.

From the top left, that’s multi-column (#13026), display: grid-lanes for masonry (#13236), MathML (#13062, #13141), corner-shape (#12942), CSS Motion Path (#13027), much more of anchor positioning (#13021, #13079, #13166), and text-wrap: balance (#13461).

We also added:

  • CSS: calc-size(), which lets heights animate to and from auto (#13006), plus vertical writing modes (#13103), zoom (#13237), the stretch sizing keyword (#13006), shape() and border-shape (#12942), field-sizing (#13050), view progress timelines and animation-range (#12943), and the start of SVG animation (#12823, #13498).
  • Web APIs and more: the HTML Sanitizer API (#13185), Touch Events (#13249), Cross-Origin-Opener-Policy (#12296), Paint Timing, Event Timing, Largest Contentful Paint (#13110), WebVTT cues (#12895), wide-gamut canvases (#13097), WebDriver BiDi (#13167), JavaScript’s using and await using (#13102), and many execCommand and contenteditable fixes (#13186, #13038).

Security and process isolation

Web pages run in sandboxed renderer processes, so a malicious page that takes over its renderer should be stuck there.

We kept fixing security issues from many sources, including ways around that sandbox. For example, a compromised renderer could ask the browser process to open any file on your computer. Now only a renderer showing local files can read them (#12582, #12590). Renderers could also fake a user click to open popups or read the clipboard. The browser process no longer trusts them on this (#12597).

We also split the browser into more processes, so a compromised one can reach less:

Diagram of the processes behind two tabs. Each renderer has its own image decoder, audio, media, and video decoder processes. A cross-site iframe gets its own renderer. Each tab's site has one network process, shared with its iframes. The compositor is shared by all tabs. Diagram of the processes behind two tabs. Each renderer has its own image decoder, audio, media, and video decoder processes. A cross-site iframe gets its own renderer. Each tab's site has one network process, shared with its iframes. The compositor is shared by all tabs.

  • Cross-site iframes get their own renderer by default (#12647), and so do cross-site popups (#12296).
  • Each top-level site gets its own network process, and the HTTP cache and third-party cookies are kept separate per site (#13144, #12424).
  • Each renderer has its own audio process (#12604) and image decoder (#12437).

Media and Windows

On Windows, video now plays and YouTube works (#12646, #13195). Hardware video decoding moved to its own process and now works on Linux through Vulkan (#12868). We also read MP4 files ourselves now instead of using FFmpeg, which fixes problems with seeking and buffering (#12641).

More C++ moved to Rust

LibJS’s runtime moved from C++ to Rust just before the JIT landed, so our JavaScript engine is now all Rust, apart from its flap interpreter and the garbage collector (#12492). The new Wasm engine is Rust as well. WebGL, 2D canvas, IndexedDB, Streams, and URL also moved over (#12699, #12935, #13287, #13083, #12998). We also deleted the C++ style computation, so style is now computed entirely in Rust (#12346).

Getting ready for alpha

Our first alpha is planned for later this year. This month we added:

  • Release builds: macOS archives, Linux tarballs, .deb and .rpm packages, and Flatpak bundles (#13176, #13313, #13340).
  • Crash reports: after a crash, you can review a report and choose to send it to us (#12298, #12342).
  • A welcome page to pick your tab layout, search engine, and ad blocking (#12333).
  • Reporting broken sites from inside the browser (#12880).

That’s it for October. Thanks for reading, and we’ll see you next month!

来源:Hacker News-首页 · ladybird.org