Checking someones bandwidth and loading content based on it - javascript

I have seen a number of questions that don't answer this, is it possible to check someones bandwidth using java script and load specific content based on it?
The BBC seem to give me low quality images when using my mobile and in the middle of nowhere.
by the looks of this this cool service does this and its a CDN so it could be server side.
http://www.resrc.it/docs/
Does anyone know how they do it? or how I could do it using asp.net or javascript, or an community opensource plug in.
I think it may be possible with https://github.com/yahoo/boomerang/ but not sure this is its true purpose.

Basically you do this like this:
Start a timer
Load an fixed size file e.g a image through an ajax call
Stop the timer
Take some samples and compute the average badwidth
Somethign like this could work:
//http://upload.wikimedia.org/wikipedia/commons/5/51/Google.png
//Size = 238 KB
function measureBW(cnt, cb) {
var start = new Date().getTime();
var bandwidth;
var i = 0;
(function rec() {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('GET', 'http://upload.wikimedia.org/wikipedia/commons/5/51/Google.png', true);
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4) {
var x = new Date().getTime() - start;
bw = Number(((238 / (x / 1000))));
bandwidth = ((bandwidth || bw) + bw) / 2;
i++;
if (i < cnt) {
start = new Date().getTime();rec();
}
else cb(bandwidth.toFixed(0));
}
};
xmlHttp.send(null);
})();
}
measureBW(10, function (e) {
console.log(e);
});
Not that var xmlHttp = new XMLHttpRequest(); won't work on all browsers, you should check for the UserAgent and use the right one
And of course its just an estimated value.
Heres a JSBin example

Start a timer.
Send a AJAX request to your server, requesting a file of known size.
When the AJAX request's done loading, stop the timer, and calculate the bandwidth from the passed time and file size.
The problem with JavaScript is that users can disable it. (Which is more common on phones, that happen to be better off with smaller images)

I've knocked this up based on timing image downloads (ref: http://www.ehow.com/how_5804819_detect-connection-speed-javascript.html)
Word of warning though:
It says my speed is 1.81Mbps,
But according to SpeedTest.Net my speeds are this:
The logic of timing the download seems right but not sure if it's accurate?

Well, like I said in my comments, you can choose 2 approaches:
1) You are in the context of a mobile app, then you can query the technology used by the device directly so you can notify the server directly what type (and size) of content you area able to render. I think phone gap can help you with accessing some of the native mobile API's using JavaScript.
2) The server-timer thing. You can "serve" some files yourself, lets say you have a magic file in your landing page, that, as soon as the client request the file, you grab this HTTP request with a custom handler. You "manually" serve the file by writing to the output stream, and you measure the bytes send and the time it took to reach the EOF, then you can somehow measure the bandwith. Combine this with the session cookie and you have this information per connected browser.

While this isn't an answer, it may be important to note that measuring bandwidth isn't always reliable.
http://www.smashingmagazine.com/2013/01/09/bandwidth-media-queries-we-dont-need-em/
To paraphrase the above:
...the number of bits downloaded divided by the time it took to download them...is true when you download a large file over a single warmed-up TCP connection. That is rarely the case.
Typical page load scenario:
Initial HTML page is downloaded using slow-start mechanism, so measurement will significantly underestimate the available bandwidth
CSS and JavaScript external resources are loaded -- a collection of new TCP connections, all in their slow-start phase, and they are not all necessarily to the same destination server
Images are loaded -- multiple connections, each one downloading a resource. The problem is that these connections are not always in the same phase of their life cycle. Some might be in the slow-start phase; some may have suffered a packet loss and, thus, reduced their window and the bandwidth they are trying to fill; and some might be warmed-up TCP connections, ready to fill the bandwidth. These TCP connections are not necessarily all to the same destination server, and the bandwidth towards the various destination servers might be different between one another.
So, estimating bandwidth is possible, but it is far from simple, and it is possible only for certain phases of the page-loading process. And because having several TCP connections to various destination servers is common (for example, a CDN could host the image resources of a Web page), we cannot really tell what is the bandwidth we want to measure.
Since this is an older question, the alternative suggestion at the end of the article is to consider the more recent srcset attribute for responsive imagery, which lets the browser decide which asset to load based on whatever it knows (which should be more than us). It sounds like it's weighted more towards just determining resolution, but maybe it'll get smarter as support goes up.

