我编写了一个网络抓取工具应用程序来监控网站,检查问题。每当它访问一个页面时,我想捕获时间到第一个字节(即,发出请求和接收响应的第一个字节之间的时间)。 TTFB尽可能接近测量服务器渲染页面所需的时间。
下面是我执行此操作的代码,但结果看起来不正确。 TTFB通常与完整响应时间完全相同或少一点。我错过了什么?
HttpWebResponse webResponse = null;
var stopWatch = new Stopwatch();
stopWatch.Start();
try
{
var webRequest = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
webRequest.Method = "get";
webRequest.AllowAutoRedirect = false;
webRequest.UserAgent = userAgent;
webRequest.Accept = "*/*";
webRequest.KeepAlive = true;
webRequest.CookieContainer = CookieContainer;
webResponse = (HttpWebResponse)webRequest.GetResponse();
responseTimeToFirstByte = Convert.ToInt32(stopWatch.ElapsedMilliseconds);
using (var responseStream = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.ASCII))
{
bodyContent = responseStream.ReadToEnd();
stopWatch.Stop();
}
webResponse.Close();
responseTimeFull = Convert.ToInt32(stopWatch.ElapsedMilliseconds);
}
答案 0 :(得分:4)
你没有遗漏任何东西。只有当框架已经被缓冲和解析时,框架才会通知响应。
HttpWebResponse
对象已经设置了有关HTTP标头的信息,因此数据已经被重新编译和解析。也许发送一个巨大的文件你可能会发现不同,我不完全确定。
如果您想测量TFB,可以使用Socket
或更好的TcpClient
并发送精心设计的HTTP请求,然后测量返回数据的时间:
Byte[] buffer = new Byte[1024];
Int32 readed = -1;
TcpClient client = new TcpClient();
Stopwatch watch = new Stopwatch();
List<Int64> readTimes = new List<Int64>();
watch.Start();
await client.ConnectAsync(<IP address>, <Port>);
using(var stream = client.GetStream())
using (var ms = new MemoryStream())
using (var sw = new StreamWriter(stream, Encoding.ASCII))
{
sw.WriteLine("GET /the/path/to/your/resource HTTP/1.1");
sw.WriteLine("Host: yourdomainname.com");
sw.WriteLine("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
sw.WriteLine();
await sw.FlushAsync();
while(readed != 0)
{
readed = await stream.ReadAsync(buffer,0,buffer.Length);
readTimes.Add(watch.ElapsedMilliseconds);
ms.Write(buffer,0,readed);
}
watch.Stop();
}
(警告,此代码未经过测试)
在此代码中,“readTimes”中的第一个值将是您的TFB,最后一个值是总时间。
干杯。