HTML5 video fully buffered but continuously send network request when seeking - html

When I fully buffered a mp4 file and seek, browser continuously sending network request and buffering (sometimes ~100ms simetimes 500ms depending on network). Someone knows why?
Even If I use a local file and seek, it also send Range request!

I think if you look at the request in detail you'll see the requests are cancelled (on Chrome anyway, which is what you are using above). See below for example (this happens when moving back along the timeline of a short video):
I suspect that the browser is simply making the request first as an optimisation and then cancelling it when it checks and confirms that it has the video already buffered.
You also should be able to see that the first request will have a range request from 0 onwards and the request when you move along the time bar have an offset reflecting where you moved to:

Related

Understanding results from Chrome request timing

I am doing some profiling of my web app and I am puzzled about the results I am getting from the Chrome built-in timing of requests. To put things simple, lets say I request a web page composed of:
The HTML.
The static files (js, css, etc.).
Data loaded using AJAX.
According to the timing provided by Chrome the main HTML loading time is like this:
So far, so good. If I understand it, this means my server takes around 7-8 secs to process the request and send the response. In fact, according to this info, the first byte arrives at 7.79 secs, so the browser cannot start processing the HTML and loading other resources until this time.
However, if I look at the timing for static resources and AJAX requests, I found something puzzling. For instance, this is the timing for the request for bootstrap.min.css:
Notice the request was queued at 21.6 ms, much earlier than the arrival of the first byte from the HTML. By the way, the file was retrieved from cache (from disk cache, according to Chrome), but how did the browser know the HTML were going to request that file before receiving the response?
In the case of the AJAX request we have something similar:
but this time is even more strange, because to perform this request some javascript from the html should be processed, but the first byte was not received when the AJAX request was queued!.
How can this be possible? How am I suppossed to interpret these results regarding the performance of the website (i. e. did the HTML really take 7 secs to load the very first byte)?

Chrome, Firefox caching 302 redirects

According to the HTTP spec, upon loading a resource that results in a 302 redirect:
...the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.
However, within a single page load, I'm seeing current Chrome and Firefox both resolving subsequent requests to the initial Request-URI to the resolved value from the first request, even when the redirect specifies no caching.
I've setup a minimal repro case here:
http://chrome-302-broke.herokuapp.com/test.html
It's on a free heroku dyno (in case you reach it while it's offline).
Am I missing something? It seems like caching the redirect from the initial response, even within the same page load, is taking liberty with the description from the spec. A strict interpretation shouldn't cache this request at all.
Especially with a growing number of web applications that don't navigate between pages for a considerable amount of time, this seems like it would cause problems for an increasing number of use cases.
Is this something I should submit as a bug to Chrome/Firefox?

Understanding Firebug's Net panel

I am trying to get a hang on analysing the performance of a web page using Firebug's Net panel.
The following screenshot shows an example of a google query. For the sake of this discussion I clicked twice, so some requests are cached.
So here are my questions:
1) What is happening between the end of the first request and the beginning of the next request (which is the third one). In the same context: Why is the third request starting earlier than the second request?
2) The next 6 requests are coming from the cache. The purple bar is indicating waiting time and I assumed this is the time the browser "waiting for the server to to something". So as comes from cache, what exactly is the browser waiting for. Also: What could be the reason, that the waiting time for for a 4,4KB response is longer (63ms) than for a 126,3 KB response (50ms).
3) In the next request there is a fairly long green bar indicating the time of receiving the response. How comes that this doesn't seem to be at least fairly proportional to the size of the response?
4) The red vertical line indicates the load event. According to https://developer.mozilla.org/en-US/docs/Web/Events/load this means: "The load event is fired when a resource and its dependent resources have finished loading." In the timeline you can see that there are still a couple of requests performed after the load event. How comes? Are they considered to be not dependent and if so why?
The response of the first request needs to be parsed to find out what else needs to be loaded. This parsing time causes the gap to the second request. See also my answer to a related question.
Responses coming from cache still have an associated network request, which returns the 304 HTTP status code. You can see the request and response headers as well as the response headers of the cached response when you expand the request.
In contrast to that there is also a response that is directly served from a special cache called Back-Forward Cache (or BFCache). These responses happen directly after the browser start when you have the option enabled to restore your tabs from the last session and also when you navigate back and forth in the tab history.
This depends on the network connection speed and the response's size in the first place but also on how long the server takes to send the full response. Why that one request takes that long in comparison to the others can't be explained without knowing what happens on the server side.
The load event is fired when the page request is loaded including all its depending resources like CSS, images, JavaScript sources, etc. Requests initiated after the load event are loaded asyncronously, e.g. through an XMLHttpRequest or the defer attribute of the element.

Determine which webpage an object in a packet capture is associated with

I am currently working on trying to take a packet capture and work backwards to determine what objects are associated to each page request. For example if a packet capture contains 2 different webpages worth of requests I want to be able to determine for each object (TCP stream) which root page it is associated with. Is there an easy way to do this?
I know there are tools that will isolate the TCP streams and which will pull the data within them out, however I am not looking to replicate the webpage. I am simply looking to be able to associate each stream to the original page that requested it.
What you are trying to do is reconstructing the "call graph" of a browsing session. For a simply analysis, you can inspect just the HTTP headers. Bro makes this process very convenient. If site A loads site B, A typically shows up in the Referer header of B.
However, if you aim for completeness, this task becomes a daunting challenge: you need to parse the HTTP body payload and even JavaScript to determine all the URLs that are being created at runtime in the client, e.g., via AJAX, iframes, and friends.

Streaming without Content-Length in response

I'm using Node.js, Express (and connect), and fluent-ffmpeg.
We want to stream audio files that are stored on Amazon S3 through http.
We have all working, except that we would like to add a feature, the on-the-fly conversion of the stream through ffmpeg.
This is working well, the problem is that some browsers checks in advance before actually getting the file.
Incoming requests containing the Range header, for which we reply with a 206 with all the info from S3, have a fundamental problem: we need to know in advance the content-length of the file.
We don't know that since it is going through ffmpeg.
One solution might be to write out the resulting content-length directly on S3 when storing the file (in a special header), but this means we have to go through the pain of having queues to encode after upload just to know the size for future requests.
It also means that if we change compressor or preset we have to go through all this over again, so it is not a viable solution.
We also noticed big differencies in the way Chrome and Safari request the audio tag src, but this may be discussion for another topic.
Fact is that without a proper content-length header in response everything seems to break or browsers goes in an infinite loop or restart the stream at pleasure.
Ideas?
This seems to be working for me.
It would be great if you could confirm whether it gives the expect results in your browsers too.
res.writeHead(200, {
'Transfer-Encoding': 'chunked'
, 'Content-Type': 'audio/mpeg'
, 'Accept-Ranges': 'bytes' //just to please some players, we do not actually allow seeking
});
Basically, you tell the browser that you are going to stream using chunked encoding. An issue may be that some browsers do not like streaming without know how much bytes they should expect in total.