gpt4 book ai didi

javascript - 在触摸屏上滚动会显着减慢 Chrome 上的 AJAX 下载时间

转载 作者:行者123 更新时间:2023-11-30 07:53:12 27 4
gpt4 key购买 nike

我看到一些奇怪的行为,只要您的手指被按住,AJAX 请求就会在用手指滚动时偶尔挂起。很难用语言描述这个问题,所以看看这个 fiddle :

$("div").on('scroll', infiniteDictionaryScrollAjax);

function infiniteDictionaryScrollAjax(){
$("div").off("scroll");
$.ajax({
type: "POST",
url : "/someURL",
data: {data: "data"}

})
.done(function(response) {
$("div").append("<br>appendedData");
$("div").on('scroll', infiniteDictionaryScrollAjax);
})
.fail(function() {
$("div").append("<br>appendedError");
$("div").on('scroll', infiniteDictionaryScrollAjax);
});
}

https://jsfiddle.net/rx1qj9L5/5/

它触发一个 AJAX 请求(到一个不存在的 URL)并返回一个错误。 AJAX 请求在 scroll 事件上触发。当您使用鼠标滚动时,平均时间在 80-200 毫秒之间。这似乎非常一致。

这就是问题所在。用手指滚动时,ajax 请求可能会卡在“正在下载内容”不确定,直到手指从滚动中松开!

使用以下步骤,我能够一致地重现:

  1. 在支持触摸的设备上(在 Google Chrome 中)重新加载上面的页面
  2. 打开 chrome 开发工具,转到网络选项卡
  3. 触摸可滚动的 div(不要放手!)按住手指上下滚动。
  4. 这将触发 3 个 ajax 调用,其中第三个调用将无限期地挂起,直到您松开手指。只有在谷歌浏览器中用手指滚动时才会发生这种情况。
  5. 松开手指的那一刻,您会看到 Ajax 通过。

我想不出这种行为的任何原因。有没有人遇到过这个?这个问题有什么解决方法吗?

附注- 我试过在 vanilla Javascript 中做同样的绑定(bind)。没有区别。 :/

最佳答案

好的,我找到了这种行为的原因。由于默认情况下 JavaScript 是单线程的,因此在支持触摸的设备上滚动时,线程会暂停。 (我觉得禁用事件的“被动”性质应该可以解决问题,但线程仍然已暂停)

但是,有一个解决方案。如果您生成 html5 WebWorker,JavaScript 不再是单线程的。 WebWorker 拥有自己的线程,滚动不再导致任何问题。

我自己在 webworker 中使用 ajax 进行了一些测试,ajax 始终更快,并且它与滚动完美配合。这是我见过的最流畅的无限卷轴!

通过 webworker 的 ajax 似乎在所有方面都工作得更好(可能是因为它有自己的专用线程?)但是尤其是移动 chrome,其中 ajax 在 暂停滚动,并在滚动后 继续保持 1-2 秒的暂停。使用 web worker 允许 ajax 在滚动甚至停止之前完成,因此它给人一种无限期无缝滚动的错觉。

这是我使用 Web Worker 调用 ajax 函数的(无依赖)解决方案:

主页面js中的函数:

// wajax (webworker ajax)
function wajax(obj)
{

var sendObj = {};

sendObj.url = obj.url;
sendObj.data = obj.data;
sendObj.csrf = {{csrfToken here}}; //make sure to fill this out if you're using csrf tokens


if (typeof(Worker) !== "undefined") {
if (typeof(ajaxWorker) === "undefined") {
ajaxWorker = new Worker("path/to/webworker.js");
}


ajaxWorker.postMessage(JSON.stringify(sendObj));

ajaxWorker.onmessage = function(event) {
obj.success(event.data);
};
}
else {
// This means webworkers aren't available. Here, just do a regular ajax call....
}
}

Webworker(与页面的 javascript 分开的脚本/线程):

Webworker 具有我从 jQuery 源代码派生的代码,以允许在 AJAX 调用中使用 JSON 对象。我将源代码精简到最低限度。在缩小之前,webworker 的全尺寸只有大约 80 行。

/* ADAPTED FROM JQUERY SOURCE */
function param(a)
{
var prefix,
params = [],
add = function(key, value) {
params[params.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value);
};

for (prefix in a) {
buildParams(prefix, a[prefix], add);
}

// Return the resulting serialization
return params.join("&");
}

function buildParams(mainKey, mainValue, add)
{
var name;
var length = mainValue.length;
if (Array.isArray(mainValue)) {
for (var index = 0; index < length; index++) {
var value = mainKey[index];
if (/\[]$/.test(mainKey)) {
add(mainKey, value);
}
else {
buildParams(mainKey + "[" + (typeof value === "object" && value != null ? index : "") + "]", value, add);
}
}
}
else if (typeof mainValue === "object") {
for (name in mainValue) {
buildParams(mainKey + "[" + name + "]", mainValue[name], add);
}
}
else {
add(mainKey, mainValue);
}
}

/* END CODE ADAPTED FROM JQUERY SOURCE */

/*
* Created by Skeets 2017-12-13
* */

onmessage = function(e) {

var obj = JSON.parse(e.data);

obj.data._token = obj.csrf;

var request = new XMLHttpRequest();
request.open('POST', obj.url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success
var output;
try {
output = JSON.parse(request.responseText);
}
catch (e) {
output = request.responseText;
}
postMessage(output);
}
else {
// error
console.log(request.responseText);
}
};

request.onerror = function() {
// connection error
};

request.send(param(obj.data));

};

一旦就绪,您可以像这样发出 ajax 请求:

wajax({
url : "/some/url",
data : {value_a:"somestuff",value_b:2},
success: function(response) {
// do something with the response
}
});

请随意使用和改编此代码。

关于javascript - 在触摸屏上滚动会显着减慢 Chrome 上的 AJAX 下载时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47788146/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com