为什么我的Ajax请求比普通浏览器请求慢得多?

4
我为一个朋友创建了一个网站。因为他希望音乐播放器可以在页面加载时继续播放音乐,所以我决定通过ajax(利用jQuery)将内容加载到页面中。它运行良好,在没有JavaScript的情况下可以很好地回退,并且前进/后退按钮也很好用,但是服务器上非常慢。
一些要点:
1. 初始页面加载相当快。Chrome开发者控制台告诉我,“index.php”大约需要2.5秒钟。我已经设置了查询字符串参数来指示加载哪个页面,这个时间对于它们所有都是准确的。对于主页,加载了8.4KB的数据。
2. 当我通过ajax请求加载内容时,无论下载的数据大小如何,都需要大约20秒钟。以这种方式加载的最小数据量约为500字节。显然存在不匹配。
因此,Chrome告诉我,花费的绝大部分时间是“等待”,这意味着服务器正在处理请求。那么,只能是我的代码需要很长时间,或者服务器出了问题。我认为这不是我的代码问题,因为它非常简单:
$file = "";
if (isset($_GET['page'])) {
    $file = $_GET['page'];
} else if (isset($_POST['page'])) {
    $file = $_POST['page'];
} else {
    $file = "home";
}

$file = 'content/' . $file . '.php';

if (file_exists($file)) {
    include_once($file);
} else {
    include_once('content/404.php');
}

这段代码位于content_loader.php文件中,我的JavaScript(在这种情况下)与“page”参数一起发送GET请求。 HTML标记返回并放置在页面的DIV中。
我使用jQuery的.get() 简写函数,因此我不认为这会出现问题,而且我相信这不是JavaScript的问题,因为延迟是等待来自服务器的数据。即使数据非常小,它也需要大约20秒的时间。
我目前认为这是服务器的问题,但我不明白为什么通过JavaScript发出的请求比通过传统方式通过浏览器发出的请求要慢得多。另外,一些内容页面确实连接到MySQL数据库,但有些则不是。似乎无论页面需要处理什么或者包含多少数据,都需要大约20秒的时间。
我很困惑......有没有人知道有什么可能解释这个问题?此外,如果这不是适当的提问场所,我很抱歉,因为其他地方似乎也不是特别适合这个问题。

根据我过去处理类似问题的经验,我立刻想到了几件事情。首先可能是反向DNS查找问题。它可能在反向DNS查找失败后超时。其他问题:您是否使用MySQL?您是否正在加载基于文件的会话? - Justin Warkentin
建立了一个MySQL连接,尽管一些内容页面根本没有使用它。而且我根本没有使用会话。我突然想到要尝试计算我的PHP执行时间,所以在任何其他事情发生之前(包括与数据库的连接),我非常简单地回显了time(),并且在所有操作完成后,在将其发送回客户端之前,就像之前一样回显了time()。输出是相同的,因此我认为这意味着我的脚本运行时间少于一秒钟。您能详细谈谈反向DNS问题吗?我不确定您的意思。 - user2276673
我的第一个怀疑是你的查询语句。如果最终证明你的查询语句非常低效,导致应用程序等待数据库执行完成,我也不会感到惊讶。 - Matthew Cox
@FeistyMango 我认为这不是一个查询,有两个原因。1)他计时了PHP脚本的执行本身,而且很快。运行查询会显示在执行时间中 - 它是同步的。2)查询从来没有那么一致,如果是相同的查询,第二次会被缓存。 - Justin Warkentin
我知道这是一个有点老的问题,但我正在经历一个相同的问题。假设我有页面x。当我在浏览器中调用它时,它非常快,没有加载时间。当我在ajax中调用它时,它非常慢。也许没有超过OP的时间(我需要5秒),但仍然很慢。我正在创建一个基于地图的游戏,希望它能够运行得很快...我正在使用带有CORS的跨域ajax连接。(尽管两个域都由我控制) - user5147563
显示剩余6条评论
1个回答

1
如我在评论中提到的,一个确定的可能性可能是反向DNS查找。我以前也遇到过这个问题,我敢打赌这是你缓慢请求的来源。无论是常规Apache还是虚拟主机配置以及.htaccess中都有一些需要注意的Apache配置指令。以下是一些希望能够帮助你的链接:

http://www.tablix.org/~avian/blog/archives/2011/04/reverse_dns_lookups_and_apache/

http://betabug.ch/blogs/ch-athens/933

要查找更多资源,只需谷歌搜索“apache slow reverse dns”之类的内容。
一个反向DNS查找尝试将IP地址解析为主机名。大多数情况下,像Apache、SSH和MySQL这样的服务都不需要进行此操作,这是一种不好的想法,因为它只会减慢请求/连接。如果不需要,最好寻找您不同服务的配置设置并禁用反向DNS查找。
在Apache中,有一些配置设置会导致反向查找发生。例如,指定域而不是IP地址的allow/deny规则和HostnameLookups等设置。有关更多信息,请参见上面的链接。
正如您在评论中建议的那样,PHP脚本一旦运行就会快速执行。时间花费在等待Apache上 - 最有可能是进行反向DNS查找并失败。您知道问题不在于您的代码,而在于请求涉及的其他服务。
希望这能帮到您!

据我了解,如果正在进行反向DNS查找,则Apache访问日志将显示主机名,而不仅仅是IP地址,对吗?在我的情况下,日志仅显示IP地址。 - user2276673
这取决于它尝试进行查找的内容。您可能已经关闭了HostnameLookups,但在其他地方有一个不同的规则尝试进行查找。或者,它可能在反向查找时失败,并且只是将IP地址粘贴到日志中。在此处的日志中,尝试对最近的IP进行反向查找:http://remote.12dt.com/ - 还要注意访问日志中GET请求的时间戳与您实际发出请求的时间之间的差异,看看给您的时间戳是什么。 - Justin Warkentin
反向查找正常工作。我在我的IP地址上进行了测试(当然会出现在日志中),它解析为一个合理的主机名。另一件我不明白的事情是,每次大约需要20秒钟,好像服务器因某种原因阻塞了一段时间... - user2276673
是的,这很有道理。首先,它在等待的时间上是一致的,因为它正在等待超时。仍然可能是反向DNS - 并非每个反向DNS请求都会显示在日志中。它也可能涉及到请求的另一个服务 - 但我不知道您设置了什么或正在进行什么操作。您是否查看了那些链接并查找其他有问题的设置?此外,知道Apache记录请求接收的时间将非常有帮助。 - Justin Warkentin
正如我在原问题的评论中提到的那样,该网站位于共享服务器上。由于某种原因,他们没有实时更新日志。它们似乎每小时更新一次,这非常令人恼火...我已经保存了我的Javascript请求时间,并将在日志可用时查看它。 - user2276673

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