javascript , HTML, difference between writing javascript in head and body - javascript

I am learning javascript and to tell the truth, some parts don't make sense to me. like this one. I wrote this block of code first :
<body>
<script type="text/javascript">
function people(name, age){
this.name = name;
this.age = age;
this.ret = yearsLeft;
}
function yearsLeft(){
var numYears = 65 - this.age;
return numYears;
}
var sam = new people("sam forest", 39);
var billy = new people("billy wood", 45);
document.write(billy.ret());
</script>
</body>
and I got the result. However I wrote this one after the first one and I got the same result:
<head>
<title>Javascript</title>
<script type="text/javascript">
function people(name, age){
this.name = name;
this.age = age;
this.ret = yearsLeft;
}
function yearsLeft(){
var numYears = 65 - this.age;
return numYears;
}
var sam = new people("sam forest", 39);
var billy = new people("billy wood", 45);
</script>
</head>
<body>
<script type="text/javascript">
document.write(billy.ret());
</script>
</body>
Here is my question, what is the difference , when I get the same result in both ways?

From Yahoo's Best Practices for Speeding Up Your Web Site:
The problem caused by scripts is that they block parallel downloads.
The HTTP/1.1 specification suggests that browsers download no more
than two components in parallel per hostname. If you serve your images
from multiple hostnames, you can get more than two downloads to occur
in parallel. While a script is downloading, however, the browser won't
start any other downloads, even on different hostnames.
In some situations it's not easy to move scripts to the bottom. If,
for example, the script uses document.write to insert part of the
page's content, it can't be moved lower in the page. There might also
be scoping issues. In many cases, there are ways to workaround these
situations.
An alternative suggestion that often comes up is to use deferred
scripts. The DEFER attribute indicates that the script does not
contain document.write, and is a clue to browsers that they can
continue rendering. Unfortunately, Firefox doesn't support the DEFER
attribute. In Internet Explorer, the script may be deferred, but not
as much as desired. If a script can be deferred, it can also be moved
to the bottom of the page. That will make your web pages load faster.
Therefore, in general, it is preferrable to put them at the bottom. However, it isn't always possible, and it often doesn't make that much of a difference anyway.

In many cases the result is the same, but there's a relevant difference due to the way web browser render html pages.
Since a browser reads the page content top-to-bottom, placing the javascript code within the <head> tag will cause the actual page content to be displayed after the browser has finished parsing the script. Placing it just before the </body> tag instead will let the browser display the content faster, which is usually desirable.
Another implication of the top-to-bottom rendering is related to SEO optimization: since most crawlers will inspect a fixed number of bytes at the top of a page, having those first bytes filled with javascript code will prevent the crawler from accessing the actual page content, therefore reducing the benefits of whatever you've SEO-wise.

Because you're doing pretty much the same thing. The browser is going to evaluate your javascript code sequentially, and, if it's just statements, as you putted, they're going to be executed.
So, one thing you need to pay attention is that the browser is going to evaluate your hole document (html, css, javascript), and the javascript statements that are not function definitions are going to be executed right away.

Related

Loading 2000 characters text inside a .js versus loading in the HTML

