The main difference between internal js file and external js file - javascript

Is there any different between include external js file and write down javascript in the html page.
Case 1
test.html
<html>
<head>
<script type="text/javascript" src="test.js"></script>
</head>
<body>
</body>
</html>
test.js
alert('aaa');
Case 2
test.html
<html>
<head>
<script>
alert('aaa');
</script>
</head>
<body>
</body>
</html>
Case 1 execute more faster than Case2 if my memory services me right. But I am not sure. Moreover, I cannot find the relative documents or articles to support my ideal. May someone help me?

Case 1 is is slightly slower at first, because it needs to do a second request to get the script, so there is a little overhead.
However, the browser will cache the javascript file, so if you have multiple pages that share the same script, Case 2 will be more efficient, because for subsequent pages, the browser already has the cached script and doesn't need to download it again.
Also, most browsers will allow opening two connections to the same server, so it may download the page and the script simultaneously on the first request, although it depends on size of the page and the script, the server, the client and the internet properties (latency and speed) which solution is faster.

Case 1: will retreive the script from the server and run it syncrhonously (script file will be cached on subsequent requests, file can be minified)
Case 2: will have the script loaded as part of the page (no extra page request), and run when script tag is loaded into dom.
both: will hold up page at that point
Info: http://webdesign.about.com/od/speed/a/script-placement-for-speed.htm

Related

Javascript not executing using XAMPP

In my html document (which is in the xampp/htdocs directory), I'm using an external .js file. The .js file is in the same directory as my html file. I'm simply trying to use document.write() function and it's not printing anything.
I don't understand what I'm doing wrong. Whats the issue?
HTML file
<!DOCTYPE html>
<html>
<head>
<?php include 'include/head_elements.html'?>
<script type="text/javascript" src="register.js"></script>
</head>
<body>
<h1>Company Account creation</h1>
<div id="registration_menu">
<!--Elements are added and removed dynamically using JS-->
</div>
<script>
hello();
load_element_group("email_verification");
</script>
</body>
</html>
JS file
function hello(){
document.write("Hello world")
}
Internet Explorer's security policy may block certain scripts from running on a local machine.
There are ways to avoid this -- such as by adding the XAMPP website as a trusted location -- but often this gets tricky since the default "Intranet Zone" is auto-configured on a PC and modifying that can have other consequences (different zones assume different settings, such as passing NTLM credentials to local websites).
See also https://stackoverflow.com/a/7038775/3196753
A quick fix often is to add the fully qualified domain name (FQDN) to the URL, but depending on the zone settings, this may still cause issues.
A final solution, and one many developers fall back on, is to actually use a registered DNS address, such as http://localtest.me/, which points back to localhost and should use the "Internet Zone".
As Chris G points out in the comments, this isn't typical. Normally localhost can be used without issue so I've provided an example Local Intranet setting which can cause this:

What is the correct src= attribute to load scripts from node.js server

Both my p5.js and sketch.js scripts will not load.
My index.html is loaded by Node.js
I think I am misusing the src value in my<script> tag in the HTML.
My p5.js script is up one level and in a folder called P5, and my sketch.js file is in a folder called P5Scripts in the same directory as this index.html file.
In the chrome console, I get this message :
Loading failed for the <script> with source “http://45.76.140.199:3000/P5/p5.js”.
and
Loading failed for the <script> with source “http://45.76.140.199:3000/P5Scripts/sketch.js”.
I can see that my src attribute is wrong, but what would be the correct way to load these scripts?
index.html:
<!doctype html>
<html>
<head>
<title>My Website</title>
</head>
<script src="../P5/p5.js"></script>
<script src="P5Scripts/sketch.js"></script>
<body>
</body>
</html>
There isn't a way to bind nodejs with the DOM elements of your html because nodejs is backend and html DOM elements are frontend.
Since you are trying to modify the html, chances are that what you really want is to use plain javascript which would run on the browser.
Nodejs is a backend technology which runs on the server. At the time the html is displayed nodejs has already done its work and isn't aware of what is going on the page unless AJAX involved.
Have a brief look to client/server model here.

Javascript running from html but not php