I have released BwCh which is an open-source JavaScript API to detect bandwidth for web-based environments
It is built with ES2015. It uses some of the latest JavaScript innovation (window.navigator.connection currently supported in Chrome 48+ for Android as of April 2016) in order to provide a flexible method to detect bandwidth for both mobile and desktop devices. It fallbacks/complements to image pre-loading to detect bandwidth where those newest API are not available.

Related

Trouble with playing sounds from JavaScript [duplicate]

I'm trying to get sound working on my iPhone game using the Web Audio API. The problem is that this app is entirely client side. I want to store my mp3s in a local folder (and without being user input driven) so I can't use XMLHttpRequest to read the data. I was looking into using FileSystem but Safari doesn't support it.
Is there any alternative?
Edit: Thanks for the below responses. Unfortunately the Audio API is horribly slow for games. I had this working and the latency just makes the user experience unacceptable. To clarify, what I need is sounething like -
var request = new XMLHttpRequest();
request.open('GET', 'file:///./../sounds/beep-1.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
dogBarkingBuffer = buffer;
}, onError);
}
request.send();
But this gives me the errors -
XMLHttpRequest cannot load file:///sounds/beep-1.mp3. Cross origin requests are only supported for HTTP.
Uncaught Error: NETWORK_ERR: XMLHttpRequest Exception 101
I understand the security risks with reading local files but surely within your own domain should be ok?
I had the same problem and I found this very simple solution.
audio_file.onchange = function(){
var files = this.files;
var file = URL.createObjectURL(files[0]);
audio_player.src = file;
audio_player.play();
};
<input id="audio_file" type="file" accept="audio/*" />
<audio id="audio_player" />
You can test here:
http://jsfiddle.net/Tv8Cm/
Ok, it's taken me two days of prototyping different solutions and I've finally figured out how I can do this without storing my resources on a server. There's a few blogs that detail this but I couldn't find the full solution in one place so I'm adding it here. This may be considered a bit hacky by seasoned programmers but it's the only way I can see this working, so if anyone has a more elegent solution I'd love to hear it.
The solution was to store my sound files as a Base64 encoded string. The sound files are relatively small (less than 30kb) so I'm hoping performance won't be too much of an issue. Note that I put 'xxx' in front of some of the hyperlinks as my n00b status means I can't post more than two links.
Step 1: create Base 64 sound font
First I need to convert my mp3 to a Base64 encoded string and store it as JSON. I found a website that does this conversion for me here - xxxhttp://www.mobilefish.com/services/base64/base64.php
You may need to remove return characters using a text editor but for anyone that needs an example I found some piano tones here - xxxhttps://raw.github.com/mudcube/MIDI.js/master/soundfont/acoustic_grand_piano-mp3.js
Note that in order to work with my example you're need to remove the header part data:audio/mpeg;base64,
Step 2: decode sound font to ArrayBuffer
You could implement this yourself but I found an API that does this perfectly (why re-invent the wheel, right?) - https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js
Resource taken from - here
Step 3: Adding the rest of the code
Fairly straightforward
var cNote = acoustic_grand_piano.C2;
var byteArray = Base64Binary.decodeArrayBuffer(cNote);
var context = new webkitAudioContext();
context.decodeAudioData(byteArray, function(buffer) {
var source = context.createBufferSource(); // creates a sound source
source.buffer = buffer;
source.connect(context.destination); // connect the source to the context's destination (the speakers)
source.noteOn(0);
}, function(err) { console.log("err(decodeAudioData): "+err); });
And that's it! I have this working through my desktop version of Chrome and also running on mobile Safari (iOS 6 only of course as Web Audio is not supported in older versions). It takes a couple of seconds to load on mobile Safari (Vs less than 1 second on desktop Chrome) but this might be due to the fact that it spends time downloading the sound fonts. It might also be the fact that iOS prevents any sound playing until a user interaction event has occured. I need to do more work looking at how it performs.
Hope this saves someone else the grief I went through.
Because ios apps are sandboxed, the web view (basically safari wrapped in phonegap) allows you to store your mp3 file locally. I.e, there is no "cross domain" security issue.
This is as of ios6 as previous ios versions didn't support web audio api
Use HTML5 Audio tag for playing audio file in browser.
Ajax request works with http protocol so when you try to get audio file using file://, browser mark this request as cross domain request. Set following code in request header -
header('Access-Control-Allow-Origin: *');

