diff --git a/_posts/2025-11-14-october-in-servo.md b/_posts/2025-11-14-october-in-servo.md new file mode 100644 index 000000000..1cd6a76ef --- /dev/null +++ b/_posts/2025-11-14-october-in-servo.md @@ -0,0 +1,184 @@ +--- +layout: post +tags: blog +title: "October in Servo: better for the web, better for embedders, better for you" +date: 2025-11-14 +summary: Big changes to our webview API, improved macOS and Android builds, and now we’ve shipped AbortController, AbortSignal, and XPath. +categories: +--- + +Servo now supports several new web platform features: + +- **<source>** in **<video>** and **<audio>** ([@tharkum](https://github.com/tharkum), [#39717](https://github.com/servo/servo/pull/39717)) +- **CompressionStream** and **DecompressionStream** ([@kkoyung](https://github.com/kkoyung), [#39658](https://github.com/servo/servo/pull/39658)) +- **fetchLater()** ([@TimvdLippe](https://github.com/TimvdLippe), [#39547](https://github.com/servo/servo/pull/39547)) +- **Document.parseHTMLUnsafe()** ([@lukewarlow](https://github.com/lukewarlow), [#40246](https://github.com/servo/servo/pull/40246)) +- the **which** property on **UIEvent** ([@Taym95](https://github.com/Taym95), [#40109](https://github.com/servo/servo/pull/40109)) +- the **relatedTarget** property on **UIEvent** ([@TimvdLippe](https://github.com/TimvdLippe), [#40182](https://github.com/servo/servo/pull/40182)) +- **self.name** and **.onmessageerror** in dedicated workers ([@yerke](https://github.com/yerke), [#40156](https://github.com/servo/servo/pull/40156)) +- **name** and **areas** properties on **HTMLMapElement** ([@tharkum](https://github.com/tharkum), [#40133](https://github.com/servo/servo/pull/40133)) + +
+ servoshell nightly showing new support for CompressionStream and synthetic bold +
+ +**servoshell** for **macOS** now ships as **native Apple Silicon binaries** ([@jschwe](https://github.com/jschwe), [#39981](https://github.com/servo/servo/pull/39981)). +Building servoshell for macOS x86-64 still works for now, but is no longer officially supported by automated testing in CI (see *§ For developers*). + +In **servoshell** for **Android**, you can now enable **experimental mode** with just two taps ([@jdm](https://github.com/jdm), [#40054](https://github.com/servo/servo/pull/40054)), use the **software keyboard** ([@jdm](https://github.com/jdm), [#40009](https://github.com/servo/servo/pull/40009)), deliver **touch events** to web content ([@mrobinson](https://github.com/mrobinson), [#40240](https://github.com/servo/servo/pull/40240)), and dismiss the location field ([@jdm](https://github.com/jdm), [#40049](https://github.com/servo/servo/pull/40049)). +**Pinch zoom** is now fully supported in both Servo and **servoshell**, taking into account the locations of pinch inputs ([@mrobinson](https://github.com/mrobinson), [@atbrakhi](https://github.com/atbrakhi), [#40083](https://github.com/servo/servo/pull/40083)) and allowing keyboard scrolling when zoomed in ([@mrobinson](https://github.com/mrobinson), [@atbrakhi](https://github.com/atbrakhi), [#40108](https://github.com/servo/servo/pull/40108)). + +
+
+
+ +
+
+
+ +
+
+
+
servoshell on Android. Left: you can now turn on experimental mode in the settings menu. Right: we now support the soft keyboard and touch events.
+
+ +**AbortController** and **AbortSignal** are now **enabled by default** ([@jdm](https://github.com/jdm), [@TimvdLippe](https://github.com/TimvdLippe), [#40079](https://github.com/servo/servo/pull/40079), [#39943](https://github.com/servo/servo/pull/39943)), after implementing **AbortSignal.timeout()** ([@Taym95](https://github.com/Taym95), [#40032](https://github.com/servo/servo/pull/40032)) and fixing **throwIfAborted()** on **AbortSignal** ([@Taym95](https://github.com/Taym95), [#40224](https://github.com/servo/servo/pull/40224)). +If this is the first time you’ve heard of them, you might be surprised how important they are for real-world web compat! +[**Over 40%**](https://webstatus.dev/features/aborting) of Google Chrome page loads at least *check* if they are supported, and many popular websites including GitHub and Discord are broken without them. + +**XPath** is now **enabled by default** ([@simonwuelker](https://github.com/simonwuelker), [#40212](https://github.com/servo/servo/pull/40212)), after implementing **‘@attr/parent’ queries** ([@simonwuelker](https://github.com/simonwuelker), [#39749](https://github.com/servo/servo/pull/39749)), **Copy** > **XPath** in the **DevTools Inspector** ([@simonwuelker](https://github.com/simonwuelker), [#39892](https://github.com/servo/servo/pull/39892)), completely rewriting the parser ([@simonwuelker](https://github.com/simonwuelker), [#39977](https://github.com/servo/servo/pull/39977)), and landing several other fixes ([@simonwuelker](https://github.com/simonwuelker), [#40103](https://github.com/servo/servo/pull/40103), [#40105](https://github.com/servo/servo/pull/40105), [#40161](https://github.com/servo/servo/pull/40161), [#40167](https://github.com/servo/servo/pull/40167), [#39751](https://github.com/servo/servo/pull/39751), [#39764](https://github.com/servo/servo/pull/39764)). + +Servo now supports `new KeyboardEvent({keyCode})` and `({charCode})` ([@atbrakhi](https://github.com/atbrakhi), [#39590](https://github.com/servo/servo/pull/39590)), which is enough to get [**Speedometer 3.0**](https://browserbench.org/Speedometer3.0/) and [**3.1**](https://browserbench.org/Speedometer3.1/) working on macOS. + +
+ servoshell nightly showing Speedometer 3.1 running successfully on macOS +
+ +**ImageData** can now be sent over **postMessage()** and **structuredClone()** ([@Gae24](https://github.com/Gae24), [#40084](https://github.com/servo/servo/pull/40084)). + +## Layout engine + +Our layout engine can now render text in **synthetic bold** ([@minghuaw](https://github.com/minghuaw), [@mrobinson](https://github.com/mrobinson), [#39519](https://github.com/servo/servo/pull/39519), [#39681](https://github.com/servo/servo/pull/39681), [#39633](https://github.com/servo/servo/pull/39633), [#39691](https://github.com/servo/servo/pull/39691), [#39713](https://github.com/servo/servo/pull/39713)), and now selects more appropriate fallback fonts for **Kanji** in **Japanese text** ([@arayaryoma](https://github.com/arayaryoma), [#39608](https://github.com/servo/servo/pull/39608)). + +**‘initial-scale’** now does the right thing in **<meta name=viewport>** ([@atbrakhi](https://github.com/atbrakhi), [@shubhamg13](https://github.com/shubhamg13), [@mrobinson](https://github.com/mrobinson), [#40055](https://github.com/servo/servo/pull/40055)). + +We’ve improved the way we handle **‘border-radius’** ([@Loirooriol](https://github.com/Loirooriol), [#39571](https://github.com/servo/servo/pull/39571)) and **margin collapsing** ([@Loirooriol](https://github.com/Loirooriol), [#36322](https://github.com/servo/servo/pull/36322)). +While they’re fairly unassuming fixes on the surface, both of them allowed us to **find interop issues** in the big incumbent engines ([@Loirooriol](https://github.com/Loirooriol), [#39540](https://github.com/servo/servo/issues/39540), [#36321](https://github.com/servo/servo/issues/36321)) and **help improve web standards** ([@noamr](https://github.com/noamr), [@Loirooriol](https://github.com/Loirooriol), [csswg-drafts#12961](https://github.com/w3c/csswg-drafts/issues/12961), [csswg-drafts#12218](https://github.com/w3c/csswg-drafts/issues/12218)). + +In other words, Servo is good for the web, even if you’re not using it yet! + +## Embedding and ecosystem + +Our HTML-compatible **XPath** implementation now lives in its [own](https://github.com/servo/servo/tree/cd4c032908211fa2c26df550f6766080d1d28969/components/xpath) [crate](https://doc.servo.org/xpath/), and it’s no longer limited to the Servo DOM ([@simonwuelker](https://github.com/simonwuelker), [#39546](https://github.com/servo/servo/pull/39546)). +We don’t have any specific plans to release this as a standalone library just yet, but please let us know if you have a use case that would benefit from this! + +You can now **take screenshots** of webviews with [WebView](https://doc.servo.org/servo/struct.WebView.html)::[take_screenshot](https://doc.servo.org/servo/struct.WebView.html#method.take_screenshot) ([@mrobinson](https://github.com/mrobinson), [@delan](https://github.com/delan), [#39583](https://github.com/servo/servo/pull/39583)). + +Historically Servo has struggled with situations causing **100% CPU usage** or **unnecessary work on every tick** of the event loop, whenever a page is considered “active” or “animating” ([#25305](https://github.com/servo/servo/issues/25305), [#3406](https://github.com/servo/servo/issues/3406)). +We had since throttled animations ([@mrobinson](https://github.com/mrobinson), [#37169](https://github.com/servo/servo/pull/37169)) and reflows ([@mrobinson](https://github.com/mrobinson), [@Loirooriol](https://github.com/Loirooriol), [#38431](https://github.com/servo/servo/pull/38431)), but only to fixed rates of 120 Hz and 60 Hz respectively. + +But starting this month, you can run Servo with **vsync**, thanks to the **[RefreshDriver](https://doc.servo.org/servo/trait.RefreshDriver.html) trait** ([@coding-joedow](https://github.com/coding-joedow), [@mrobinson](https://github.com/mrobinson), [#39072](https://github.com/servo/servo/pull/39072)), which allows embedders to tell Servo *when* to start rendering each frame. +The [default driver](https://doc.servo.org/compositing/refresh_driver/struct.TimerRefreshDriver.html) continues to run at 120 Hz, but you can define and install your own with [ServoBuilder](https://doc.servo.org/servo/struct.ServoBuilder.html)::[refresh_driver](https://doc.servo.org/servo/struct.ServoBuilder.html#method.refresh_driver). + +### Breaking changes + +Servo’s embedding API has had a few **breaking changes**: + +- [Opts](https://doc.servo.org/servo_config/opts/struct.Opts.html)::wait_for_stable_image was **removed**; to wait for a stable image, call [WebView](https://doc.servo.org/servo/struct.WebView.html)::[**take_screenshot**](https://doc.servo.org/servo/struct.WebView.html#method.take_screenshot) instead ([@mrobinson](https://github.com/mrobinson), [@delan](https://github.com/delan), [#39583](https://github.com/servo/servo/pull/39583)). + +- [MouseButtonAction](https://doc.servo.org/servo/enum.MouseButtonAction.html)::Click was **removed**; use [**Down**](https://doc.servo.org/servo/enum.MouseButtonAction.html#variant.Down) followed by [**Up**](https://doc.servo.org/servo/enum.MouseButtonAction.html#variant.Up). [Click events](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event) need to be *derived* from mouse button downs and ups to ensure that they are fired correctly ([@mrobinson](https://github.com/mrobinson), [#39705](https://github.com/servo/servo/pull/39705)). + +- **Scrolling is now *derived*** from mouse wheel events. When you have mouse wheel input to forward to Servo, you should now call [WebView](https://doc.servo.org/servo/struct.WebView.html)::[notify_input_event](https://doc.servo.org/servo/struct.WebView.html#method.notify_input_event) *only*, not [notify_scroll_event](https://doc.servo.org/servo/struct.WebView.html#method.notify_scroll_event) ([@mrobinson](https://github.com/mrobinson), [@atbrakhi](https://github.com/atbrakhi), [#40269](https://github.com/servo/servo/pull/40269)). + +- [WebView](https://doc.servo.org/servo/struct.WebView.html)::set_pinch_zoom was renamed to [pinch_zoom](https://doc.servo.org/servo/struct.WebView.html#method.pinch_zoom), to better reflect that **pinch zoom** is always **relative** ([@mrobinson](https://github.com/mrobinson), [@atbrakhi](https://github.com/atbrakhi), [#39868](https://github.com/servo/servo/pull/39868)). + +We’ve improved **page zoom** in our webview API ([@atbrakhi](https://github.com/atbrakhi), [@mrobinson](https://github.com/mrobinson), [@shubhamg13](https://github.com/shubhamg13), [#39738](https://github.com/servo/servo/pull/39738)), which includes some **breaking changes**: + +- [WebView](https://doc.servo.org/servo/struct.WebView.html)::set_zoom was renamed to [set_page_zoom](https://doc.servo.org/servo/struct.WebView.html#method.set_page_zoom), and it now takes an **absolute** zoom value. This makes it idempotent, but it means if you want relative zoom, you’ll have to multiply the zoom values yourself. +- Use the new [WebView](https://doc.servo.org/servo/struct.WebView.html)::[page_zoom](https://doc.servo.org/servo/struct.WebView.html#method.page_zoom) method to get the current zoom value. +- [WebView](https://doc.servo.org/servo/struct.WebView.html)::reset_zoom was removed; use `set_page_zoom(1.0)` instead. + +Some **breaking changes** were also needed to give embedders a more powerful way to **share input events with webviews** ([@mrobinson](https://github.com/mrobinson), [#39720](https://github.com/servo/servo/pull/39720)). +Often both your app and the pages in your webviews may be interested in knowing when users press a key. +Servo handles these situations by asking the embedder for all potentially useful input events, then echoing some of them back: + +1. Embedder calls [WebView](https://doc.servo.org/servo/struct.WebView.html)::[notify_input_event](https://doc.servo.org/servo/struct.WebView.html#method.notify_input_event) to tell Servo about an input event, then web content (and Servo) can handle the event. +2. Servo calls [WebViewDelegate](https://doc.servo.org/servo/trait.WebViewDelegate.html)::notify_keyboard_event to tell the embedder about keyboard events that were neither [canceled by scripts](https://dom.spec.whatwg.org/#dom-event-preventdefault) nor handled by Servo itself. The event details is included in the arguments. + +Embedders had **no way of knowing *when*** non-keyboard input events, or keyboard events that were canceled or handled by Servo, have **completed all of their effects in Servo**. +This was good enough for servoshell’s overridable key bindings, but not for WebDriver, where commands like [Perform Actions](https://w3c.github.io/webdriver/#perform-actions) need to reliably wait for input events to be handled. +To solve these problems, we’ve replaced notify_keyboard_event with [notify_input_event_handled](https://doc.servo.org/servo/trait.WebViewDelegate.html#method.notify_input_event_handled): + +1. Embedder calls [WebView](https://doc.servo.org/servo/struct.WebView.html)::[notify_input_event](https://doc.servo.org/servo/struct.WebView.html#method.notify_input_event) to tell Servo about an input event, then web content (and Servo) can handle the event. **This now returns an [InputEventId](https://doc.servo.org/servo/struct.InputEventId.html)**, allowing embedders to remember input events that they still care about for step 2. +2. **Servo calls [WebViewDelegate](https://doc.servo.org/servo/trait.WebViewDelegate.html)::[notify_input_event_handled](https://doc.servo.org/servo/trait.WebViewDelegate.html#method.notify_input_event_handled)** to tell the embedder about **every input event, when Servo has finished handling it**. The event details are **not included** in the arguments, but you can use the [InputEventId](https://doc.servo.org/servo/struct.InputEventId.html) to look up the details in the embedder. + +## Perf and stability + +Servo now does **zero unnecessary layout work** when **updating canvases** and **animated images**, thanks to a new “UpdatedImageData” layout mode ([@mrobinson](https://github.com/mrobinson), [@mukilan](https://github.com/mukilan), [#38991](https://github.com/servo/servo/pull/38991)). + +We’ve fixed crashes when clicking on web content on Android ([@mrobinson](https://github.com/mrobinson), [#39771](https://github.com/servo/servo/pull/39771)), and when running Servo on platforms where JIT is forbidden ([@jschwe](https://github.com/jschwe), [@sagudev](https://github.com/sagudev), [#40071](https://github.com/servo/servo/pull/40071), [#40130](https://github.com/servo/servo/pull/40130)). + +## For developers + +CI builds for **pull requests** should now take **70% less time**, since they now run on self-hosted CI runners ([@delan](https://github.com/delan), [#39900](https://github.com/servo/servo/pull/39900), [#39915](https://github.com/servo/servo/pull/39915)). +**Bencher builds** for runtime benchmarking now run on our new [dedicated](https://ci3.servo.org) [servers](https://ci4.servo.org), so our [Speedometer](https://bencher.dev/perf/servo?branches=52e1e9bb-959c-4171-a53d-e06bd694a6c1&testbeds=d742c702-3842-4108-9d0c-2db74e57599a%2Cd5e49dbe-b866-453a-b6ac-1cc2c452b846&benchmarks=0df0380f-9809-45bc-b525-b6ad9d5fbe91%2Cf7c6adb5-e702-42bc-902c-d2154b1e2428&measures=e71c685b-9ce9-4abc-a55d-a1de2ffe04fb&start_time=1733011200000&end_time=1764460800000) and Dromaeo data should now be more accurate and less noisy ([@delan](https://github.com/delan), [#39272](https://github.com/servo/servo/pull/39272)). + +We’ve now switched all of our macOS builds to run on arm64 ([@sagudev](https://github.com/sagudev), [@jschwe](https://github.com/jschwe), [#38460](https://github.com/servo/servo/pull/38460), [#39968](https://github.com/servo/servo/pull/39968)). +This helps back our macOS releases with thorough automated testing on the same architecture as our releases, but we can’t run them on self-hosted CI runners yet, so they may be slower for the time being. + +Work is underway to set up faster macOS arm64 runners on our own servers ([@delan](https://github.com/delan), [ci-runners#64](https://github.com/servo/ci-runners/pull/64)), funded by your donations. Speaking of which! + +## Donations + +Thanks again for your generous support! +We are now receiving **5753 USD/month** (+1.7% over September) in recurring donations. + +This helps us cover the cost of our **[speedy](https://ci0.servo.org) [CI](https://ci1.servo.org) [and](https://ci2.servo.org) [benchmarking](https://ci3.servo.org) [servers](https://ci4.servo.org)**, one of our latest **[Outreachy interns](https://www.outreachy.org/alums/2025-06/#:~:text=Servo)**, and funding **[maintainer work]({{ '/blog/2025/09/17/your-donations-at-work-funding-jdm/' | url }})** that helps more people contribute to Servo. +Keep an eye out for [further CI improvements](https://github.com/servo/servo/issues/38141) in the coming months, including [faster macOS arm64 builds](https://github.com/servo/ci-runners/pull/64) and [ten-minute WPT builds](https://github.com/servo/ci-runners/issues/21). + +Servo is also on [thanks.dev](https://thanks.dev), and already **28 GitHub users** (same as September) that depend on Servo are sponsoring us there. +If you use Servo libraries like [url](https://crates.io/crates/url/reverse_dependencies), [html5ever](https://crates.io/crates/html5ever/reverse_dependencies), [selectors](https://crates.io/crates/selectors/reverse_dependencies), or [cssparser](https://crates.io/crates/cssparser/reverse_dependencies), signing up for [thanks.dev](https://thanks.dev) could be a good way for you (or your employer) to give back to the community. + +
+
+
5753 USD/month
+
+
+
10000
+
+ +
+ +Use of donations is decided transparently via the Technical Steering Committee’s public **[funding request process](https://github.com/servo/project/blob/main/FUNDING_REQUEST.md)**, and active proposals are tracked in [servo/project#187](https://github.com/servo/project/issues/187). +For more details, head to our [Sponsorship page]({{ '/sponsorship/' | url }}). + + + + diff --git a/assets/img/blog/2025-11-diffie.png b/assets/img/blog/2025-11-diffie.png new file mode 100644 index 000000000..dedc96275 Binary files /dev/null and b/assets/img/blog/2025-11-diffie.png differ diff --git a/assets/img/blog/2025-11-experimental.jpg b/assets/img/blog/2025-11-experimental.jpg new file mode 100644 index 000000000..a879e0334 Binary files /dev/null and b/assets/img/blog/2025-11-experimental.jpg differ diff --git a/assets/img/blog/2025-11-experimental.webm b/assets/img/blog/2025-11-experimental.webm new file mode 100644 index 000000000..86c8c0d13 Binary files /dev/null and b/assets/img/blog/2025-11-experimental.webm differ diff --git a/assets/img/blog/2025-11-input.jpg b/assets/img/blog/2025-11-input.jpg new file mode 100644 index 000000000..031837d31 Binary files /dev/null and b/assets/img/blog/2025-11-input.jpg differ diff --git a/assets/img/blog/2025-11-input.webm b/assets/img/blog/2025-11-input.webm new file mode 100644 index 000000000..803f2ac81 Binary files /dev/null and b/assets/img/blog/2025-11-input.webm differ diff --git a/assets/img/blog/2025-11-speedometer-small.png b/assets/img/blog/2025-11-speedometer-small.png new file mode 100644 index 000000000..a503e9ee3 Binary files /dev/null and b/assets/img/blog/2025-11-speedometer-small.png differ diff --git a/assets/img/blog/2025-11-speedometer.png b/assets/img/blog/2025-11-speedometer.png new file mode 100644 index 000000000..23545685b Binary files /dev/null and b/assets/img/blog/2025-11-speedometer.png differ diff --git a/assets/img/blog/2025-11-speedometer0.png b/assets/img/blog/2025-11-speedometer0.png new file mode 100644 index 000000000..32526f6bc Binary files /dev/null and b/assets/img/blog/2025-11-speedometer0.png differ diff --git a/assets/img/blog/2025-11-speedometer1.png b/assets/img/blog/2025-11-speedometer1.png new file mode 100644 index 000000000..b1069698e Binary files /dev/null and b/assets/img/blog/2025-11-speedometer1.png differ diff --git a/assets/img/blog/2025-11-speedometer2.png b/assets/img/blog/2025-11-speedometer2.png new file mode 100644 index 000000000..b75974a73 Binary files /dev/null and b/assets/img/blog/2025-11-speedometer2.png differ diff --git a/assets/img/blog/2025-11-speedometer3.png b/assets/img/blog/2025-11-speedometer3.png new file mode 100644 index 000000000..5bce9166c Binary files /dev/null and b/assets/img/blog/2025-11-speedometer3.png differ