|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Web-Perf Wednesday 010 – Safari Keeps Scrolled Content in Place" |
| 4 | +date: 2026-09-23 12:00:00 +0100 |
| 5 | +categories: |
| 6 | + - Web Performance |
| 7 | +tags: |
| 8 | + - Safari |
| 9 | + - Caching |
| 10 | + - Tooling |
| 11 | +show_taxonomy: true |
| 12 | +main: "" |
| 13 | +meta: "Safari 27 adds scroll anchoring, tighter HTTP caching, and static Service Worker routes, while Chrome improves performance tooling." |
| 14 | +--- |
| 15 | + |
| 16 | +A fair amount has changed since last Wednesday, and Safari accounts for most |
| 17 | +of what matters here. Safari 27 can now keep scrolled content in place when |
| 18 | +something is inserted above it, follows several more HTTP caching rules, and |
| 19 | +lets Service Workers declare routes that bypass their own fetch handlers. |
| 20 | +Chrome DevTools has also completed its soft-navigation workflow and added |
| 21 | +reproducible CPU-tier controls. The common thread is browser behaviour that can |
| 22 | +change a user’s experience without a site deployment. |
| 23 | + |
| 24 | +## Safari Keeps Scrolled Content in Place |
| 25 | + |
| 26 | +Safari 27 adds [scroll anchoring](https://webkit.org/blog/18325/webkit-features-for-safari-27-0/), |
| 27 | +which adjusts the scroll position when content is inserted above the part of a |
| 28 | +page someone is currently viewing. An image, advert, comment, or other late |
| 29 | +content can still change the document’s layout, but the browser compensates so |
| 30 | +that the text or interface already on screen stays in place. |
| 31 | + |
| 32 | +This brings Safari into a part of the platform that Chrome and Firefox users |
| 33 | +have had for some time. The [CSS Scroll Anchoring |
| 34 | +specification](https://drafts.csswg.org/css-scroll-anchoring/) describes how a |
| 35 | +scrolling box selects an anchor node and adjusts its offset after a layout |
| 36 | +change. It only applies once the box has been scrolled away from its origin, |
| 37 | +and `overflow-anchor: none` lets developers opt a container or subtree out. |
| 38 | +The default is `auto`, so most sites receive the new behaviour without making |
| 39 | +a code change. |
| 40 | + |
| 41 | +That default is helpful, particularly for long articles, feeds, product lists, |
| 42 | +and ad-supported pages where content can arrive above the reader. It also |
| 43 | +creates a clear before-and-after point for Safari testing and field data. |
| 44 | +Safari 27 users may experience a steadier page than Safari 26 users even though |
| 45 | +the application, advert stack, and reserved space are identical. |
| 46 | + |
| 47 | +Scroll anchoring doesn’t reserve space or stop the layout from changing. Pages |
| 48 | +should still give images dimensions, allocate space for adverts and embeds, |
| 49 | +and avoid inserting avoidable content above the viewport. Those fixes help |
| 50 | +from the first paint and across browsers; anchoring applies later, once the |
| 51 | +user has scrolled, and deals with a narrower symptom. |
| 52 | + |
| 53 | +There are also interactions to test. Safari 27’s release notes contain fixes |
| 54 | +for anchoring around smooth scrolling, rubber-banding, scroll snapping, and |
| 55 | +dynamic `scroll-padding`. Sites with infinite feeds, sticky controls, in-page |
| 56 | +navigation, or their own scroll-compensation JavaScript should compare Safari |
| 57 | +26 and 27 on real journeys rather than assuming the default can’t disturb |
| 58 | +existing behaviour. |
| 59 | + |
| 60 | +One useful diagnostic is to replay the same journey with the default, then |
| 61 | +disable anchoring only on the suspected scroller. That shows whether browser |
| 62 | +compensation is hiding a page-level shift or causing a second correction. Keep |
| 63 | +the opt-out narrow: the specification makes `none` exclude the element and its |
| 64 | +descendants for that scrolling box, so a broad rule can remove the protection |
| 65 | +from much more of the page than intended. Record the Safari version, selector, |
| 66 | +and scroll position with the result so somebody else can reproduce it. |
| 67 | + |
| 68 | +I’d segment Safari RUM and replay data by major version, then run a |
| 69 | +[journey-level performance test](/performance-audits/) on pages that inject |
| 70 | +content after the reader has moved down the page. Look for sudden scroll |
| 71 | +offsets, double compensation, missed anchors, and controls that end up under a |
| 72 | +sticky header. A quieter experience is useful; knowing whether the browser or |
| 73 | +the site produced it is what makes the result actionable. |
| 74 | + |
| 75 | +## Safari Tightens Its HTTP Cache Behaviour |
| 76 | + |
| 77 | +The same Safari release fixes several HTTP-cache behaviours. WebKit now says |
| 78 | +it honours the `max-age`, `min-fresh`, and `no-store` request directives, |
| 79 | +updates cached entries with `Content-*` headers from `304` responses, honours |
| 80 | +`Cache-Control: public` on responses with unknown status codes, and stores |
| 81 | +responses with explicit freshness across all status codes. |
| 82 | + |
| 83 | +The details need a little care. [RFC |
| 84 | +9111](https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.1) defines request |
| 85 | +directives as advisory, while response directives carry different |
| 86 | +requirements. Even so, Safari changing its implementation can alter cache |
| 87 | +reuse, revalidation, and network traffic after an operating-system update. If |
| 88 | +a Safari cohort suddenly behaves differently, compare requests and response |
| 89 | +headers before attributing the movement to the CDN or application. A focused |
| 90 | +[caching review](/consultancy/) should compare the behaviour before and after |
| 91 | +the Safari update. |
| 92 | + |
| 93 | +## Static Routes Can Avoid Service Worker Startup |
| 94 | + |
| 95 | +Safari 27 also supports the [Service Worker static routing |
| 96 | +API](https://www.w3.org/TR/service-workers/#dom-installevent-addroutes). During |
| 97 | +installation, `event.addRoutes()` can declare conditions based on URL, request |
| 98 | +method, mode, destination, or Worker state, then choose the network, a cache, |
| 99 | +the fetch handler, or a race between network and handler. |
| 100 | + |
| 101 | +For requests that can go straight to the network or a named cache, the browser |
| 102 | +can avoid starting the Worker and dispatching a `fetch` event. That removes |
| 103 | +bootstrap and JavaScript work from routes whose behaviour is already known. |
| 104 | +Start with a small, measurable route set, retain the ordinary fetch path for |
| 105 | +unsupported browsers, and compare cold navigations as well as warm ones; a |
| 106 | +[PWA performance review](/performance-audits/) should prove that the declared |
| 107 | +route matches the application’s real caching and offline requirements. |
| 108 | + |
| 109 | +## Chrome DevTools Makes Comparisons More Reproducible |
| 110 | + |
| 111 | +[Chrome DevTools’ latest release |
| 112 | +summary](https://developer.chrome.com/blog/new-in-devtools-october-2026/) adds |
| 113 | +soft-navigation analysis to Performance Insights, completing the workflow that |
| 114 | +already covered Live Metrics and trace views. DevTools can also configure a |
| 115 | +calibrated CPU performance tier through the Chrome DevTools Protocol, rather |
| 116 | +than relying only on an arbitrary slowdown multiplier tied to the machine |
| 117 | +running the test. |
| 118 | + |
| 119 | +Both additions make comparisons easier to defend. Developers can now inspect |
| 120 | +a soft navigation and its insights in the same place, while automation can |
| 121 | +target a repeatable hardware tier across different developer and CI machines. |
| 122 | +Teams should record the Chrome version, selected tier, trace settings, and |
| 123 | +application build with every result. A [performance workshop](/workshops/) can |
| 124 | +then turn the tooling into a shared test method instead of a collection of |
| 125 | +screenshots produced under unknown conditions. |
| 126 | + |
| 127 | +## Need Help Explaining a Browser-Led Change? |
| 128 | + |
| 129 | +When a browser release changes scrolling, caching, or Service Worker routing, |
| 130 | +the effect can resemble an application improvement or regression even when the |
| 131 | +site itself hasn’t deployed. I can help separate browser behaviour from site |
| 132 | +behaviour, compare the right cohorts, and turn the difference into a test or |
| 133 | +fix that the team can own. |
| 134 | + |
| 135 | +A Safari version split, an unexpected cache trace, or one PWA navigation that |
| 136 | +feels slower than it should is enough to begin. If you’d like help working out |
| 137 | +what changed and what to do next, [get in touch](/contact/). |
| 138 | + |
| 139 | +{% include web-perf-wednesdays.md %} |
0 commit comments