How to get transferred size of a complete page load?

With Selenium or JavaScript how could you get the (over the network) transferred size (bytes) of the loaded page including all the content, images, css, js, etc?
The preferred size is that of what goes over the network, that is compressed, only for the requests that are made, etc.
This is what you usually can see in dev tools, to the right in the network status bar:
If that's not possible, could one just get a total size of all the loaded resources (without compression, etc)? That would be an acceptable alternative.
The browser is Firefox, but if it could be done with some other Selenium compatible browser that would be acceptable also.
I guess this could be done using a proxy, but is there any JS or Selenium way to get such information?
If proxy is the only way, which one would one use (or implement) to keep things simple for such a task? Just implementing something in Java before setting up the driver?
(The solution should work at least on Linux, but preferably on Windows also. I'm using Selenium WebDriver via Java.)
For future reference, it is possible to request this information from the browser by javascript. However, at the time of writing no browser supports this feature for this specific data yet. More information can be found here.
In the mean time, for Chrome you can parse this information from the performance log.
//Enable performance logging
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
capa.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
//Start driver
WebDriver driver = new ChromeDriver(capa);
You can then get this data like this
for (LogEntry entry : driver.manage().logs().get(LogType.PERFORMANCE)) {
if(entry.getMessage().contains("Network.dataReceived")) {
Matcher dataLengthMatcher = Pattern.compile("encodedDataLength\":(.*?),").matcher(entry.getMessage());
dataLengthMatcher.find();
//Do whatever you want with the data here.
}
If, like in your case, you want to know the specifics of a single page load, you could use a pre- and postload timestamp and only get entries within that timeframe.
The performance API mentioned in Hakello's answer is now well supported (on everything except IE & Safari), and is simple to use:
return performance
.getEntriesByType("resource")
.map((x) => x.transferSize)
.reduce((a, b) => (a + b), 0);
You can run that script using executeScript to get the number of bytes downloaded since the last navigation event. No setup or configuration is required.
Yes you can do it using BrowserMobProxy. This is a java jar which use selenium Proxy to track network traffic from client side.
like page load time duration, Query string to different services etc.
you can get it bmp.lightbody.net . This api will create .har files which will contain all these information in json format which you can read using
an online tool http://www.softwareishard.com/har/viewer/
I have achieved this in Python, which might save people some time. To setup the logging:
logging_prefs = {'performance' : 'INFO'}
caps = DesiredCapabilities.CHROME.copy()
caps['loggingPrefs'] = logging_prefs
driver = webdriver.Chrome(desired_capabilities=caps)
To calculate the total:
total_bytes = []
for entry in driver.get_log('performance'):
if "Network.dataReceived" in str(entry):
r = re.search(r'encodedDataLength\":(.*?),', str(entry))
total_bytes.append(int(r.group(1)))
mb = round((float(sum(total_bytes) / 1000) / 1000), 2)

How to start two or more custom URL Protocol from Javascript

I have an old html page that creates a script file and executes it using:
fsoObject = new ActiveXObject("Scripting.FileSystemObject")
wshObject = new ActiveXObject("WScript.Shell")
I am trying to modify it and make it usable also from other browsers. If you know the answer stop reading and please answer. If there is no quick answer, here is the description of my attempts. I was successful in doing the job, but only when the script is shorter than 2000 characters. I need help for scripts longer than 2000 characters.
The webpage is for internal use only, so it is easy for me to create a custom URL protocol on each computer that runs a VBScript file from a network drive.
I created my custom URL Protocol that starts a VBScript file like this:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\MyUrlProtocol]
"URL Protocol"=""
#="Url:MyUrlProtocol"
"UseOriginalUrlEncoding"=dword:00000001
[HKEY_CLASSES_ROOT\MyUrlProtocol\DefaultIcon]
#="C:\\Windows\\System32\\WScript.exe"
[HKEY_CLASSES_ROOT\MyUrlProtocol\shell]
[HKEY_CLASSES_ROOT\MyUrlProtocol\shell\open]
[HKEY_CLASSES_ROOT\MyUrlProtocol\shell\open\command]
#="C:\\Windows\\System32\\WScript.exe \"X:\\MyUrlProtocol.vbs\" \"%1\""
In MyUrlProtocol.vbs I have this:
MsgBox "The length of the link is " & Len(WScript.Arguments(0)) & " characters"
MsgBox "The content of the link is: " & WScript.Arguments(0)
When I click on click me I see two messages, so everything works well (tested with Chrome and IE in Windows 7.)
It works also when I execute document.getElementById("test").click()
I thought this could be the solution: I would pass the text of the script to the VBS static script, which would create the dynamic script and run it, but with this system I can't pass more than ~2000 characters.
So I tried to split the text of the script in chunks smaller than 2000 characters and simulate several clicks on the link, but only the first one works.
So I tried with xmlhttp.open("GET","MyUrlProtocol:test",false);, but Chrome says Cross origin requests are only supported for HTTP.
Is it possible to pass more than 2000 characters to a VBScript script via a custom URL protocol?
If not, is it possible to call several custom URL protocols in sequence?
If not, is there another way to create a script file and run it from Javascript?
EDIT 1
I found a solution, but in Chrome only works when it likes, so I'm back to square one.
The code below in IE executes the script 4 times (correct), but in Chrome only the first execution runs.
If I change it to delay += 2000, then Chrome usually runs the script 2 times, but sometimes 1 and sometimes 3 or even 4 times.
If I change it to delay += 10000, then it usually runs the script 4 times, but sometimes misses one.
The function is always executed 4 times, both in Chrome and IE. What is weird is that the sr.click() sometimes does nothing and the function execution continues.
<HTML>
<HEAD>
<script>
var delay;
function runScript(text) {
setTimeout(function(){runScript2(text)}, delay);
delay += 100;
}
function runScript2(text) {
var sr = document.getElementById('scriptRunner');
sr.href='intelliclad:'+text;
sr.click();
}
function test(){
delay = 0;
runScript("uno");
runScript("due");
runScript("tre");
runScript("quattro");
}
</script>
</HEAD>
<BODY>
<input type="button" value="Run test" onclick="test()">
scriptRunner
</BODY>
</HMTL>
EDIT 2
I tried with Luke's suggestion of setting the next timeout from inside the call back but nothing changed (IE works always, Chrome whenever it likes).
Here is the new code:
var scripts;
var delay = 2000;
function runScript() {
var sr = document.getElementById('scriptRunner');
sr.href = 'intelliclad:' + scripts.shift();
sr.click();
if(scripts.length)
setTimeout(function() {runScript()}, delay);
}
function test(){
scripts = ["uno", "due", "tre", "quattro"];
runScript();
}
Some background: The page asks for the shape of a panel, which can be just a few parameters [nfaces=1, shape1='square', width1=100] or hundreds of parameters for panels with many faces, many slots, many fasteners, etc. After asking for all the parameters a script for our internal 3D CAD (which can be larger than 20KB) is generated and the CAD is started and asked to execute the script.
I would like to do all on the client side, because the page is served by a Domino web server, which can't even dream of managing such a complex script.
I didn't read your whole post...have an answer:
I too wish that custom url protocols can handle long urls. They simply do not. IE is even worse as some OSs only accept 800 chars.
So, here's the solution:
For long urls, only pass a single use token. The vbscript uses the token
and does a url get to your web server to get all of the data.
This is the only way I've been able to successfully pass lots of data around. If you ever find a clearer solution, please remember to post it here.
Update:
Note that this is the best way I have found to deal with the url protocol limitations. I too wish this was not necessary. This does work and works well.
You mentioned Dominos, so possibly you need something in a POS environment... I create a web based POS system, so we could face a lot of the same issues.
Suppose you want a custom url to print a pdf to the default printer without the annoying popup window. We need to do this thousands of times a day...
When building the web page, add the print button which when pressed calls the custom url: myproto://printpdf?id=12345&tocken=onetimetoken
this will execute your vbscript on the local desktop
in your vbscript, parse the arguments and react. In this case, your command is printpdf and the id is 123456 and you have a onetime tocken key.
have the vb script to an https get to: https://mydomain.com/APIs/printpdf.whatever?id=12345&key=onetimetoken
check the credentials based on the ip address and token, if all aligns, then return the contents of the pdf (you may want to convert the pdf to a byte array string)
now the vbscript has the pdf, assemble it and write it to a temp folder then execute a silent pdf print command (I use Sumatra PDF http://blog.kowalczyk.info/software/sumatrapdf/free-pdf-reader.html)
mission accomplished.
Since I do know what you what to do in your custom url and the general workflow, I can only describe how I've solved the sort url issue.
Using this technique, the possibilities are limitless. You have full control over the local computer running the web browser, you have a onetime use token which grants access to a web API with can return any sort of information you program.
You could write a custom url protocol to turn on the pizza oven if you wanted :)
If you are not able to create the server side code which is listening for vbscript's get request then this would not work.
You might be able to pass the data from the browser to the vbscript using the clipboard.
Update 2:
Since in this case the data is on the client (one single form can define hundreds of parameters), the server API doesn't know what to answer to the vb script request. So the workflow described above must be preceded by these two steps:
The onkeypress event executes a submit to send the current parameters to the server
The server replies with the refreshed form, adding to the body onload a call to a function which uses another submit to call the custom url, as described on point 1 listed above.
Update 3:
stenci, what you've added (in Update 2) will work. I would do it like this:
user presses a button saying I'm done editing the form
ajax post the form to the server
the server saves the data and attaches unique key to the datastore
the server returns the key to ajax callback function
now the client has a single use key and invokes the url schema passing the key
vbscript does an https get to the server and passes the key
server returns the data to the vbscript
It is a bit long winded. Once coded it will work like a charm.
The only other alternative I can see is to copy the form data to the clipboard using something like: http://zeroclipboard.org/
and then in vbscript see if you can read the clipboard like: Use clipboard from VBScript
How about creating an iFrame for each instance?
Something like this:
function runScript(text) {
var iframe = document.createElement('iframe');
iframe.src = 'intelliclad:'+text;
document.body.appendChild(iframe);
}
function test(){
runScript("uno");
runScript("due");
runScript("tre");
runScript("quattro");
}
You can then use css styling to make these iframes transparent / hidden.
You might not like this answer, but I've used this method in the past and it works.
Instead of relying on ActiveX, consider using a Java Applet, and JNI.
Basically, you have to make sure the native scripts you want to run are available on your client machine, along with a JNI wrapper.
The applet will have to be at least self signed, for the browser to allow it to load and access a native library. Once the JNI libraries are loaded, you can easily call methods from the page / applet.
As a consequence of using Java, you could possibly use the same applet for windows as well as linux clients, provided of course you have native libraries present on the respective clients.
This series of articles talks about precisely your problem : http://www.javaworld.com/article/2076775/java-security/escape-the-sandbox--access-native-methods-from-an-applet.html
P.S the article is really old, but the concept remains unchanged.

How to prevent the browser using a cached image?

I am creating a pseudo video in a HTML document by updating the source of an <img> element 30 times a second with a new "frame" I get from a URL on my LAN (an IP security camera).
In Firefox the image seems to be cached so every time I try to get a new "frame", it shows the first one it got after starting the script.
In WebKit browsers (Chrome & Safari) the image I'm downloading is NOT cached, so every few ms the "video" is updated and it looks like an actual video. This is what I want in Firefox.
I have no control over the source of the video. I cannot add a GET parameter to force a re-download because the image that is sent back to me is returned empty when I try it (the server must have specific settings to disable them for security or something).
Is there a workaround while keeping this method? Is there a better method (keep in mind I have NO control over the source - this is the only way to view the video!).
My script (be prepared - it's very rushed)
Just add a timestamp or random number to the end of the image url. This will bypass the caching. Something like:
url += 'c'+ ~~(Math.random() * 10000);
EDIT - Exactly what methods have you tried? Your scriptuses image.src to load the image. Have you tried XHR? If you have, please post that code.
To the best of my knowledge you have two options:
1) Alter the header - Can be done via an intermediary server. If you have a local proxy or are in a position add one, you could possibly use it to tamper with the headers. A tad excessive either way.
2) XHR - While I'd expect XHR to behave similarly to your present approach, there is no guarantee that it will. As such it's worth at least investigating.
Add a cache busting parameter to the source address:
container.src = camerasrc + '/cgi-bin/video.jpg' + '?bust=' + (new Date()).getTime();

