I would like to evaluate the execution time of the processes contained in a javascript function, so I created a simple code that can evaluate this.
I would like your opinion as experts and know if I can use the code to evaluate the execution time of much more complex processes.
I tried it on IE, FF and Chrome, and Chrome processes were faster.
LINK TO THE EXPERIMENT
This is my Javascript:
/* Global Vars */
var inputSearch = document.getElementById('texto');
var buscando = document.getElementById('buscando');
/* TIME PERFORMANCE > Catching */
var timer = document.getElementById('timer');
var maxtimer = document.getElementById('maxtimer');
var qmaxtimer = document.getElementById('querymaxtimer');
/* Adding Event */
if(window.addEventListener)
{inputSearch.addEventListener('keyup',searching,false);}
else
{if(window.attachEvent){inputSearch.attachEvent('keyup',searching);}}
/* Test Function */
function searching(event,callback)
{
/* TIME PERFORMANCE */
/* >> Timer Ini */
var i = performance.now();
/* Do something........ */
var query = this.value;
buscando.textContent = query;
/* Finish something ......... */
/* TIME PERFORMANCE */
/* >> Timer End */
var f = performance.now();
/* >> TotalTime */
var totalTime = f - i;
var t;
if(totalTime < 1){
if(totalTime<=0.0001){t= ' Nanoseconds?';}
else{t= ' Microseconds';}
}else{t = ' Miliseconds'};
/* >> Max Time */
var mt = parseFloat(maxtimer.textContent);
if(totalTime > mt){
maxtimer.textContent = totalTime.toFixed(15) + t;
qmaxtimer.textContent=query;
}
/* >> Current Time */
timer.textContent = totalTime.toFixed(15) + t;
}
Thank you.
P.D.: Sorry for my bad english :-)
These kind of measurements can never be truly achieved via editing the code. First of all, it might be too difficult to just edit each and every method in your code to add those timing calls, secondly, you might be breaking stuff in the process.
I would suggest you to use the Performance tools present in both Firefox and Chrome, via these, you can measure time spent in various parts of your code along with the bottlenecks etc.
You can also see where your UI froze, and what code was super efficient.
Firefox : https://developer.mozilla.org/en-US/docs/Tools/Profiler
Chrome : https://developer.chrome.com/devtools/docs/timeline
Related
A online tool, such as JSCompress, will reduce code size up to 80%. It's easy to notice that the result, compressed code, removes space. Beyond the removal of EOL and ' ' characters, is there any other trickery needed to minify a js file?
Example compressed:
function glow(e){$("#"+e).fadeIn(700,function(){$(this).fadeOut(700)})}function startLevel(){ptrn=[],pos=0,setLevel(lvl),$("#mg-lvl").fadeOut("slow",function(){$("#mg-contain").prop("onclick",null).off("click"),$("#mg-contain").css("cursor","default"),$(this).text("Level "+lvl+": "+ptrn.length+" blink(s)."),$(this).fadeIn("slow"),showLevel(0)})}function setLevel(e){ptrn.push(Math.floor(3*Math.random()+1)),0==e||setLevel(--e)}function showLevel(e){$("#b"+ptrn[e]+"c").fadeOut(speed,function(){$("#ball_"+ptrn[e]).fadeOut(speed,function(){$("#b"+ptrn[e]+"c").fadeIn(speed),$(this).fadeIn(speed,function(){e+1<ptrn.length&&showLevel(++e,speed)})})}),e+1==ptrn.length&&setTimeout(bindKeys(1),ptrn.length*speed+15)}function bindKeys(e){for(var e=1;e<4;e++)bind(e)}function bind(e){$("#ball_"+e).on("click",function(){$("#b"+e+"c").fadeOut(speed,function(){$("#ball_"+e).fadeOut(speed,function(){$("#ball_"+e).fadeIn(speed),$("#b"+e+"c").fadeIn(speed),referee(e)&&unbind()})})})}function referee(e){if(pos<ptrn.length&&(e===ptrn[pos]?$("#mg-score").text(parseInt($("#mg-score").text())+1):end()),++pos==ptrn.length)return++lvl,speed-=40,!0}function unbind(){for(var e=1;e<4;e++)$("#ball_"+e).off();startLevel()}function nestedFade(e,n,t){e[n]&&$(e[n]).fadeOut("fast",function(){t[n]&&($(e),t[n]),nestedFade(e,++n,t)})}function end(){for(var e=[],n=[],t=1;t<4;t++)e.push("#b"+t+"c"),e.push("#ball_"+t),n.push(null);e.push("#mg-contain"),n.push('.fadeOut("slow")'),e.push("#mg-obj"),n.push(".fadeOut('slow')"),e.push("#bg-ball-container"),n.push(".toggle()"),nestedFade(e,0,n)}var ptrn=[],pos=0,lvl=1,speed=400,b1=setInterval(function(){glow("ball_1b",700)}),b2=setInterval(function(){glow("ball_2b",700)}),b3=setInterval(function(){glow("ball_3b",700)});
Example uncompressed:
var ptrn = [];
var pos = 0;
var lvl = 1;
var speed = 400;
/* make balls glow */
function glow(id)
{
$('#'+id).fadeIn(700, function(){$(this).fadeOut(700);})
}
var b1 = setInterval(function(){ glow('ball_1b',700) ,1500});
var b2 = setInterval(function(){ glow('ball_2b',700) ,1500});
var b3 = setInterval(function(){ glow('ball_3b',700) ,1500});
/* end */
function startLevel()
{
ptrn = [];
pos = 0;
/* set pattern for the level */
setLevel(lvl);
/* display prompt for level */
$('#mg-lvl').fadeOut("slow", function(){
$('#mg-contain').prop('onclick',null).off('click');
$('#mg-contain').css('cursor','default');
$(this).text("Level " + lvl + ": " + ptrn.length + " blink(s).");
$(this).fadeIn('slow');
/* play back the pattern for user to play */
showLevel(0); //TODO: use promise and deferred pattern to pull this out of fade function.
});
}
function setLevel(lvl)
{
ptrn.push(Math.floor((Math.random() * 3) + 1));
(lvl == 0 ) ? null : setLevel(--lvl);
}
function showLevel(i)
{
/* blink the balls */
$('#b'+ptrn[i]+'c').fadeOut(speed, function(){
$('#ball_'+ptrn[i]).fadeOut(speed, function(){
$('#b'+ptrn[i]+'c').fadeIn(speed);
$(this).fadeIn(speed, function(){
if(i+1<ptrn.length)
showLevel(++i,speed);
});
});
});
if( (i+1) == ptrn.length)
setTimeout( bindKeys(1), ptrn.length*speed+15) //after the pattern is revealed bind the clicker
}
function bindKeys(i)
{
for(var i=1;i<4;i++)
bind(i);
}
function bind(i)
{
$('#ball_'+i).on('click', function() {
$('#b'+i+'c').fadeOut(speed, function() {
$('#ball_'+i).fadeOut(speed, function() {
$('#ball_'+i).fadeIn(speed);
$('#b'+i+'c').fadeIn(speed);
if(referee(i))
unbind();
});
});
});
}
function referee(val)
{
if(pos < ptrn.length){
( val === ptrn[pos] ) ? $('#mg-score').text(parseInt($('#mg-score').text())+1) : end();
}
if(++pos == ptrn.length)
{
++lvl;
speed-=40;
return true;
}
}
function unbind()
{
for(var i=1;i<4;i++)
$( "#ball_"+i).off();
startLevel();
}
function nestedFade(id,i,func)
{
(!id[i]) ? 0 : $(id[i]).fadeOut('fast',function(){ if(func[i])
{$(id)+func[i];};nestedFade(id,++i,func);})
}
function end()
{
var id = [];
var func = [];
for(var i=1;i<4;i++){
id.push('#b'+i+'c');
id.push('#ball_'+i);
func.push(null)
}
id.push('#mg-contain');
func.push('.fadeOut("slow")');
id.push('#mg-obj');
func.push(".fadeOut('slow')");
id.push('#bg-ball-container');
func.push(".toggle()");
nestedFade(id,0,func);
}
Saves 32% on file size...and if that is the case, is it a fair assumption then that writing less is doing more for the end user?
The same way you can 'minify' a file to reduce its size, you can also 'uglify' a file, which takes your code and shortens things like variable names to the same end: reduce file size by reducing the number of characters in it (not just removing line breaks and space characters).
While it will reduce loadtime for a user, it's not a great practice to write minified/uglified-style code off the bat. That's why in almost any professional build/deploy process, you take your clear, descriptive code and then run your build processes to reduce the size of your files and eventually deploy versions that your end user will have a quicker time loading. You can always write your regular code, then run a compression process like the one you described, save it into a "public" folder and upload that for users to have access to, rather than your fleshed out code.
All a minifier will do is remove white space, which like you said, is ' ' and EOL characters. I believe you may be thinking of file compression tools such as a .zip file with the way your question is worded. Such file types (.zip) will find common strings in your file, and put references to the original string rather than having it written out 10 times. Meaning if the string "I like cake" shows up 4 times in your file, it will have "I like cake" in one location, and the other three locations will reference that first location, shortening the length of the file and therefore decreasing its size.
Well the main reason JS, CSS and HTML get's minified is to decrease the size of the files transmitted from server to client when a client requests a webpage. This decrease in size will allow for a faster load time. So technically writing less is more for a webpages load time, but realistically the effect of you as a developer consciously writing shorter code to minimize file size will either a.) Be to minimal a change to actually make a difference or b.) lead to loss of functionality or bugs due to the focus being on cutting down code length, not code quality.
----EDIT the question was to long and to hard to understand------
Here is a working exemple : http://codepen.io/anon/pen/Mwapgb
WARNING : This will make firefox CRASH ! , if you dare, click around 500 time on any div (i suggest to use a tool to simulate it. Rip mouse)
But This http://codepen.io/anon/pen/eNNqde
Wont make firefox crash
What is the difference :
function GetDateFromDatetimePython(stringdate){ // IT CRASH
var partieDate = stringdate.split(' ');
var ymd = partieDate[0].split('-');
var hms = partieDate[1].split(':');
return new Date(Date.UTC(ymd[0],ymd[1]-1,ymd[2],hms[0],hms[1],hms[2],0));
}
function GetDateFromDatetimePython(stringdate){ // IT DON'T
var partieDate = stringdate.split(' ');
var tmp = partieDate[0]; // add this
var tmp2 = partieDate[1]; // add this
var ymd = tmp.split('-'); // change this
var hms = tmp2.split(':'); // change this
return new Date(Date.UTC(ymd[0],ymd[1]-1,ymd[2],hms[0],hms[1],hms[2],0));
}
I'm going crazy. What is wrong with the first practice ?
Ok , it's stupid to make 3 split, i could combined in 1 . Whenever. WHY does this blow up firefox , Why aren't Chrome nor IE affect ?
May be you are trapped into some infinite loop or a process is instantiated which involves heavy processing which drains all the memory available with your browser.
I'm working on a JavaScript game that involves throwing a snowball. I need the snowball to render as often as possible during its flight path. Chrome does all the calculations, including setting the style.left and style.top properties, but doesn't actually redraw the snowball until it reaches its destination. Opera doesn't have this problem.
A relevant point is that putting in an alert() after renderSnowball() fixes the problem, except using the alert() is an obvious issue.
Here's my code so far:
function throwSnowball()
{
var theta = parseFloat(angleField.value) * Math.PI/180 ;
var Vir = parseFloat(velocityField.value) ;
if (!isNaN(Vir) && !isNaN(theta) )
{
Vix = Math.cos(theta) * Vir * 50;
Viy = Math.sin(theta) * Vir * 50;
time = new Date() ;
var timeThrown = time.getTime() ;
while (snowballPosY > 0)
{
current = new Date() ;
var currentTime = current.getTime() ;
var timeElapsed = (currentTime - timeThrown)/5000 ;
snowballPosX += Vix * timeElapsed;
snowballPosY += Viy * timeElapsed;
Viy -= GRAVITY * timeElapsed ;
renderSnowball() ; //renderSnowball() sets the style.left
// and style.top properties to snowballPosX pixels
// and snowballPosY pixels respectively
timeThrown = currentTime ;
}
snowballPosX = 0 ;
snowballPosY = 50 ;
renderSnowball() ;
}
}
You're totally blocking the main thread. Have you tried using a setTimeout (even with a zero timeout) to allow other things to happen during your animation?
If you're willing to use experimental technology, requestAnimationFrame would be even better.
Edit: the setTimeout approach would look something like this (replacing the while loop):
var drawAndWait = function() {
if (snowballPosY > 0) {
// movement/drawing code here
setTimeout(drawAndWait, 20 /* milliseconds */);
} else {
// reset code that would normally go after your while loop
}
};
drawAndWait();
So each time the drawing finishes, it arranges for itself to be invoked again, if appropriate. Note that your throwSnowball function will return quickly; the throwing isn't actually done until later on. This takes awhile to get used to doing correctly; don't be too concerned if it's not intuitive at first.
Try getting out of the tight loop. Chrome may not want to redraw until your function exits. Try using setInterval or setTimeout to give Chrome a chance to repaint.
I'm looking into the speed of JavaScript parsers in web browsers, importantly it needs to be easy to demonstrate. I came up with a simple test - the idea being that each script block is parsed and executed individually, so a large block of script could be timed:
<script>var start = new Date().getTime();</script>
<script>
/*! jQuery v1.8.2 jquery.com | jquery.org/license */
...
</script>
<script>alert ( new Date().getTime() - start );</script>
Superficially this appears to work, removing the middle script block will result in a negligible time.
However I'm not certain that my logic is not fundamentally flawed.
It seems the answer is broadly yes, but to get a reasonable result (like anything else) the test should be run many times to level out the effects of compilation caching and garbage collection. The test above can easily be placed into the Parse-n-Load library: http://carlos.bueno.org/2010/02/measuring-javascript-parse-and-load.html
Thanks for your help
This may be of help!
var start = new Date().getTime();
var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time);
If you want to benchmark your JavaScript, include MilliSeconds etc.
var t = new Date();
var start = t.getTime()*1000 + t.getMilliseconds();
/* do something*/
var t2 = new Date();
var end = t2.getTime()*1000 + t.getMilliseconds();
alert("The Code needed " + (end-start) + " milliseconds. That are " + parseInt((end-start)/1000) + " seconds.");
You might want to differentiate between parsing and execution time. You could do something like
<script>start = Date.now();</script>
<script>
parsed = Date.now();
/*! jQuery v1.8.2 jquery.com | jquery.org/license */
…
</script>
<script>var end = Date.now();
alert ( "parsed in " + (parsed - start) + "ms" );
alert ( "executed in " + (end - parsed) + "ms" );
alert ( "overall time: " + (end - start) + "ms" );
</script>
With that you might be able to detect cached parse trees etc. Yet, for more distinct information have a look at your developer tools, they show such type of information in their profiler section. Or in Opera, it's included in the load process of scripts in the network panel.
This answer is from 10 years in the future.
There are a number of approaches to timing web page processes including:
Date-related methods:
Date.now();
and:
console.time-related methods:
console.time('myTimer');
console.timeLog('myTimer');
console.timeEnd('myTimer');
but, since late 2015, the ideal way to time web page processes using high-resolution timestamps has been:
window.performance.now();
Using Performance:
The Performance interface, accessed via window.performance has numerous methods, including:
timeOrigin
mark
measure
getEntries
toJSON
and more.
But in order to time a script, all you need is window.performance.now():
let scriptStart = window.performance.now();
let scriptEnd = window.performance.now();
let scriptDuration = (scriptEnd - scriptStart);
Working Example:
let paragraph = document.querySelector('p');
let button = document.querySelector('button');
const runTimedScript = () => {
let scriptStart = window.performance.now();
for (let i = 0; i < 10000; i++) {
paragraph.textContent = 'Loop iteration ' + (i + 1);
}
let scriptEnd = window.performance.now();
let scriptDuration = (scriptEnd - scriptStart);
button.textContent = 'Re-run Script';
console.log('The script ran in ' + scriptDuration + ' milliseconds');
}
button.addEventListener('click', runTimedScript, false);
button {
cursor: pointer;
}
<p></p>
<button type="button">Run Script</button>
<p>To see how long the script takes to run,<br />
click the button above repeatedly.</p>
Further Reading:
To find out more about the Performance Interface, see:
Performance API (MDN)
Does anyone know what event or property I need to query in order to get a percentage figure of the amount an HTML5 video has loaded? I want to draw a CSS styled "loaded" bar that's width represents this figure. Just like You Tube or any other video player.
So just like you tube a video will play even if the whole video hasn't loaded and give the user feedback on how much of the video has loaded and is left to load.
Just like the Red Bar on YouTube:
The progress event is fired when some data has been downloaded, up to three times per second. The browser provides a list of ranges of available media through the buffered property; a thorough guide to this is available on Media buffering, seeking, and time ranges on MDN.
Single load start
If the user doesn't skip through the video, the file will be loaded in one TimeRange and the buffered property will have one range:
------------------------------------------------------
|=============| |
------------------------------------------------------
0 5 21
| \_ this.buffered.end(0)
|
\_ this.buffered.start(0)
To know how big that range is, read it this way:
video.addEventListener('progress', function() {
var loadedPercentage = this.buffered.end(0) / this.duration;
...
// suggestion: don't use this, use what's below
});
Multiple load starts
If the user changes the playhead position while it's loading, a new request may be triggered. This causes the buffered property to be fragmented:
------------------------------------------------------
|===========| |===========| |
------------------------------------------------------
1 5 15 19 21
| | | \_ this.buffered.end(1)
| | \_ this.buffered.start(1)
| \_ this.buffered.end(0)
\_ this.buffered.start(0)
Notice how the number of the buffer changes.
Since it's no longer a contiguous loaded, the "percentage loaded" doesn't make a lot of sense anymore. You want to know what the current TimeRange is and how much of that is loaded. In this example you get where the load bar should start (since it's not 0) and where it should end.
video.addEventListener('progress', function() {
var range = 0;
var bf = this.buffered;
var time = this.currentTime;
while(!(bf.start(range) <= time && time <= bf.end(range))) {
range += 1;
}
var loadStartPercentage = bf.start(range) / this.duration;
var loadEndPercentage = bf.end(range) / this.duration;
var loadPercentage = loadEndPercentage - loadStartPercentage;
...
});
The other awnsers didn't work for me so I started digging into this problem and this is what I came up with. The solutions uses jquery to make an progressbar.
function loaded()
{
var v = document.getElementById('videoID');
var r = v.buffered;
var total = v.duration;
var start = r.start(0);
var end = r.end(0);
$("#progressB").progressbar({value: (end/total)*100});
}
$('#videoID').bind('progress', function()
{
loaded();
}
);
I hope this helps others as well
Percentage fix for loaded string.. Output something like 99% loaded inside #loaded element...
function loaded() {
var v = document.getElementById('videoID');
var r = v.buffered;
var total = v.duration;
var start = r.start(0);
var end = r.end(0);
var newValue = (end/total)*100;
var loader = newValue.toString().split(".");
$('#loaded').html(loader[0]+' loaded...');
$("#progress").progressbar({
value: newValue
});
}
I think best event to update the buffered progress bar is timeupdate. whenever time of the media is updated event is fired.
It gives buffered property which we can use like this
audio.addEventListener('timeupdate', function () {
if (this.duration) {
let range = 0;
let bf = this.buffered;
let time = this.currentTime;
while (!(bf.start(range) <= time && time <= bf.end(range))) {
range += 1;
}
let loadStartPercentage = bf.start(range) / this.duration;
let loadEndPercentage = bf.end(range) / this.duration;
let loadPercentage = (loadEndPercentage - loadStartPercentage) * 100;
//Update your progressbar DOM here
}
});
Best advantage of this event is this is fired when media is played. Whereas progress event is fired when media is downloaded and notified by browser.
So just like youtube, buffered percentage can only be shown when media is played
My answer is better than all of the other ones because you want to update buffer progress when the video is paused. This happens with the progress event. The time update event fires when progress fails, as it sometimes does.
$("#video").on("timeupdate progress", function(){
var video = document.getElementById("video");
var vidDur = video.duration;
for(var i = 0; i <= vidDur; i++){
var totBuffX = video.buffered.end(i);
var perBuff = totBuffX/vidDur*100;
$("#xVidBuffX").css("width", perBuff+"%");
}
});
you only need video.buffered.end(i).