I've read a similar question here, but can't seem to get around it in this case, so would appreciate any clarification. I have a page in php that runs several instances of JavaScript that work on cue on localhost. However one particular instance of JavaScript (that makes an arrow hide when it scrolls beyond 10px) does not run, but when i run the same from an html version of the same php page, the arrow action works as desired. Why is this the case? Here is the code of the page in jsfiddle (exactly the same is used for respective sections in the php page.)
To clarify i have added this bit of JavaScript in the following manner at the end (after footer, before body end) of the index.php file (along with other blocks of JavaScript which work as desired for their respective targets):
<script type="text/javascript">
$(window).scroll(function () {
if ($(this).scrollTop() > 10)
document.getElementById('arr_downpoint').style.visibility = 'hidden';
else
document.getElementById('arr_downpoint').style.visibility = 'visible';
});
</script>
I have added jquery as follows (and it works for all other instances on the php page except for the arrow):
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
Lastly, there are no console errors. Would like to know why only this block of JavaScript isn't working from php, but works from HTML (while the other JavaScript instances work fine on both php and HTML), and how to find out what's wrong?
RESOLUTION: Just found that I'd erroneously added # while assigning arrowpoint id. That's why the script couldn't do anything with the arrowpoint, since <a> now had a # as part of its name. sorry about that careless oversight, for the time it may have taken to consider.
If you are trying to load the page directly from the file (your page url start with 'file://...') the problem is that the browser is trying to load jquery using the same protocol (file instead of http) because you didn't specify a protocol for the external files (the src attribute starts with '//', which mean something like "use the same protocol of the current page"). You can verify if this is the reason behind your problem, opening the browser console looking for errors like:
GET file://code.jquery.com/jquery-1.11.3.min.js net::ERR_FILE_NOT_FOUND
GET file://code.jquery.com/jquery-migrate-1.2.1.min.js net::ERR_FILE_NOT_FOUND
Uncaught ReferenceError: $ is not defined
To fix this problem, you should always run you html from a server (like Apache with PHP, as you already did) or you can write the external scripts url including the protocol (but this can cause other problems if you will run your page under https)
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>

Caching Javascript inlined in HTML