Can I use the browser Navigation Timing API for Ajax events in single page apps? If not, what's a good tool?

We've got a single page app built with Knockout and Backbone which makes Ajax calls to the server and does some complex data caching and DOM rendering. We're really like to measure the performance (and log it back to the server) as seen by the user. I can't seem to get my head wrapped around whether the browser Navigation Timing API is going to be useful for this or not. From what I see in examples, the Navigation Timing API is tied to window.performance and this is limited to the page load and not suitable for monitoring Ajax behavior. True or false? If false, what else can I use?
I'd love to set custom instrumentation points between which to measure time, e.g. for an Ajax call that does some DOM rendering with a server result.
1 - True, window.performance is tied to page load. See example below which shows this:
<button id='searchButton'>Look up Cities</button>
<br>
Timing info is same? <span id='results'></span>
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script type="text/javascript">
jQuery('#searchButton').on('click', function(e){
// deep copy the timing info
var perf1 = jQuery.extend(true, {}, performance.timing);
// do something async
jQuery.getJSON('http://ws.geonames.org/searchJSON?featureClass=P&style=full&maxRows=10&name_startsWith=Denv', function() {
// get another copy of timing info
var perf2 = jQuery.extend(true, {}, performance.timing);
// show if timing information has changed
jQuery('#results').text( _.isEqual( perf1, perf2 ) );
});
return false;
});
</script>
Also, even if you did get it working you'd have missing data from old browsers that don't support this object.
2 - The Boomerang project seems to go beyond the web timing API and also supports older browsers. There is a talk with slides and sample code by the current maintainer listed in this conference. Sorry no direct link.
You can now use the User Timing API (W3C Recommendation 12 December 2013) which provides a way that you can insert API calls at different parts of your Javascript and then extract detailed timing data.
You do that using mark(), it lets you work out how much time it took you hit that ‘mark’ in your web application, and then measure() to calculate the time elapsed between your marks.
For your specific case you can have something like this:
app.render = function(content){
myEl.innerHTML = content;
window.performance.mark('end_render');
window.performance.measure('measure_render', 'start_xhr', 'end_render');
};
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onload = function(e) {
window.performance.mark('end_xhr');
window.performance.measure('measure_xhr', 'start_xhr', 'end_xhr');
app.render(e.responseText);
}
window.performance.mark('start_xhr');
myReq.send();
There seems to be patchy support for window.performance.getEntries(), which will give you details of all resources loaded into a page along with their URLs. I use this API for jsonp (not XMLHttpRequest) requests in AzurePing.info for the browsers that support it, falling back to new Date().getTime() for those that don't.
At time of writing, IE 10 and Chrome support getEntries, but Firefox does not. Unfortunately, not all the timing properties are set - even in Chrome and IE. All I could rely on was a fetchStart, responseEnd, and duration.
Sample source is on GitHub.
The Navigation Timing API is in my opinion not really helpful when it comes to measuring single page application performance.
Along with the already mentioned User Timing API, the Resource Timing API is actually much more helpful. This API provides functionality to retrieve the timings for all requests made in a user session (actually all you see in the network tabs of the developer tools in most browsers). These timings include Round-Trip times as well as DNS-lookup times etc.
Unfortunately, this is a relatively new specification and is not yet implemented accross all browsers. Chrome and IE > 10 provide implementations (although not yet complete). Surprisingly, IE seems to have implemented the most unitl now...
There are two ways to do it
Resource Timing API
Wrapping XMLHTTPRequest
Lets see the differences between them.
1. Resource Timing API
Browsers add supports for Resource Timing API recently. Resource Timing API basically has timing information about each and every resources loaded from app. It may be css, javascript or AJAX requests. You can get list of resources details as
performance.getEntriesByType('resource');
It will return array of object where you can find AJAX requests by initiatorType which is equal to xmlhttprequest. But there are some limitation.
By default, maximum resource size is 150. Above array only have maximum of 150 resources. If you want more, you can increase buffer size as performance.setResourceTimingBufferSize(500).
You will not get information about whether the AJAX requests is succeed or failed.
2. Wrapping XMLHTTPRequest
If you can wrap your XMLHTTPRequest API, you will get all information that you need from timing, status code and byte size. But you have to write lot of code and ofcourse test, test and test.
[Disclaimer] I work for atatus.com where we help you to measure page load time, AJAX timing and custom transaction. Also you can see session traces about how each and every resources perform.

Categories