为什么我的Google Chrome扩展程序在外部显示器上的弹出界面很卡顿,但在笔记本电脑的原生屏幕上却不会呢?

17

我正在制作一个Chrome扩展程序,其中包括一个简单的弹出窗口页面,当您点击扩展图标时会出现该页面。此弹出窗口页面由一些简单的HTML、CSS和jQuery代码组成,没有什么花哨的东西。

JS代码似乎运行得很好,但是在外部显示器上与其交互时,CSS的悬停、过渡和动画效果非常卡顿(延迟长达5秒)。

其他所有方面都运行良好,我可以看到JavaScript正在按预期执行。只有上述提到的CSS渲染问题。

有趣的是,如果我将同一浏览器窗口拖到笔记本电脑的原生屏幕上,问题就消失了。一切都很顺畅。将同一窗口拖到我的2个外部显示器上,噼里啪啦!卡顿一个城市......

我已经在朋友的电脑上进行了测试,他遇到了同样的问题。在原生屏幕上运行良好,在外部显示器上卡顿。到目前为止,看起来这个问题只发生在Mac电脑上。通过排除法,我知道问题不是由显示器本身引起的,也与视频输入电缆无关。我只能在连接到我的Macbook Pro(2015年初)和朋友的Macbook Pro(2014年初)的外部显示器上观察到此错误。

我尝试过的事情(没有帮助):

  • 通过Chrome设置禁用“硬件加速”
  • 将Chrome还原为默认设置
  • 监视系统性能(CPU和内存使用率都远低于极限)
  • 监视Chrome任务管理器
  • 在chrome://flags中切换各种设置
  • 更换各种电缆(HTMI、DVI和VGA)

想知道是否有其他人遇到类似的问题?这个奇怪的外部显示器卡顿问题一直困扰着我整整一个星期,我已经没有任何想法了。

Github演示项目repo-> https://github.com/peachteaboba/chrome_extension_bug_demo


-------------------------更新-------------------------

我已经确定了错误的根本原因。显然,如果在manifest.json中包含background.js文件,则弹出窗口会卡顿。如果不包含背景脚本,则没有卡顿。

manifest.json(卡顿版本)

{
  "manifest_version": 2,
  "name": "Chrome Extension Bug Demo v2",
  "description": "Chrome Extension Bug Demo v2",
  "version": "2.00",
  "author": "",
  "browser_action": {
    "default_icon": "images/bug.png",
    "default_title": "Chrome Extension Bug Demo v2",
    "default_popup": "popup.html"
  },
  "chrome_url_overrides": {},
  "permissions": [
    "storage",
    "tabs"
  ],
  "background": {
    "scripts": [
      "js/background.js"
    ]
  },
  "web_accessible_resources": [
    "script.js"
  ],
  "externally_connectable": {
    "matches": [
      "http://*/*",
      "https://*/*"
    ],
    "accept_tls_channel_id": true
  }
}

清单文件(无卡顿版本)manifest.json

{
  "manifest_version": 2,
  "name": "Chrome Extension Bug Demo v2",
  "description": "Chrome Extension Bug Demo v2",
  "version": "2.00",
  "author": "",
  "browser_action": {
    "default_icon": "images/bug.png",
    "default_title": "Chrome Extension Bug Demo v2",
    "default_popup": "popup.html"
  },
  "chrome_url_overrides": {},
  "permissions": [
    "storage",
    "tabs"
  ],
  "background": {
    "scripts": [
    
    ]
  },
  "web_accessible_resources": [
    "script.js"
  ],
  "externally_connectable": {
    "matches": [
      "http://*/*",
      "https://*/*"
    ],
    "accept_tls_channel_id": true
  }
}

唯一的更改是从后台脚本部分中删除“js/background.js”。 实际上,background.js 文件为空,因此即使包括此空脚本也会触发 Chrome bug。

针对此问题已在 Chromium 中开放了一个 bug 报告。 您可以通过此链接查看:https://bugs.chromium.org/p/chromium/issues/detail?id=971701


你的“更新”是一个答案吗?如果是,只需使用“你的答案”框来回答你自己的问题... - Heretic Monkey
@HereticMonkey 这不是答案,只是关于这个问题的额外信息。 - Andy
很高兴我不是唯一一个经历这种情况的人。 - wobsoriano
也有过这样的经历!转场和 CSS 动画会丢失很多帧,有时候甚至不会发生。这不是一个扩展级别的问题,它更深层次。 - Brad Decker
我也遇到了类似的问题。在输入字段中输入内容时,直到触发另一个复合绘制操作之前,它才会“隐形”。当我为扩展程序记录 DevTools 中的性能时,我能够使事情变得更加流畅。 - Donnie D'Amato
2个回答

21
我们在 usebubbles.com 的 Chrome 扩展程序中遇到了这个问题,并通过强制打开在 MacOS 的第二显示器上的弹出窗口进行重绘来解决它。
只需将以下内容添加到从 popup.html 包含的 JavaScript 文件的顶部即可:
/**
 * Temporary workaround for secondary monitors on MacOS where redraws don't happen
 * @See https://bugs.chromium.org/p/chromium/issues/detail?id=971701
 */
if (
  // From testing the following conditions seem to indicate that the popup was opened on a secondary monitor
  window.screenLeft < 0 ||
  window.screenTop < 0 ||
  window.screenLeft > window.screen.width ||
  window.screenTop > window.screen.height
) {
  chrome.runtime.getPlatformInfo(function (info) {
    if (info.os === 'mac') {
      const fontFaceSheet = new CSSStyleSheet()
      fontFaceSheet.insertRule(`
        @keyframes redraw {
          0% {
            opacity: 1;
          }
          100% {
            opacity: .99;
          }
        }
      `)
      fontFaceSheet.insertRule(`
        html {
          animation: redraw 1s linear infinite;
        }
      `)
      document.adoptedStyleSheets = [
        ...document.adoptedStyleSheets,
        fontFaceSheet,
      ]
    }
  })
}

3
我们将这段 CSS 直接添加到样式表中(没有 os / 第二个显示器检查)。效果非常好。感谢分享! - Eddie
1
太棒了。非常感谢您的修复和分享!老实说,我以为自己要疯了;你应该看看它对SVG做了什么。 - Dave Stewart

1
如果您处于双显示器环境并遇到输入延迟问题,则与您的物理窗口大小有关。请勿尝试在大型显示器上尝试,而是在笔记本电脑(MacBook)设备上尝试您的Chrome扩展程序。您会发现它可以在您的Mac上运行,但不能在连接的大屏幕上运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接