如何找到 safari 中页面不断刷新的原因?
How to find the cause of a constant page refresh in safari?
我正在尝试找出自 iOS 和 OSX 的最新更新以来在过去一个月左右出现的客户网站上的问题。当 Mac 或 iOS Safari 的用户通过 EDM 中的 link 被定向到站点中的任何页面时,他们会陷入不断刷新的页面循环中。它似乎也在刷新之间泄漏内存,因为 Activity 监视器显示该站点的 Safari Web 内容进程的内存使用量快速增长(在我杀死它之前两分钟左右达到 4 GB)。
此问题只能在 Safari 浏览器上重现。 Chrome 在 Mac 上似乎不受影响。 Windows 的 Safari 显示刷新问题,但似乎没有开始囤积内存,尽管 WebKit2WebProcess.ee 进程的 CPU 使用率一直处于相当高的值,直到 window已经关了。我尝试一个一个地删除添加到 EDM links 的 utm_* 参数,直到我可以确认问题是由 utm_source 本身引起的,然后发现我应该预料到这一点显然是 GA 寻找的主要标签。更有趣的是,删除 GA 并没有解决问题——我注释掉了创建脚本标签的代码(就其价值而言,使用的脚本不是正常的 www.google-analytics。com/ga .js 而不是来自 stats.g.doubleclick.net/dc.js).
的 DFP
解决问题的方法是不加载 GPT - 注释以下代码:
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
var gads = document.createElement("script");
gads.async = true;
gads.type = "text/javascript";
var useSSL = "https:" == document.location.protocol;
gads.src = (useSSL ? "https:" : "http:") + "//www.googletagservices.com/tag/js/gpt.js";
var node =document.getElementsByTagName("script")[0];
node.parentNode.insertBefore(gads, node);
})();
所以我相当确定 GPT 正在检测 utm_source 参数并尝试做...某事...在 Safari 上由于...某些原因而失败...不幸的是 GPT 代码是混淆了,我不太可能只是阅读它就发现我的问题,所以我希望在我不知道的 Safari 开发人员控制台中刷新页面之前,可能有一些方法可以获取调用堆栈,或者其他一些方法我没有想到的调试技术。也许其他人甚至遇到过这个问题?
据我所知,唯一关心这些参数的脚本是 Google Analytics,所以我也乐于听到我正在沿着花园小径前进。
编辑:我尝试取消注释 GPT 脚本标签,然后在我们向其推送命令的页面上注释一个地方(使用 googletag.cmd.push()
),以防我们的使用导致问题(我们本质上只是定义然后在推送的 cmd 中发布 8 个插槽,然后启用广告服务)。评论这个命令并没有解决问题,它似乎与加载 GPT 完全相关。
所以这在所有方面都是一个令人难以置信的令人困惑的问题,即使在我修复它之后仍然如此。
我们能够通过更新网站上使用的 History.js 库来解决问题,就其本身而言,我完全可以接受这是一个有效的故障排除步骤(因此我尝试了一下)。但是,我对 History.js 和 gpt.js 如何相互交互感到非常困惑。导致问题仅在以下情况下发生:
使用 Safari
使用旧版本 History.js
使用 GPT(对 History.js 应该没有影响)
使用 utm_source 标签(对 History.js 或 GPT 应该没有影响)
但我更愿意被一个固定的问题搞糊涂,而不是一个普遍的问题,所以我打算把它留在 'too hard' 篮子里。
顺便说一句,我的主要问题是做,而不是问题 persay,所以这是我如何得出结论的,以防对其他人有帮助:
- 我在
<head>
的顶部添加了一个脚本标记,它为 beforeunload 注册了一个事件处理程序,调用调试器语句。这将使我有时间在页面刷新之前实际检查时间线和分析器。
- 这向我展示了在 beforeunload 事件之前调用了一个 popstate 事件(事后看来,当我看到 popstate 时,我责备自己没有直接进入 History.js)。这个事件安装了一个计时器,我注意到它会立即触发,然后每 1000 毫秒触发一次。这是在 beforeunload 事件之前在 popstate 事件中触发的最后一件事,所以我认为它很有可能导致刷新。
接下来,由于 Safari 不会在其时间轴中公开事件的调用堆栈这一事实,我花了一些时间来解决这个问题。我知道如何在 Chrome 中解决这个问题,但我无法在 Chrome 中解决问题。我所要做的就是计时器 ID。最终我像这样覆盖了 setTimeout:
var origST = window.setTimeout;
window.timers = [];
window.setTimeout = function(f,t) {
window.timers[origST(f,t)] = window.setTimeout.caller ? window.setTimeout.caller : 'Global Scope';
}
并对 setInterval 执行相同的操作。然后我可以重新加载页面,获取计时器的 ID,然后在控制台中检查 timers[the id]
安装计时器的函数的文本。
- 接下来我需要在所有加载的脚本文件中搜索有问题的函数定义(这是一个混淆和丑化的脚本,不是我可以轻易猜到的)我不确定这在 Safari 中是否真的可行,如果是的话,我不知道该怎么做。幸运的是,这并不依赖于重现问题,所以我加载了 Chrome 并使用它的开发工具来搜索脚本文件。
- 在 History.js 中找到函数,我们更新了它并发现问题已解决。
我正在尝试找出自 iOS 和 OSX 的最新更新以来在过去一个月左右出现的客户网站上的问题。当 Mac 或 iOS Safari 的用户通过 EDM 中的 link 被定向到站点中的任何页面时,他们会陷入不断刷新的页面循环中。它似乎也在刷新之间泄漏内存,因为 Activity 监视器显示该站点的 Safari Web 内容进程的内存使用量快速增长(在我杀死它之前两分钟左右达到 4 GB)。
此问题只能在 Safari 浏览器上重现。 Chrome 在 Mac 上似乎不受影响。 Windows 的 Safari 显示刷新问题,但似乎没有开始囤积内存,尽管 WebKit2WebProcess.ee 进程的 CPU 使用率一直处于相当高的值,直到 window已经关了。我尝试一个一个地删除添加到 EDM links 的 utm_* 参数,直到我可以确认问题是由 utm_source 本身引起的,然后发现我应该预料到这一点显然是 GA 寻找的主要标签。更有趣的是,删除 GA 并没有解决问题——我注释掉了创建脚本标签的代码(就其价值而言,使用的脚本不是正常的 www.google-analytics。com/ga .js 而不是来自 stats.g.doubleclick.net/dc.js).
的 DFP解决问题的方法是不加载 GPT - 注释以下代码:
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
var gads = document.createElement("script");
gads.async = true;
gads.type = "text/javascript";
var useSSL = "https:" == document.location.protocol;
gads.src = (useSSL ? "https:" : "http:") + "//www.googletagservices.com/tag/js/gpt.js";
var node =document.getElementsByTagName("script")[0];
node.parentNode.insertBefore(gads, node);
})();
所以我相当确定 GPT 正在检测 utm_source 参数并尝试做...某事...在 Safari 上由于...某些原因而失败...不幸的是 GPT 代码是混淆了,我不太可能只是阅读它就发现我的问题,所以我希望在我不知道的 Safari 开发人员控制台中刷新页面之前,可能有一些方法可以获取调用堆栈,或者其他一些方法我没有想到的调试技术。也许其他人甚至遇到过这个问题?
据我所知,唯一关心这些参数的脚本是 Google Analytics,所以我也乐于听到我正在沿着花园小径前进。
编辑:我尝试取消注释 GPT 脚本标签,然后在我们向其推送命令的页面上注释一个地方(使用 googletag.cmd.push()
),以防我们的使用导致问题(我们本质上只是定义然后在推送的 cmd 中发布 8 个插槽,然后启用广告服务)。评论这个命令并没有解决问题,它似乎与加载 GPT 完全相关。
所以这在所有方面都是一个令人难以置信的令人困惑的问题,即使在我修复它之后仍然如此。
我们能够通过更新网站上使用的 History.js 库来解决问题,就其本身而言,我完全可以接受这是一个有效的故障排除步骤(因此我尝试了一下)。但是,我对 History.js 和 gpt.js 如何相互交互感到非常困惑。导致问题仅在以下情况下发生:
使用 Safari 使用旧版本 History.js 使用 GPT(对 History.js 应该没有影响) 使用 utm_source 标签(对 History.js 或 GPT 应该没有影响)
但我更愿意被一个固定的问题搞糊涂,而不是一个普遍的问题,所以我打算把它留在 'too hard' 篮子里。
顺便说一句,我的主要问题是做,而不是问题 persay,所以这是我如何得出结论的,以防对其他人有帮助:
- 我在
<head>
的顶部添加了一个脚本标记,它为 beforeunload 注册了一个事件处理程序,调用调试器语句。这将使我有时间在页面刷新之前实际检查时间线和分析器。 - 这向我展示了在 beforeunload 事件之前调用了一个 popstate 事件(事后看来,当我看到 popstate 时,我责备自己没有直接进入 History.js)。这个事件安装了一个计时器,我注意到它会立即触发,然后每 1000 毫秒触发一次。这是在 beforeunload 事件之前在 popstate 事件中触发的最后一件事,所以我认为它很有可能导致刷新。
接下来,由于 Safari 不会在其时间轴中公开事件的调用堆栈这一事实,我花了一些时间来解决这个问题。我知道如何在 Chrome 中解决这个问题,但我无法在 Chrome 中解决问题。我所要做的就是计时器 ID。最终我像这样覆盖了 setTimeout:
var origST = window.setTimeout; window.timers = []; window.setTimeout = function(f,t) { window.timers[origST(f,t)] = window.setTimeout.caller ? window.setTimeout.caller : 'Global Scope'; }
并对 setInterval 执行相同的操作。然后我可以重新加载页面,获取计时器的 ID,然后在控制台中检查
timers[the id]
安装计时器的函数的文本。- 接下来我需要在所有加载的脚本文件中搜索有问题的函数定义(这是一个混淆和丑化的脚本,不是我可以轻易猜到的)我不确定这在 Safari 中是否真的可行,如果是的话,我不知道该怎么做。幸运的是,这并不依赖于重现问题,所以我加载了 Chrome 并使用它的开发工具来搜索脚本文件。
- 在 History.js 中找到函数,我们更新了它并发现问题已解决。