I have a website with the typical footer "About Me", "About this site", ... and when the user clicks any of those, a modal/popup is displayed and its innerHTML set via JavaScript
var aboutMe = "I am Foo and I like ..."; // 500 characters;
var aboutTheSite = "This site is for ..."; // 500 characters;
var cookiePolicy = "This site uses cookies ..."; // 500 characters;
// ...
// ...
The alternative for doing this is to create some tags and append that text
<div id='aboutMeContent'>I am Foo and I like ... </div>
<!-- ... .... more -->
I didn't do the second option because I like to keep my source code really clean (YouTubeGo.net). But I am a bit worried about this worsening the performance of the site. All the JavaScript is minimized in a 30K file, but without aboutMe, aboutThisSite... it would be 20K, though those 10K would be loaded inside the .html.
The question:
Which of both options is better?
Or would it still preferable to load it using AJAX and forget about what I am doing?
And a little more technical question (I'm curious):
Does a browser load faster a JavaScript file with only var foo = "fooBar"; and variable declarations than one with really dense code? I know from experience that it doesn't read the contents of an object or a function until it is called or requested.
I care very much about performance time but I can't tell you what was I thinking when I implemented the first option.

How to measures script execution and *parsing* time?

As far as I know, scripts are downloaded and executed synchronously in javascript.
Hence if we write the following code:
<script type='text/javascript'>console.time('core')</script>
<script type='text/javascript' src="guicore.js"></script>
<script type='text/javascript'>console.timeEnd('core')</script>
we'll see in console total time for download, parse and execute js.
How we can exclude parsing time? Just add similar file, but with all code commented out. More or less, this technique should work.
The problem is this just doesn't work =)
I optimized that code, reduce execution time from 90ms to 25ms, but see the same ~100±10ms time for Chrome and ~160±15ms for Firefox.
Ok, I know I could use profiler, but the question is: "how to measure js parsing time correctly" and what did I measured btw. Research.reverse-engineering is very fun, but maybe there's someone who knows that field in depth.
You cannot accurately measure script parse time independent of execution time using web APIs alone. Different browsers have different strategies for when they do parsing, and some of them will parse progressively as the script is executed, or even do "partial parsing" in cases where it's assumed a block of code is unlikely to immediately be executed (e.g. a function that is not an IIFE, see some details in the optimize-js README).
Using separate <script> tags is the most accurate way to at least capture both parsing and execution time. The only modification I would make to your snippet is this:
<script>
performance.mark('start');
</script>
<script src="myscript.js"></script>
<script>
performance.mark('end');
performance.measure('total', 'start', 'end');
</script>
Note the use of the high-precision User Timing API which, as an added bonus, will show visualizations in the Chrome/Edge/IE dev tools (and tools like Windows Performance Analyzer and WebPageTest if you're so inclined).
Technically the 3rd <script> is not necessary, as you can just append the mark/measure to the end of the 2nd script. But the 1st <script> is certainly necessary to capture all parse time. You can verify in the dev tools that the marks/measures encompass all initial parsing and execution time.
I know this is kind of an old question but I came across it while looking for a solution to this myself. You can use the dev tools in the browser of your choice to look at this but if you'd like to do it in code this is the method I ended up using.
The scriptLoadParseDuration function below will take a URL to a .js file, place it into a <script> element, and log the load/parse duration to the console.
Keep in mind that this will execute the <script> you are profiling within the current DOM context. So in the example below: jQuery is still accessible in the global scope even though the script was removed. The script could be extended to do all of this in an <iframe> to isolate it though.
function scriptLoadParseDuration(url) {
var start;
var script = document.createElement('script');
// <script> must be attached to the document to actually load the file
document.querySelector('html').appendChild(script);
// Calculate load/parse duration once script has loaded
script.addEventListener('load', function scriptLoad() {
// Calculate load/parse duration
console.log('Duration: ' + (Date.now() - start) + 'ms');
// Remove <script> from document
script.parentElement.removeChild(script);
}, false);
// Get current time in milliseconds
start = Date.now();
// Setting the `src` starts the loading. Math.random is used to make sure it is an uncached request
script.src = url + '?' + Math.floor(Math.random() * 9e9);
}
var url = 'https://code.jquery.com/jquery-3.0.0.min.js';
scriptLoadParseDuration(url);
Here is an example showing that jQuery is still in the global scope after the <script> removal.
function scriptLoadParseDuration(url) {
var start;
var script = document.createElement('script');
console.log('`jQuery` before attaching: ' + typeof jQuery);
// <script> must be attached to the document to actually load the file
document.querySelector('html').appendChild(script);
// Calculate load/parse duration once script has loaded
script.addEventListener('load', function scriptLoad() {
// Calculate load/parse duration
console.log('Duration: ' + (Date.now() - start) + 'ms');
console.log('`jQuery` once attached: ' + typeof jQuery);
// Remove <script> from document
script.parentElement.removeChild(script);
console.log('`jQuery` after detach: ' + typeof jQuery);
}, false);
// Get current time in milliseconds
start = Date.now();
// Setting the `src` starts the loading. Math.random is used to make sure it is an uncached request
script.src = url + '?' + Math.floor(Math.random() * 9e9);
}
var url = 'https://code.jquery.com/jquery-3.0.0.min.js';
scriptLoadParseDuration(url);
Open up Chrome and open the developer tools, the go to the "Timeline" tab. If you press the record button (filled in circle, bottom left) then reload the page it'll give you a fairly detailed timeline, broken down into specific types of activity (Send Request, Parse, Evaluate), timed down to the microsecond.
Very old question with a relatively new answer.
Date.now() returns a timestamp with millisecond accuracy. For an application to run at 60FPS, it must update the frame every 16ms. Our millisecond meter may not be accurate enough.
Introducing the Performace API in modern JS browsers, this allows for floating-point timestamps accurate to the microsecond.
Instead of Date.now() use window.performance.now() for measurements, there's a good guide on using the Performance API on HTML5Rocks.
Chrome DevTools actually has a hidden flag that shows V8 Parse and Compile time!
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/javascript-startup-optimization#parsecompile
Outcome looks like this:
A quick guide is also available in the doc in the blue section below:
After you enable the feature, you can profile a page and then click on "Bottom-Up" tab on the Performance tab in Chrome DevTools, and then make sure you "Group by Activity", and you should see the Compile and Parse time now.
Enjoy!

reading content of .aspx using javascript

i am using javascript to read the content of .aspx page. but i am not able to read it. i am using javascript as:
function edit(headtext,totext, bodytext, footertext){
alert('lll');
//var xmlDoc=new ActiveXObject("MSXML.DOMDocument");
xmlDoc.async="false";
xmlDoc.load("theme3ex.aspx");
var students = xmlDoc.documentElement;
alert('0000');
var student = students.childNodes(0);
document.getElementById('txtareahead').innerHTML = headtext;
document.getElementById('txtareato').innerHTML = totext;
document.getElementById('txtareabody').innerHTML = bodytext;
document.getElementById('txtareafooter').innerHTML = footertext;
location.href = "MailSender.aspx";
}
is there any problem eith my javascript..
First problem is that you've commented out the line which creates the AJAX object, so none of the subsequent code will work because they're trying to access an object which doesn't exist.
Second problem is that even if you uncomment that line, it's using Activex/MSXML which will only work with IE (and even then only older versions of IE).
In short, your code isn't good, and needs to be entirely redone rather than being fixed.
My recommendation is that you find a more up-to-date example of how to do AJAX code. Possibly even just use a good quality Javascript library like JQuery.
I agree with #Spudley's point.
It's also worth mentioning that if the textboxes such as txtareahead are ASP.NET TextBox Controls, then the ID's will have most likely changed during rendering.

Dynamic evaluation of functions in JS (is this safe?)

I have a website in which all the pages are processed through an index.php that includes different PHP files depending on the requested URL (this is done through mod_rewrite).
I'm using the following method to execute specific functions at page load:
index.php
<script type="text/javascript">
readyFns = Array();
</script>
<?php
// Do some stuff here, and pull the name of the PHP page to include from the DB
include $pageToInclude
?>
<script type="text/javascript">
commonFunctionToApplyToAllThePages();
otherCommonFunction();
// page-specific functions
for (i=0; i<readyFns.length; i++)
{
if (typeof(window[readyFns[i]]) == "function")
window[readyFns[i]]();
}
</script>
includedPage.php
<?php
// Generate page
?>
<script type="text/javascript">
readyFns.push("someFunction");
readyFns.push("someOtherFunction");
</script>
I quite like this approach because I just have to set readyFns at the end of this page and everything else will be nicely controlled by index.php.
My questions is: is this safe? Could it be sensitive to someone generating a link that arbitrarily sets readyFns to point to some malicious code and then links to my site?
How would I prevent that?
thanks
nico
This is interesting. In principle, it's probably ok, but you're right to be a little concerned. This is just compiling a list of keys to lookup as functions on an object, and execute, so it's not really a security problem in that respect. But, you are essentially providing access to all globals like that. You'd probably be better off making a global object besides window to store your functions on, like so:
var funcs = {};
funcs.someFunction = function() {/*blah*/};
funcs.someOther = function() {/*blah*/};
and then your readyFuncs thing would loop over funcs instead of window. I don't think there'd be anything to worry about past that.
Of course, there are other things with your approach that could be improved, but I think it's ok as-is if it works for you.

Making DiveIntoPython3 work in IE8 (fixing a Javascript performance issue)

I am trying to fix the performance problem with Dive Into Python 3 on IE8. Visit this page in IE8 and, after a few moments, you will see the following popup:
alt text http://dl.getdropbox.com/u/87045/permalinks/dip3-ie8-perf.png
I traced down the culprit down to this line in j/dip3.js
... find("tr:nth-child(" + (i+1) + ") td:nth-child(2)");
If I disable it (and return from the function immediately), the "Stop executing this script?" dialog does not appear as the page now loads fairly fast.
I am no Javascript/jquery expert, so I ask you fellow developers as to why this query is making IE slow. Is there a fix for it?
Edit: you can download the entire webpage (980K) for local viewing/editing.
This seems to need a bit of rewriting.
nth-child is a slow operation. You should implement the current functionality by generating classes or ids that would be common for the TDs in table and elements from the refs collection (dip3.js line 183). and then:
refs.each(function(i) {
var a = $(this);
var li = a.parents("pre").next("table").find("td."+a.attr('class'));
li.add(a).hover(function() { a.css(hip); li.css(hip); },
function() { a.css(unhip); li.css(unhip); });
});
This popup message is misleading - it doesn't actually mean that IE is running slowly, but that the number of executed script statements has exceeded a certain threshold. Even if the script executes very quickly, you'll still see this message if you go over the limit. The only way to get rid of it is to reduce the number of statements executed or edit the registry.
http://support.microsoft.com/kb/175500
I find Microsoft's implementation of this very annoying. It makes assumptions about the speed of your computer.

Categories

Resources