I have a service where users embed a javascript code in they website, in the body tag. Sometimes the page where the code is embedded throws a javascript error from other javascript files which prevent our script from running.
Is there a way to design our code so it doesn't interfere with other javascript scope.
The only solution I can think of is to put the js code in an iframe.
The best way to make sure that your code always runs, is to make sure it is always loaded first.
As long as no scripts are dynamically loaded or marked as async or defer, scripts are run or evaluated in the order encountered in the page. So, the first scripts encountered run first.
In other words, by default, script tags are downloaded and evaluated sequentially as they are encountered in an HTML document.
An externally referenced script file that must be loaded will cause all further javascript execution to wait until that externally referenced file is loaded and parsed and runs.
What all of this means is that you should make sure your script is at the very top of the HTML that is being loaded, meaning it will be processed first and other scripts will not have a chance to interfere with yours.
reference: http://docstore.mik.ua/orelly/webprog/jscript/ch12_03.htm
Related
I have a javascript script that I want to load synchronously, but the URL of the script is determined by the value of a cookie. For example:
<script src="/js/[user-id-from-cookie].js">
This script has to load in the <head> of my HTML document and must be run synchronously (it has to block the main thread while it is downloaded and executed).
How can I use javascript to:
Read the value of a cookie
Download and execute the script synchronously
I need to do this in pure javascript, no frameworks like jQuery etc.
Thanks!
You can use document.write to load scripts synchronously.
But use it this way may cause some lag, I'd like to offer some alternatives.
parse the cookie and return different script per user by server. (recommended, but need to have server support)
load all the script, but rewrite them so only one would execute based on condition. (not good for large amount of variant, of course)
hide the body and only show after whatever preprocess have done. (not actually how to load script, but then you can load it asynchronously)
This question has always bothered me every time I put my js files at the bottom of the page. if I put all js files at the bottom before the closing body tag then I think that the browser will first download all the html and style sheets then it will parse the html and css and at last it will send requests for js files. So,
Would using defer on js files which are already at the bottom make any difference?
Are non deferred scripts at the end just before body tag render blocking?
Another question I have is if I put all js file in the head and use defer on them. Would this be equivalent to placing all js files at the bottom? Would seeing js with defer in head the browser make request to the server and then continue downloading rest of html file or will it make request to server only after downloading all html and css?
As far as I know async is equivalent to defer and the only difference is the js will be executed when downloaded without respecting the order of files. So,
Would using async on js files which are already at the bottom make any difference except from the order in which they are executed?
Looking through the HTML 5.2 spec for Scripting, one finds this illustration W3C uses.
What we see here is that using defer fetches the script while the HTML is being parsed, but waits until parsing is concluded before executing.
async, on the other hand, fetches alongside parsing, and once the fetch is complete, HTML rendering is paused to execute the script.
Since HTML execution is synchronous, one can assume that using defer on scripts placed just before </head> would be almost like placing them just before </body>.
However, as Chris Moschini states, I would not trust defer. I feel this StackOverflow answer as a whole would better explain how defer affects loading JavaScripts.
The defer attribute is a boolean attribute.
When present, it specifies that the script is executed when the page has finished parsing.
Note: The defer attribute is only for external scripts (should only be used if the src attribute is present).
This post I found explains it well: https://flaviocopes.com/javascript-async-defer/
Ideally, the best practice is to have <script defer... in . If you use a CDN, for example, this allows the script to be downloaded while the HTML is being parsed.
If my browser makes a GET to a script src which is currently having a gateway timeout aka 504, why does the browser hang and stop rendering until the response is actually delivered 60 seconds later? Aside from crashing the browser, isn't this the worst thing that could happen to a production javascript application? Is there anything you can do as the app dev to prevent this from blocking the rest of the rendering and script execution?
If the script is inline (e.g. not dynamically loaded) and not marked defer or async, then the script must be processed synchronously in order and the browser cannot proceed without it. Inline <script> tags (without any special attributes) are processed in order as encountered and the browser MUST process them that way.
If you want your page to render without waiting for the script to load, then you can either load it dynamically or you can mark it async or put the <script> tag right before the </body> tag and the page rendering will not wait for it. If using defer or async, you must make sure that no other scripts are dependent upon the loading of this script, otherwise they might run before this one loads.
See these references for more info:
load and execute order of scripts
Script Tag - async & defer
If you are talking about javascript in the DOM within script tags, browsers will always load them synchronously which is why it is important to have the bulk of your JS at the bottom of the page. If this becomes a big issue I would recommend using using an async loading library such as lab.js http://labjs.com/.
If you are getting into more advanced JS and want to utilize something like the AMD pattern for script loading and dependencies you can use http://requirejs.org/.
I need to know when a script is loaded and it's code is executed so that I can make sure the variables are not undefined. I searched and did not find any question like this one... again I need loaded-executed event not just download-complete.
and I will use 'id' on each script so I can find which is loaded.
<script src="utils.js" id="js_utils"></script>
If you're not loading scripts dynamically, you can rely on their order of running (which would be the order in which they appear in the document), see here:
load and execute order of scripts
Otherwise, you can either:
Add a line of code to the end of each script file loaded dynamically that runs your block of code.
or
If you don't have the ability to edit those files, start an interval as soon as you inject them into the code, tracking the object you want set before running your block of code.
When helping someone with a website that is rather large and have many includes I hit a bug and couldn't understand it. It was something like this
<script src=...></script>
<div ...
<script>
alert('myscript');
</script>
This page worked fine until I use that section of html and used jquery to ajax the content in. It broke the code but I don't understand why. I seen my alert. I can see the script is being access via the browser network log. I see some of the results of the first script tag but its broken.
Why does order matter? I thought as long as the dom is ready and the script is executed everything should be fine. But in this case being ajaxed in breaks it. I couldn't spend much time but it was curious to see something was dependent on timing.
--edit--
Also I notice if the script is already included on the page ajaxing in the content it will run fine
Does anyone have any idea why ajaxing in content breaks? When its not ajaxed in its fine.
Based on what you say, I give the following assessment :
40% likely -- it is about script load. Dependencies within the ajaxed script to other scripts, variables you define on the page, or even DOM content that is supposedly loaded could be not loaded at the time the script is ajaxed and executed.
Try changing the order of the script tag on the page, putting the loading of the script inside a document ready event handler, or delaying the script execution with setTimeout or defer="defer" -- or if you are really cool create a boot loader that ensures every script is loaded and executed in the exact order you specify : by chaining sets of dependency free simultaneous loads, to sequences of dependent loads.
Script1 <---- depends on --- (Script 2.1, Script 2.2, Script 2.3 )
<--- depends on --- Script3.
So load 1 first, then all the 2. scripts, then 3.
40% likely -- it is about security model. The website where you are ajaxing it from, Where is that? What is its relation to the domain the page is on? Are you testing this on localhost ?If so there are more restrictions. What about on an actual server? Is the Access-Control-Allow-Origin header set appropriately on the ajax response?
20% likely -- it is a circular dependency between the script and the DOM. Say some event handler on element X closes on a scope that references element X. Then there will be a reference to X inside a reference to X so they can't both be garbage collected, so X will persist, cause a memory leak, and possibly create an unusable reference which could be breaking your code.
--edit--
Based on your comment about .html(...) I think .html or .load to run scripts is too messy, and may not even work at all. See .load() doesn't load scripts for a nice way to load scripts with ajax. Or you could jQuery.getScript(...).
Also I seem to remember having issues even with loading html nodes from plain HTML using ajax. It just seems too messy to me. If you want to transfer structured information across ajax, use JSON, then present that information on your side with javascript and HTML. So, don't grab the whole data + presentation, just grab the data, then do your own presentation on your side. It's much neater.