Instead of having an external .js file, we can inline Javascript directly in HTML, i.e.
Externalized version
<html>
<body>
<script type="text/javascript" src="/app.js"></script>
</body>
</html>
Inlined version
<html>
<body>
<script type="text/javascript">
// app.js inlined
</script>
</body>
</html>
However, it's not recommended:
https://developer.yahoo.com/performance/rules.html#external
Put javascript and css inline in a single minified html file to improve performance?
The main reason is caching and pre-compiling - in the externalized version, the browser can download, pre-compile and store the file once for multiple pages, while it cannot do the same for inlined version.
However, is it possible to do something along these lines:
Inlined keyed version
<html>
<body>
<script type="text/javascript" hash="abc">
// app.js inlined
</script>
</body>
</html>
That is, do this:
In the first invocation, send the whole script and somehow tell the browser that the script hash is abc
Later, when the browser loads that or other pages containing the same script, it will send this key as a cookie. The server will only render the contents of the script if the key has been received.
That is, if the browser already knows about the script, the server will render just this:
Inlined keyed version, subsequent fetches (of the same or other pages)
<html>
<body>
<script type="text/javascript" hash="abc">
</script>
</body>
</html>
where notably the script contents are empty.
This would allow for shorter script fetching with a natural fallback.
Is the above possible? If not, is some other alternative to the above possible?
I don't know of a way to do what you asked, so I'll provide an alternative that might still suit your needs.
If you're really after a low latency first page load, you could inline the script, and then after the page loads, load the script via url so that it's in the browser cache for future requests. Set a cookie once you've loaded the script by direct url, so that your server can determine whether to inline the script or provide the external script url.
first page load
<script>
// inlined my-script.js goes here.
</script>
<script>
$(function(){
// load it again, so it's in the browser cache.
// notice I'm not executing the script, just loading it.
$.ajax("my-script.js").then(function(){
// set a cookie marking this script as cached
});
});
</script>
second page load
<script src="my-script.js"></script>
Obviously, this has the drawback that it loads the script twice. It also adds additional complexity for you to take care of when you update your script with new code - you need to make sure you address the cookie being for a old version.
I wouldn't bother with all this unless you really feel the need to optimize the first page. It might be worth it in your case.
The Concept
Here's an interesting approach (after being bugged by notifications :P)
You could have the server render your script this way. Notice the weird type attribute. That's to prevent the script from executing. We'll get to that in a second.
<script type="text/cacheable" data-hash="9182n30912830192c83012983xm019283x">
//inline script
</script>
Then create a library that looks for these scripts with weird types, get the innerHTML of these scripts, and execute them in the global context as if they were normally executing (via eval or new Function). This makes them execute like normal scripts. Here's a demo:
<script type="text/cacheable" data-hash="9182n30912830192c83012983xm019283x">
alert(a);
</script>
<script type="text/cacheable" data-hash="9182n30912830192c83012983xm019283x">
alert(b);
</script>
<script>
// Let's say we have a global
var a = "foo";
var b = "bar"
// Getting the source
var scripts = Array.prototype.slice.call(
document.querySelectorAll('script[type="text/cacheable"]')
);
scripts.forEach(function(script){
// Grabbing
var source = script.innerHTML;
// Create a function (mind security on this one)
var fn = new Function(source);
// Execute in the global scope
fn.call(window);
});
</script>
However...
Since you have the script source (the innerHTML), you can cache them somewhere locally (like in localStorage) and use the hash as its identifier. Then you can store the same hash in the cookie, where future page-requests can tell the server "Hey, I have cached script with [hash]. Don't print the script on the page anymore". Then you'll get this in future requests:
<script type="text/cacheable" data-hash="9182n30912830192c83012983xm019283x"></script>
That covers up the first half. The second phase is when your library sees an empty script. The other thing your library should do is when it sees an empty script, it should look up for that script with that hash in your local storage, get the script's source and execute it like you just did in the first place.
The Catch
Now there's always a trade-off in everything, and I'll highlight what I can think of here:
Pros
You only need one request for everything. Initial pageload contains scripts, subsequent pages become lighter because of the missing code, which is already cached by then.
Instant cache busting. Assuming the hash and code are 1:1, then changing the content should change the hash.
Cons
This assumes that pages are dynamic and are never cached. That's because if you happen to create a new script, with new hash, but had the client cache the page, then it will still be using the old hashes thus old scripts.
Initial page load will be heavy due to inlined scripts. But this can be overcome by compressing the source using a minifier on the server. Overhead of minification can also be overcome by caching minified results on the server.
Security. You'll be using eval or new Function. This poses a big threat when unauthorized code manages to sneak in. In addition, the threat is persistent because of the caching.
Out of sync pages. What happens if you get an empty script, whose hash is not in the cache? Perhaps the user deleted local storage? You'll have to issue a request to the server for it. Since you want the source, you'll have to have AJAX.
Scripts are not "normal". Your script is best put at the end of the page so that all inline scripts will be parsed by then. This means your scripts execute late and never in the time they get parsed by the browser.
Storage limits. localStorage has a size limit of 5-10MB, depending on which browser we're talking about. Cookies are limited to 4KB generally.
Request size. Note that cookies are shipped up to the server on request and down to the browser on response. That additional load might be more of a hassle than it is for good.
Added server-side logic. Because you need to know what needs to be added, you need to program your server to do it. This makes the client-side implementation dependent on the server. Switching servers (say from PHP to Python) wouldn't be as easy, as you need to port over the implementation.
If your <script> is not introduced as type=text/javascript, it will simply not be executed.
So you could have many tags like theses:
<script type="text/hashedjavascript" hash="abc">...</script>
<script type="text/hashedjavascript" hash="efg">...</script>
Then when the DOM is loaded, pick one and evaluate it.
I made an example here: http://codepen.io/anon/pen/RNGQEM
But it smells, real bad. It's definitely better to fetch two different files.
Actually what you should do, is have a single file my-scripts.js that contains the code for each of your script, wrapped in a function
// file: my-scripts.js
function script_abc(){
// what script abc is supposed to do
}
function script_efg(){
// what script efg is supposed to do
}
Then execute whatever your cookie tells you to. This is how AMD builders concatenate multiples files in one.
Also look for an AMD library such as requirejs
Edit: I misunderstood your question, removed the irrelevant part.

Edit external JavaScript file after breakpoint is hit

In the VS2010 IDE when a breakpoint (or an error) is hit, it opens a read-only [dynamic] version of the external JavaScript file I referenced. My workflow would be vastly improved if I could immediately edit this file, and refresh the browser. That is as opposed to digging up the original JS file opening it, finding the correct line and editing there.
I only know that this is possible because I was able to do this on my old work computer configuration, but for the life of me I can't duplicate it at home.
Has anyone made this work? Perhaps an extension? or maybe it has to with the way the files are referenced, or my basehref tag, or url rewriting.
This happens when the base href specifies a domain other than localhost. My issue was that to enable a local environment for Facebook JS, I need my domain in the url. So I set up my host file to remap localhost.mydomain.com to localhost.
When the Visual Studio IDE encounters a file reference which is something other than localhost, it does not attempt to grab the local file since it assumes (correctly in most cases) that it is being served from another site. In these cases it loads a file as [dynamic] and readonly.
Here is the test case:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<base href="http://localhost.mydomain.com/virtual-directory/" />
<script type="text/javascript" src="test.js"></script>
</head>
<body>
</html>
Any breakpoint within test.js will result in opening a readonly dynamic file.
how are you referencing your files? whenever a script block is written inside the html or is dynamically inserted the debugger will open the instance of the page where the code stops. If you reference the script using tags vs should open the original script file (at least that's what it does on my machine). could you upload an example of your current structure?

Categories

Resources