Safari 扩展 Popup 中的滚动迟缓问题
本文最后更新于:2026年8月7日 凌晨
前言
昨天在尝试为一个扩展程序增加 Safari 支持的时候,发现了一个神奇的问题,在 popup 中滚动感觉很迟缓。
就像是这样,滚动速度不仅缓慢,而且没有任何惯性效应。
如果在新标签页打开 popup 页面,你可以看到滚动要流畅的多
猜测
具体来说,复现步骤很简单
- 使用 JavaScript 写入大量内容产生滚动条,上面的示例中使用了一个相当简单的 for 循环 + ul list
- 打开 popup 弹窗,滚动就可以触发这个问题
1 | |
在此之前,我其实已经遇到了几个棘手的问题,包括
- popup 在切换页面时会出现白屏,或者一半黑一般白 [1]
- prefers-color-scheme 有时探测不到,导致系统暗色模式下 popup 仍然是白色背景 [2]
- 路由切换后滚动位置不归零
- 滚动没有弹簧效果
幸运的是,4 个表面上毫不相干的错误实际上指向同一个问题:popup 原生窗口会根据内容高度自动 resize,而在 chrome/firefox 中并没有什么问题,但 safari 似乎仍然有一些边缘的错误。
解决
在尝试解决的过程中,一开始并未意识到是 resize 导致的问题,我尝试了不少方法,包括
- 去掉嵌套滚动容器,改用文档级滚动:最初使用了 h-screen + flex-column,这是为了固定顶栏不跟随页面滚动而移出页面之外,所以在最初碰到切换页面再回来首页就白屏的问题时,以为是首页哪里的实现有问题
- 内联关键 CSS 抢跑加载:在这个过程中又发现页面的暗色模式支持出了 bug,最诡异的是,popup 里面是错误的,但单独打开 popup 在新标签页又是正确的,非常诡异
- TanStack Router 内置的 scrollRestoration: true:所以在之后注意到切换页面滚动距离和白屏的高度有关系之后,我认为是页面切换之后没有自动滚动到顶部,所以尝试了这个配置
- 固定 body 的宽高并在内部使用滚动:最后灵机一动想到了是否有可能是内容引起的 resize 导致的频繁渲染,进而导致的滚动缓慢问题,没想到一下子 4 个问题全被解决了
关键代码如下
1 | |
1 | |
所以 safari popup 到底发生了什么呢?我查询来自官方文档中的信息只有一个,来自 WebKit Blog - Safari 26.2 更新日志 中的这样一句描述:extension popups could open scrolled down and some websites could flicker during scrolling。
另外还找到两条相关但不完全对得上的线索:WebKit Bug 296056 报告了 iPadOS 26 上 popup 打开时滚动位置异常,已经修复,不过根因是 <dialog> 关闭后焦点恢复触发的滚动,跟这里的自动 resize 不是一回事;Apple Developer Forums 上的一个帖子 则直接印证了 resize-to-content 这套机制本身就不太可靠——有人报告 iPad 上 popup 容器撑高后再也缩不回去了。加起来看,这块至少不是我一个人遇到的边缘情况。
没有找到任何文档或 issue 把这 4 个现象和”根据内容自动 resize”这个根因关联起来,所以我把这次调试过程整理成了一份报告提交给了 Apple(FB24198765),同时也镜像发布到了专门收集 Safari 扩展 Feedback Assistant 报告的 lapcat/SafariExtensions 仓库 —— Feedback Assistant 本身是私有不可搜索的,这个仓库算是社区自发攒起来的公开备份。如果你也遇到过类似的问题,欢迎去那边 +1 或者补充你自己的复现场景。
结语
Safari 扩展在所有浏览器中都是一个异类,它强制扩展作为一个 app 封装和分发,也就是说,安装一个 Safari 扩展和安装一个 app 使用的安装包是一模一样的。即使不算扩展,Safari 浏览器对 Web 标准的支持也像是新时代的 IE,它如此糟糕,以至于 iOS 支持经常被视为一项痛苦的工作 – iOS 上所有浏览器都使用 webkit 内核,包括 Chrome 浏览器,Apple 禁止了浏览器使用自己的内核。
↩
,同样的现象在 Apple Developer Forums 上一个 2021 年的老帖子 里也有人报告过,至今没有回复。
↩