localStorageTest stores an incrementally increasing value in localStorage until it hits the localStorage size limits of the browser.
function localStorageTest(key, len) {
var value = window.localStorage.getItem(key);
value = (value == null)?"":value;
var numIters = len - value.length;
while(numIters--) {
value += "1";
window.localStorage.setItem(key, value);
if (window.localStorage.getItem(key) != value) {
console.log("limit reached at " + (value.length-1).toString() + " bytes");
break;
}
}
console.log("stored " + value.length + " bytes");
}
Chrome:
localStorageTest("1", 80000);
<browser crashed>
Firefox:
localStorageTest("1", 50000);
<browser crashed>
Suspecting an increased usage of browser memory, I wrote localStorageIncrementalTest which does the same thing as localStorageTest, but puts idle periods of 5 seconds in between its operations, using a setTimeOut call.
var increment = 5000;
function localStorageIncrementalTest(key, len) {
var value = window.localStorage.getItem(key);
value = (value == null)?"":value;
var numIters = len - value.length;
var limitReached = false;
while(numIters--) {
value += "1";
window.localStorage.setItem(key, value);
if (window.localStorage.getItem(key) != value) {
console.log("limit reached at " + (value.length-1).toString() + " bytes");
limitReached = true;
break;
}
}
console.log("stored " + value.length + " bytes");
if (!limitReached) {
setTimeout(function() {
localStorageIncrementalTest(key, len+increment);
}, 5000);
}
}
Chrome :
localStorageIncrementalTest("1", 30000);
stored 30000 bytes
stored 35000 bytes
...
stored 1800000 bytes
<browser crashed>
Firefox :
localStorageIncrementalTest("1", 30000);
stored 30000 bytes
stored 35000 bytes
...
stored 60000 bytes
<browser crashed>
So localStorageIncrementalTest allows us to store more in localStorage than localStorageTest before crashing the browser.
Can anyone explain the reasons behind the browser crash, and a possible solution to avoid the same ?
I'm using Chrome 28.0.1500.71, and Firefox 26.0
Update :
function getRandomValue(size) {
var value = "";
for (var i = 0; i < size; i++) {
value += Math.ceil(Math.random()*5);
}
return value;
}
function localStorageTest2() {
for (var i = 0; i < 70000; i++) {
window.localStorage.setItem("1", getRandomValue(20000));
}
}
Chrome :
localStorageTest2();
<browser crashed>
Firefox :
localStorageTest2();
<browser crashed>
Testing localStorage2 too caused the browser to crash.
I am not sure why the browsers crash, but it is worth reporting it at crbug.com and bugzilla.mozilla.com.
However, localStorage is not meant for this kind of usage. It is a synchronous API which puts a lot of strain on the browser when it is used, especially when it is used so frequently and will cause the page to perform badly in general.
Also, your test would not yield the right results - setItem(x, y) would throw an exception when you exceed the limit. localStorage.setItem(x, y); if (y == localStorage.getItem(x)) { ... } will never reach the if part, because it will throw an exception beforehand when the limit is reached.
The alternatives are simple variables, server storage or IndexedDB.
Chrome also has the FileSystem API and the Web SQL Databases API, but it is best not to rely on those, because they are not supported in other browsers.
Related
I didn't do a great job of explaining the problem. The hanging behavior seems to be related to the use of console logging (with either Logger.log or console.log statements). If I comment out the logging statements, the hanging behavior does not occur. So, if I put in a breakpoint, the looping code will stop at the breakpoint one or a few times after clicking Resume and then just hang without getting back to the breakpoint. The number of successful times hitting the breakpoint before the hanging behavior occurs seems to be random. So, it seems that the problem is related to there being console logging in the loop. If I remove the logging statements, the hanging behavior does not occur. Thanks for any suggestions, here.
I have a loop that hangs in the debugger when a breakpoint{s) are set (but seemingly not when there are no breakpoints set). I've tried putting breakpoints in at various locations and then step over the breakpointed statement and then continue execution. Sometimes (randomly) it just never returns to the breakpoint and just runs forever (until timeout). Here's my code. Can anybody see what's going on. Thanks.
function getHikesDataByMonth() {
var firstHikeMonth = events[1][0].getMonth();
var thisHikeMonth = firstHikeMonth;
//var hikesColumn = firstHikeMonth;
var hikeDate, hikeDay,hikeName, hikeLevel, hikeNameShort;
var hikeMonth, newHikeMonth;
var eventRow = 1;
var hikeRow = 0;
var participantNumber = 0;
var numParticipants;
var hikeData = [];
var hikesColumn = [];
var hikeDate, hikeName, hikeNameShort, hikeLevel;
Logger.log("events.length " + events.length)
while (eventRow < events.length) {
//if (events[eventRow][4].isBlank) { break;}
if ((!events[eventRow][4].includes("hike") && !events[eventRow][4].includes("Hike") && !events[eventRow][4].includes("HIKE")) || events[eventRow][4].includes("CANCEL")) {
eventRow += 1;
continue;
}
// found a hike
console.log("Found Hike: " + events[eventRow][4]);
hikeName = events[eventRow][4];
hikeMonth = events[eventRow][0].getMonth() - firstHikeMonth;
if (hikeMonth > thisHikeMonth - firstHikeMonth) {
newHikeMonth = true;
thisHikeMonth = hikeMonth;
} else {
newHikeMonth = false;
}
hikeLevel = getHikeLevel(hikeName);
hikeNameShort = getHikeNameShort(hikeName);
hikeDate = events[eventRow][0];
hikeDay = weekDayNames[hikeDate.getDay()];
hikeData.push(hikeDay);
hikeData.push(hikeDate.toLocaleDateString('en-US'));
hikeData.push(hikeName)
hikeData.push(hikeNameShort);
hikeData.push(hikeLevel);
hikeData.push("");
hikeData.push("");
//hikeRowArray[0] = hikeRow;
//hikeData[hikeRow] = hikeRow;
console.log("Getting Participants: " + hikeName)
while (events[eventRow][4] == hikeName){
if (events[eventRow][9] != "Paid") {
eventRow += 1;
continue;
}
hikeData.push(events[eventRow][6] + " " + events[eventRow][5]);
eventRow += 1;
participantNumber += 1;
}
numParticipants = participantNumber
for (var i = participantNumber+1; i < 30; i++){
hikeData.push("");
}
//Logger.log(hikeParticipants[participantNumber]);
hikeData.push(numParticipants < 15 ? "Yes" : "No");
hikeData.push(15 - numParticipants);
// That's all for that hike - go to next hike
participantNumber = 0;
eventRow += 1;
hikeData.push(hikeData);
hikesColumn.push(hikeData);
console.log("Going to next hike at eventRow:" + eventRow)
if (newHikeMonth) {
hikesDataByMonth.push(hikesColumn);
}
}
}
I'm wondering how website like this one : https://ping.eu/ping/ manage to make our ip ping an other ip and get the result.
Someone have an idea ?
Thanks
It Doesn't. A PHP script(on the server) will most likely do it with "PHP Sockets". Have a look at
this: https://www.php.net/manual/en/sockets.examples.php
Else it could use exec() function, but that would be a security flaw.
So to answer your question: The website will ping the IP address not the 'client'
If you want to ping a server, i.e. an actual web address/URL like www.google.com, you can look at this JSFiddle http://jsfiddle.net/GSSCD/203/ or GitHub repository https://github.com/jdfreder/pingjs.
Here's some code from the JSFiddle:
function Pinger_ping(ip, callback) {
if(!this.inUse) {
this.inUse = true;
this.callback = callback
this.ip = ip;
var _that = this;
this.img = new Image();
this.img.onload = function() {_that.good();};
this.img.onerror = function() {_that.good();};
this.start = new Date().getTime();
this.img.src = "http://" + ip;
this.timer = setTimeout(function() { _that.bad();}, 1500);
}
}
Another way to ping a server/web address is to use JavaScript and the XMLHttpRequest() function it supports:
HTML:
<div id="result"></div>
JavaScript:
function http_ping(fqdn) {
var NB_ITERATIONS = 4; // number of loop iterations
var MAX_ITERATIONS = 5; // beware: the number of simultaneous XMLHttpRequest is limited by the browser!
var TIME_PERIOD = 1000; // 1000 ms between each ping
var i = 0;
var over_flag = 0;
var time_cumul = 0;
var REQUEST_TIMEOUT = 9000;
var TIMEOUT_ERROR = 0;
document.getElementById('result').innerHTML = "HTTP ping for " + fqdn + "</br>";
var ping_loop = setInterval(function() {
// let's change non-existent URL each time to avoid possible side effect with web proxy-cache software on the line
url = "http://" + fqdn + "/a30Fkezt_77" + Math.random().toString(36).substring(7);
if (i < MAX_ITERATIONS) {
var ping = new XMLHttpRequest();
i++;
ping.seq = i;
over_flag++;
ping.date1 = Date.now();
ping.timeout = REQUEST_TIMEOUT; // it could happen that the request takes a very long time
ping.onreadystatechange = function() { // the request has returned something, let's log it (starting after the first one)
if (ping.readyState == 4 && TIMEOUT_ERROR == 0) {
over_flag--;
if (ping.seq > 1) {
delta_time = Date.now() - ping.date1;
time_cumul += delta_time;
document.getElementById('result').innerHTML += "</br>http_seq=" + (ping.seq-1) + " time=" + delta_time + " ms</br>";
}
}
}
ping.ontimeout = function() {
TIMEOUT_ERROR = 1;
}
ping.open("GET", url, true);
ping.send();
}
if ((i > NB_ITERATIONS) && (over_flag < 1)) { // all requests are passed and have returned
clearInterval(ping_loop);
var avg_time = Math.round(time_cumul / (i - 1));
document.getElementById('result').innerHTML += "</br> Average ping latency on " + (i-1) + " iterations: " + avg_time + "ms </br>";
}
if (TIMEOUT_ERROR == 1) { // timeout: data cannot be accurate
clearInterval(ping_loop);
document.getElementById('result').innerHTML += "<br/> THERE WAS A TIMEOUT ERROR <br/>";
return;
}
}, TIME_PERIOD);
}
But, of course, these are web addresses, not IP addresses, so I'm not sure if that's what you're aiming for. I'm also not sure if you're looking for the amount of time spent to get the connection and the number of packets and bytes sent and received, or if you just want to validate the connection. The above code does all of those things. For IP addresses, you can try an AJAX request to ping a server, which only sees if there is a connection using YOUR SERVER'S IP address, NOT THE USER'S CLIENT, like this:
client --AJAX-- yourserver --ICMP ping-- targetservers
You could also try:
Using a Java applet with isReachable
Writing a server-side script which pings, and using AJAX to communicate to your server-side script
You might also be able to ping in Flash (using ActionScript)
One last hypothetical and unorthodox way to get an IP address is to inspect and view the source of the website you mentioned and copy some code, mostly JavaScript, and test it on your end and try to implement it.
I am using JSON and YQL to access some data from an external domain.
http://jsfiddle.net/NdkPU/22/
But the problem I am having is that the code only works intermittently, sometimes I get a response, sometimes nothing is returned.
Obviously this is a very slow solution to access this data - so one reason I thought might be that it is timing out or there is a problem with the callback function.
Any ideas why the result is not working all the time?
// Start function when DOM has completely loaded
$(document).ready(function(){
requestCrossDomain("http://api.fool.com/caps/ws/Ticker/GOOG/Pitches/10?apikey=rW3550aXdsuJPg4bKEemC13x39jDNR6f", function (result) {
var num = 1;
var browserName = navigator.appName;
var doc;
if (browserName == 'Microsoft Internet Explorer') {
doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = 'false'
doc.loadXML(result.results);
} else {
doc = (new DOMParser()).parseFromString(result.results, 'text/xml');
}
var xml = doc;
console.log("Data Loaded: " + xml);
// Build an HTML string
myHTMLOutput = '';
myHTMLOutput += '<table width="98%" border="1" cellpadding="0" cellspacing="0">';
myHTMLOutput += '<th>Text</th>';
// Run the function for each student tag in the XML file
$('Pitch',xml).each(function(i) {
PitchText = $(this).find("Text").text();
// Build row HTML data and store in string
mydata = BuildStudentHTML(PitchText);
myHTMLOutput = myHTMLOutput + mydata;
});
myHTMLOutput += '</table>';
myHTMLOutput += '<br>Rating: ';
myHTMLOutput += $('Ticker',xml).attr("Percentile");
// Update the DIV called Content Area with the HTML string
$("#ContentArea").append(myHTMLOutput);
});
});
function BuildStudentHTML(PitchText){
// Build HTML string and return
output = '';
output += '<tr>';
output += '<td>'+ PitchText + '</td>';
output += '</tr>';
return output;
}
// Accepts a url and a callback function to run.
function requestCrossDomain(site, callback) {
// If no url was passed, exit.
if (!site) {
alert('No site was passed.');
return false;
}
// Take the provided url, and add it to a YQL query. Make sure you encode it!
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from xml where url="' + site + '"') + '&format=xml&callback=?';
// Request that YSQL string, and run a callback function.
// Pass a defined function to prevent cache-busting.
$.getJSON(yql, cbFunc);
function cbFunc(data) {
// If we have something to work with...
if (data.results[0]) {
if (typeof callback === 'function') {
callback(data);
}
}
// Else, Maybe we requested a site that doesn't exist, and nothing returned.
else throw new Error('Nothing returned from getJSON.');
}
}
It looks like it's just a slow API. I wrote a simple bash loop that timed that query using curl, and here were the timings:
7.4 sec
11.1 sec
11.2 sec
7.4 sec
11.1 sec
7.3 sec
10.2 sec
11.8 sec
11.3 sec
7.1 sec
I need to determine which connection type a device is using.
Distinguishing between WIFI and 3G doesn't seem to be a problem on iOS (using the NetworkInfo ANE) and Android (using the native NetworkInfo class) but I've got no clue how to further distinguish between a fast (3G, 4G) and slow (EDGE) connection.
Is there a way to do this with Adobe Air?
Try this for detecting Mobile vs. Wifi on iOS. This requires the Adobe native extension "NetworkInfo"
import com.adobe.nativeExtensions.Networkinfo.InterfaceAddress;
import com.adobe.nativeExtensions.Networkinfo.NetworkInfo;
import com.adobe.nativeExtensions.Networkinfo.NetworkInterface;
var vNetworkInterfaces:Object;
if (flash.net.NetworkInfo.isSupported)
{
vNetworkInterfaces = getDefinitionByName('flash.net.NetworkInfo')['networkInfo']['findInterfaces']();
mytrace("fall 1" );
}
else
{
vNetworkInterfaces = getDefinitionByName('com.adobe.nativeExtensions.Networkinfo.NetworkInfo')['networkInfo']['findInterfaces']();
mytrace("fall 2" );
}
var hasWifi: Boolean = false;
var hasMobile: Boolean = false;
for each (var networkInterface:Object in vNetworkInterfaces)
{
if ( networkInterface.active && (networkInterface.name == "en0" || networkInterface.name == "en1") ) hasWifi = true;
if ( networkInterface.active && (networkInterface.name == "pdp_ip0" || networkInterface.name == "pdp_ip1" || networkInterface.name == "pdp_ip2") ) hasMobile = true;
mytrace( "active: " + networkInterface.active );
mytrace( "displayName: " + networkInterface.displayName );
mytrace( "name: " + networkInterface.name );
mytrace( "hwAddress: " + networkInterface.hardwareAddress );
mytrace( "--------------------" );
}
mytrace( "has Mobile Internet: " + hasMobile );
mytrace( "has Wifi Internet: " + hasWifi );
I dunno if there's a solution a direct solution but when you're downloading a file you could check the speed at which file is downloaded, by using getTimer function in conjunction with loaded bytes and a ratio of total bytes.
Example
function init()
{
startTime = getTimer();
loader = new Loader();
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoaderInit);
loader.load("some-site.com/myasset.png");
}
function onLoaderInit(e:ProgressEvent)
{
$timePassed = (getTimer() - startTime) * 0.001; //it's in millisecounds convert to secounds
$newBytes = loader.contentLoaderInfo.bytesLoaded - oldBytes;
var $rate:Number = $newBytes * $timePassed; //returns a value of bytes per sec.
startTime = getTimer();
oldBytes = loader.contentLoaderInfo.bytesLoaded;
}
Nice... if it works... dunno if there's a solution a direct solution but when you're downloading a file you could check the speed at which file is downloaded, by using getTimer function in conjunction with loaded bytes and a ratio of total bytes
has anyone noticed or found a solution to the problem I've been experiencing? It takes a long time to render large fonts (>100px) in Chrome on the canvas using fillText(). I need to have a much faster frame rate, but once the fonts get big it take like a second to load each frame. In firefox it runs well though...
UPDATE:
Here is the pertinent code that is running in my draw() function which runs every 10 milliseconds on interval. If anything pops out to you, that would be great. I'll try to profiler thing though, thanks.
g.font = Math.floor(zoom) + "px sans-serif";
g.fillStyle = "rgba(233,233,245," + (ZOOM_MAX-zoom*(zoom*0.01))/(ZOOM_MAX) + ")";
for (h=0; h<76; h++)
{
h_offset = 2.75*h*Math.floor(zoom);
// only render if will be visible, because it tends to lag; especially in Chrome
hpos = Math.floor(half_width + std_offset + h_offset);
if (hpos > (-half_width)-h_offset && hpos < WIDTH+h_offset)
{
g.fillText(1950+h, hpos, anchor_y - 0);
}
}
g.font = "600 " + Math.floor(zoom/40) + "px sans-serif";
g.fillStyle = "rgba(233,233,245," + (ZOOM_MAX-zoom*(zoom*0.0001))/(ZOOM_MAX) + ")";
for (h=0; h<76; h++)
{
h_offset = 2.75*h*Math.floor(zoom);
hpos = Math.floor(half_width + std_offset + h_offset);
if (hpos > (-half_width)-h_offset && hpos < WIDTH+h_offset)
{
// see if we should bother showing months (or will it be too small anyways)
if (zoom/40 > 2)
{
// show months
for (i=0; i<12; i++)
{
i_offset = 0.175*i*zoom;
ipos = Math.floor(WIDTH/2 + std_offset + i_offset + h_offset) + 10;
if (ipos > -half_width && ipos < WIDTH)
{
g.fillText(months[i], ipos, anchor_y - 20);
}
}
}
}
}
g.font = "600 " + Math.floor(zoom/350) + "px sans-serif";
g.fillStyle = "rgba(233,233,245," + (ZOOM_MAX-zoom/5)/(ZOOM_MAX*2.25) + ")";
for (h=0; h<76; h++)
{
h_offset = 2.75*h*Math.floor(zoom);
// only render if will be visible, because it tends to lag; especially in Chrome
hpos = Math.floor(half_width + std_offset + h_offset);
if (hpos > (-half_width)-h_offset && hpos < WIDTH+h_offset)
{
// see if we should bother showing months (or will it be too small anyways)
if (zoom/40 > 2)
{
// show months
for (i=0; i<12; i++)
{
i_offset = 0.175*i*zoom;
ipos = Math.floor(WIDTH/2 + std_offset + i_offset + h_offset) + 10;
// see if we should bother showing days (or will it be too small anyways)
if (zoom/350 > 2)
{
// show days
for (j=0; j<31; j++)
{
j_offset = 0.005*j*zoom + zoom*0.005;
jpos = Math.floor(half_width + std_offset + j_offset + i_offset + h_offset);
if (jpos > -half_width && jpos < WIDTH)
{
g.fillText(days[i][j], jpos, anchor_y - 20);
selected_days += 'm: '+i+', d: '+j+' | ';
}
}
}
}
}
}
}
We'd need a lot more information, I'm not convinced that drawing a large font is actually whats causing the performance issues. Drawing such a large font works extremely quickly on my machines for any browser that I've tried.
The first thing you should do is open up the Chrome profiler and then run the code, and see if it is actually the ctx.fillText call that is taking up the time. I imagine its actually something else.
It's possible you are calling something too much, like setting ctx.font over and over unnecessarily. Setting ctx.font on some browsers actually takes significantly longer to do than calls to fillRect! If your font changes in the app you can always cache.
Here's a test back from October: http://jsperf.com/set-font-perf
As you can see, in many versions of Chrome setting the font unnecessarily doubles the time it takes! So make sure you set it as little as possible (with caching, etc).