{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreig2jr7opxxskdgx6yklsdpamlmkunajjlxyrkfziut5ljmc46phna",
"uri": "at://did:plc:qp37y62idugoomg4hj4hfukc/app.bsky.feed.post/3m5nxdnc6kkp2"
},
"path": "/blog/2025/11/14/october-in-servo/",
"publishedAt": "2026-06-02T20:02:48.987Z",
"site": "https://servo.org",
"tags": [
"@tharkum",
"39717",
"@kkoyung",
"39658",
"@TimvdLippe",
"39547",
"@lukewarlow",
"40246",
"@Taym95",
"40109",
"40182",
"@yerke",
"40156",
"40133",
"@jschwe",
"39981",
"§ For developers",
"@jdm",
"40054",
"40009",
"@mrobinson",
"40240",
"40049",
"@atbrakhi",
"40083",
"40108",
"40079",
"39943",
"40032",
"40224",
"Over 40%",
"@simonwuelker",
"40212",
"39749",
"39892",
"39977",
"40103",
"40105",
"40161",
"40167",
"39751",
"39764",
"39590",
"Speedometer 3.0",
"3.1",
"@Gae24",
"40084",
"@minghuaw",
"39519",
"39681",
"39633",
"39691",
"39713",
"@arayaryoma",
"39608",
"@shubhamg13",
"40055",
"@Loirooriol",
"39571",
"36322",
"39540",
"36321",
"@noamr",
"csswg-drafts#12961",
"csswg-drafts#12218",
"own",
"crate",
"39546",
"WebView",
"take_screenshot",
"@delan",
"39583",
"25305",
"3406",
"37169",
"38431",
"RefreshDriver",
"@coding-joedow",
"39072",
"default driver",
"ServoBuilder",
"refresh_driver",
"Opts",
"MouseButtonAction",
"Down",
"Up",
"Click events",
"39705",
"notify_input_event",
"notify_scroll_event",
"40269",
"pinch_zoom",
"39868",
"39738",
"set_page_zoom",
"page_zoom",
"39720",
"WebViewDelegate",
"canceled by scripts",
"Perform Actions",
"notify_input_event_handled",
"InputEventId",
"@mukilan",
"38991",
"39771",
"@sagudev",
"40071",
"40130",
"39900",
"39915",
"dedicated",
"servers",
"Speedometer",
"39272",
"38460",
"39968",
"ci-runners#64",
"speedy",
"CI",
"and",
"benchmarking",
"Outreachy interns",
"maintainer work",
"further CI improvements",
"faster macOS arm64 builds",
"ten-minute WPT builds",
"thanks.dev",
"url",
"html5ever",
"selectors",
"cssparser",
"funding request process",
"servo/project#187",
"Sponsorship page",
"@attr"
],
"textContent": "Servo now supports several new web platform features:\n\n * **< source>** in **< video>** and **< audio>** (@tharkum, #39717)\n * **CompressionStream** and **DecompressionStream** (@kkoyung, #39658)\n * **fetchLater()** (@TimvdLippe, #39547)\n * **Document.parseHTMLUnsafe()** (@lukewarlow, #40246)\n * the **which** property on **UIEvent** (@Taym95, #40109)\n * the **relatedTarget** property on **UIEvent** (@TimvdLippe, #40182)\n * **self.name** and **.onmessageerror** in dedicated workers (@yerke, #40156)\n * **name** and **areas** properties on **HTMLMapElement** (@tharkum, #40133)\n\n\n\n**servoshell** for **macOS** now ships as **native Apple Silicon binaries** (@jschwe, #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_).\n\nIn **servoshell** for **Android** , you can now enable **experimental mode** with just two taps (@jdm, #40054), use the **software keyboard** (@jdm, #40009), deliver **touch events** to web content (@mrobinson, #40240), and dismiss the location field (@jdm, #40049). **Pinch zoom** is now fully supported in both Servo and **servoshell** , taking into account the locations of pinch inputs (@mrobinson, @atbrakhi, #40083) and allowing keyboard scrolling when zoomed in (@mrobinson, @atbrakhi, #40108).\n\nservoshell on Android showing GitHub loaded with an internal error, then enabling experimental mode in the settings menu, then reloading the page successfully (click to pause)\n\n▶\n\nservoshell on Android showing a page that opens the software keyboard and listens for touch events (click to pause)\n\n▶\n\nservoshell on Android. **Left:** you can now turn on experimental mode in the settings menu. **Right:** we now support the soft keyboard and touch events.\n\n**AbortController** and **AbortSignal** are now **enabled by default** (@jdm, @TimvdLippe, #40079, #39943), after implementing **AbortSignal.timeout()** (@Taym95, #40032) and fixing **throwIfAborted()** on **AbortSignal** (@Taym95, #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% of Google Chrome page loads at least _check_ if they are supported, and many popular websites including GitHub and Discord are broken without them.\n\n**XPath** is now **enabled by default** (@simonwuelker, #40212), after implementing **‘@attr/parent’ queries** (@simonwuelker, #39749), **Copy** > **_X_ Path** in the **DevTools Inspector** (@simonwuelker, #39892), completely rewriting the parser (@simonwuelker, #39977), and landing several other fixes (@simonwuelker, #40103, #40105, #40161, #40167, #39751, #39764).\n\nServo now supports `new KeyboardEvent({keyCode})` and `({charCode})` (@atbrakhi, #39590), which is enough to get Speedometer 3.0 and 3.1 working on macOS.\n\n**ImageData** can now be sent over **postMessage()** and **structuredClone()** (@Gae24, #40084).\n\n## Layout engine \n\nOur layout engine can now render text in **synthetic bold** (@minghuaw, @mrobinson, #39519, #39681, #39633, #39691, #39713), and now selects more appropriate fallback fonts for **Kanji** in **Japanese text** (@arayaryoma, #39608).\n\n**‘initial-scale’** now does the right thing in **< meta name=viewport>** (@atbrakhi, @shubhamg13, @mrobinson, #40055).\n\nWe’ve improved the way we handle **‘border-radius’** (@Loirooriol, #39571) and **margin collapsing** (@Loirooriol, #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, #39540, #36321) and **help improve web standards** (@noamr, @Loirooriol, csswg-drafts#12961, csswg-drafts#12218).\n\nIn other words, Servo is good for the web, even if you’re not using it yet!\n\n## Embedding and ecosystem \n\nOur HTML-compatible **XPath** implementation now lives in its own crate, and it’s no longer limited to the Servo DOM (@simonwuelker, #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!\n\nYou can now **take screenshots** of webviews with `WebView::take_screenshot` (@mrobinson, @delan, #39583).\n\nHistorically 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, #3406). We had since throttled animations (@mrobinson, #37169) and reflows (@mrobinson, @Loirooriol, #38431), but only to fixed rates of 120 Hz and 60 Hz respectively.\n\nBut starting this month, you can run Servo with **vsync** , thanks to the **`RefreshDriver` trait** (@coding-joedow, @mrobinson, #39072), which allows embedders to tell Servo _when_ to start rendering each frame. The default driver continues to run at 120 Hz, but you can define and install your own with `ServoBuilder::refresh_driver`.\n\n### Breaking changes \n\nServo’s embedding API has had a few **breaking changes** :\n\n * `Opts::wait_for_stable_image` was **removed** ; to wait for a stable image, call `WebView::take_screenshot` instead (@mrobinson, @delan, #39583).\n\n * `MouseButtonAction::Click` was **removed** ; use `Down` followed by `Up`. Click events need to be _derived_ from mouse button downs and ups to ensure that they are fired correctly (@mrobinson, #39705).\n\n * **Scrolling is now _derived_** from mouse wheel events. When you have mouse wheel input to forward to Servo, you should now call `WebView::notify_input_event` _only_ , not `notify_scroll_event` (@mrobinson, @atbrakhi, #40269).\n\n * `WebView::set_pinch_zoom` was renamed to `pinch_zoom`, to better reflect that **pinch zoom** is always **relative** (@mrobinson, @atbrakhi, #39868).\n\n\n\n\nWe’ve improved **page zoom** in our webview API (@atbrakhi, @mrobinson, @shubhamg13, #39738), which includes some **breaking changes** :\n\n * `WebView::set_zoom` was renamed to `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.\n * Use the new `WebView::page_zoom` method to get the current zoom value.\n * `WebView::reset_zoom` was removed; use `set_page_zoom(1.0)` instead.\n\n\n\nSome **breaking changes** were also needed to give embedders a more powerful way to **share input events with webviews** (@mrobinson, #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:\n\n 1. Embedder calls `WebView::notify_input_event` to tell Servo about an input event, then web content (and Servo) can handle the event.\n 2. Servo calls `WebViewDelegate::notify_keyboard_event` to tell the embedder about keyboard events that were neither canceled by scripts nor handled by Servo itself. The event details is included in the arguments.\n\n\n\nEmbedders 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 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`:\n\n 1. Embedder calls `WebView::notify_input_event` to tell Servo about an input event, then web content (and Servo) can handle the event. **This now returns an`InputEventId`**, allowing embedders to remember input events that they still care about for step 2.\n 2. **Servo calls`WebViewDelegate::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` to look up the details in the embedder.\n\n\n\n## Perf and stability \n\nServo now does **zero unnecessary layout work** when **updating canvases** and **animated images** , thanks to a new “UpdatedImageData” layout mode (@mrobinson, @mukilan, #38991).\n\nWe’ve fixed crashes when clicking on web content on Android (@mrobinson, #39771), and when running Servo on platforms where JIT is forbidden (@jschwe, @sagudev, #40071, #40130).\n\n## For developers \n\nCI builds for **pull requests** should now take **70% less time** , since they now run on self-hosted CI runners (@delan, #39900, #39915). **Bencher builds** for runtime benchmarking now run on our new dedicated servers, so our Speedometer and Dromaeo data should now be more accurate and less noisy (@delan, #39272).\n\nWe’ve now switched all of our macOS builds to run on arm64 (@sagudev, @jschwe, #38460, #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.\n\nWork is underway to set up faster macOS arm64 runners on our own servers (@delan, ci-runners#64), funded by your donations. Speaking of which!\n\n## Donations \n\nThanks again for your generous support! We are now receiving **5753 USD/month** (+1.7% over September) in recurring donations.\n\nThis helps us cover the cost of our **speedy CI and benchmarking servers** , one of our latest **Outreachy interns** , and funding **maintainer work** that helps more people contribute to Servo. Keep an eye out for further CI improvements in the coming months, including faster macOS arm64 builds and ten-minute WPT builds.\n\nServo is also on 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, html5ever, selectors, or cssparser, signing up for thanks.dev could be a good way for you (or your employer) to give back to the community.\n\n**5753** USD/month\n\n**10000**\n\nUse of donations is decided transparently via the Technical Steering Committee’s public **funding request process** , and active proposals are tracked in servo/project#187. For more details, head to our Sponsorship page.",
"title": "October in Servo: better for the web, better for embedders, better for you",
"updatedAt": "2025-11-14T00:00:00.000Z"
}