Is there a way to know what js files was loaded in html, but not used? Let's say I load on a HTML page jQuery, jQuery Tabs, jQuery DatePicker libs, but on that page I use none o them, except jQuery. Is there a way to find out what js files where used ( executed )?
Short answer - No.
Long answer:
Since the files are referenced in the page itself, all scripts would be loaded, executed and it's code(global variables and functions - $ for example) exposed.
The only way to check if a certain part of a script is executed, is to observe the actors or -in other words- the calling code and the called code.
For example:
function callingFunction() {
console.log('I will call this code!');
calledFunction();
}
function calledFunction() {
/// <summary>
/// Lets say this function is added in a external file
/// </summary>
console.log('My code was called!');
}
onDemand scriptloading
A good aproach would be to load your libraries only when needed. jQuery's $.getScript is doing a great job here. If you reference your libraries like this, you can check the currently loaded ones via the network panel.
Update
Chrome 59 now supports Code coverage which does something similar.
Check it out
https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage
No not really. When you include all files, all javascript code in that file is loaded. If you want to load the js file at the moment you use a function in it, you can check if the plugin is available. If it isn't available then include the file.
E.g.:
if(jQuery().datepicker) {
//Include datepicker here
}
No cause when you include any js into your page it gets loaded,
though you can check what is getting run when you interact with things using thne chrome event listeners tab.
That's the closest you are gonna get
I don't think there is an easy way to do what you want. If the purpose is to do lazy loading, prefer use a library like require
Related
Google Pagespeed said I should load my JS files asynchronously, but this has introduced a problem for many of my pages with code using libraries and plugins.
For example, I have the following code on one page:
$(document).ready(function () {
var hound = new Bloodhound({ .......
});
So when the page loads, I am creating a Twitter Bloodhound (goes with Typeahead) object. The problem is, if Bloodhound and Typeahead are loaded asynchronously, then an error is thrown:
Uncaught ReferenceError: Bloodhound is not defined
This is because those scripts haven't been loaded yet.
I came up with this solution:
$(document).ready(function () {
createBloodhound();
});
function createBloodhound() {
if (typeof Bloodhound != "undefined") { // if bloodhound JS has loaded
var hound = new Bloodhound({ .......
}
else {
setTimeout(function(){
createBloodhound();
}, 10);
}
}
Is this a good practice, or is there a better way?
NOTE: I realize there are libraries like RequireJS out there to handle dependencies when loading files, but I don't think this type of solution will not work in my case because I load the libraries asynchronously in a wrapper file (since they're required for every page). The example code here would not be on every page, but only on a specific page on my website.
The best approach is to use a callback mechanism, which you can react to, rather than using a polling mechanism. I used script.js, which is simple and yet functional, and offers the callback mechanism.
Without that, you could implement something yourself. Performance-wise though, utilizing callback are better.
Depending on the complexity of your site, different options might be best. If...
All of your javascript is in JS files
Your above-the-fold content looks identical before and after the JS is loaded (or close enough to identical that the flash of change when your JS does load wouldn't distract your users)
The total file size is small (or most of your JS is needed on pages everyone will visit every time they visit your site)
... then combine them into one file and just server that instead of all the individual ones. Then you don't have to worry about dependencies at all. Include that script file at the bottom of your body tag (no need for async or defer attributes, but you can use them if you want).
If some of your javascript is necessary to make your above-the-fold content look correct, do the same thing, except split your JS into two files. One file contains only what is necessary to make the above-the-fold content look correct, and the other file contains everything else. Include the first one in your head tag (possibly inlining it), and include the second one at the bottom of your body tag. If the second one depends on the first tag, do not use the async attribute, because it might get executed first.
If you have some large JS files that are only used on some pages, and those files depend on other JS files, stick your scripts at the bottom of your body tag and use the defer attribute.
If you have javascript mixed in with your HTML, you can use a callback mechanism (like script.js), or you can build up execution queues like Google Analytics does, which the external script knows to look for when it first loads.
I have created an external JS file, this JS file contains some methodes that uses JQuery, i can't seem to find a way to refernece the JQuery file on JS file and user it there. Any help would be appreciated
Two things are important to reach your goal:
Include the javascript files. Include both files in your HTML via a script-tag, starting with jQuery to make sure it is loaded when used by your javascript.
Ensure jQuery. This is something way to less people tell you. If you write JS and jQuery for a long time, sooner or later you'll encounter a case where something is overwriting the $-variable. The $-variable is used by jQuery and everyone coding with it because of the obvious fact that it's just one char. However, jQuery doesn't have any "rights" or something for the $-variable, so basically anything or anyone could overwrite it. So I recommend your own javascript file looks like this:
(function($)
{
// your coding starts here.
})(jQuery);
You probably already encountered this when dissecting jQuery plugins from people who know what they're doing. It creates an anonymous function that takes one parameter which will be know by $ inside the function. The function is then immediately called and hands over the jQuery function. This way you can be sure that, whatever happens outside this function, inside of it $ stands for jQuery.
In your HTML file, include the jQuery file first and then your file:
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="myfile.js"></script>
As long as you include the jQuery core in your HTML, the global jQuery object is available in any of your scripts. Is there a specific problem you're having?
You must write a piece of script (plain JS) that checks for the presence of jQuery, if not, it must append a script reference to the page pointing to a jQuery file (or Google CDN) to include jQuery. After that, you can use jQuery in the rest of your script.
I think it will involve some interval that checks wheter the jQuery object is present or not and waits with executing the rest of your code till that it the case.
Google for this, I'm sure there is something out there.
In my custom JS code file I use various plugins, for instance, the Masonry plugin for JQuery. However, I don't include the plugin on every page or at the master page file level (in some yes, in some no) but I do include my custom file on every page. Therefore, the code in my JS file will issue an error if the Masonry plugin is missing.
If someone could reply with a solution of how to:
Check if certain JS plugin was referenced (included) and only run the code then,
(optionally) include the file at runtime if it is missing.
I have it working with JQuery and JQuery UI because they both introduce a class into DOM structu (jquery and jquery.ui objects) but there are other plugin's like lightbox scripts, the forementioned Masonry etc..
Rather than checking whether a particular JavaScript file has been 'included', I'd just check if the functionality that you need is available (i.e. if you need a function named foo, just do something along the lines of typeof foo == 'undefined' to see if it is there ...).
What you are trying to do is probably a bad idea, but anyway here's how to determine if a given plugin has been defined. In jQuery they are just namespaces to the jQuery scope:
if(!jQuery().somePlugin) {
// the plugin is not loaded => load it:
jQuery.getScript('/url_of_the_plugin', function() {
// the plugin is now loaded => use it
});
}
You can only check if its class or methods are defined, in your case:
if (typeof($.fn.masonry) == 'undefined') ...
Anyway, I'll recommend including every script at every page, compressed into one file. The cost of downloading and parsing potentially not needed code is often far less than penalty of having multiple HTTP requests.
Off the bat Magento comes with more than half a dozen JavaScript libraries which do not help with the already cumbersome load times. Has anybody been able to successfully use a script loader like head.js or labjs with Magento so that they can load asynchronously? I have been trying but can't get it to work.
Seems as though the in-line scripts on the pages are firing before the libraries are loaded. I know that head.js has a function like head.ready to tell a script to execute , but there are so many in-line scripts it is not practical to add this to every occurrence in the whole site.
Regarding the inline scripts, there is a programmatic solution.
You could write an Observer that binds to the core_block_abstract_to_html_after or controller_action_layout_render_before Events which fire immediately prior to outputting the rendered HTML. In your Observer, you could use a preg_replace to insert a head.ready statement immediately after each <script> tag.
It would add a fraction more to the render time, but I suspect it would be less than the latency of downloading the libraries. And if you're using full page caching, then the function would only be called once.
You could use the inbuilt Magento Profiler to test the impact. Worth a try at least.
HTH,
JD
well, i use jquery for this. and it works great.
All you have to do is to make an ajax request that returns the script and then evaluate the script using eval. You can write your own function for this, but jquery already has some nice approaches.
For single scripts, the $.getScript function works well. It's basically an extension of the $.ajax function that specifies that you are requesting a script. the syntax is like this :
$.getScript('my_script_url',function(){
// do whatever needs to be done after the script loads
alert('my script was asynchroniously loaded');
});
If you have more scripts that you want to add through ajax, jquery has a neet way of doing this :
$.when(
$.getScript("/script_1.js"),
$.getScript("/script_2.js"),
$.getScript("/script_3.js")
// ...
//$.getScript("/script_n.js")
).then(
// on succes
function(){
alert('good to go!');
},
// on failure
function(){
alert('loading failed. one or more scripts encountered a problem :(');
}
);
All loaders of this nature are going to require some modification to every script on your site. I know--I just implemented LABjs on a system which, when I grepped, showed over 400 files with some sort of script tag!!
What is the general developer opinion on including javascript code on the file instead of including it on the script tag.
So we all agree that jquery needs to be included with a script file, like below:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"
type="text/javascript"></script>
My question is, in order to get functions on a page that is not on all pages of a site. Do we include the functions like below in the same page or in a global include file like above called mysite.js.
$(document).ready(function(){
$(".clickme").click(function(event){
alert("Thanks for visiting!");
});
});
ok. So the question is: if the code above is going to be called in every class="clickme" on a specific pages, and you have the ability to call it either from an include separate file called mysite.js or in the content of the page. Which way will you go?
Arguments are:
If you include it on the page you will only call it from those specific pages that the js functionality is needed.
Or you include it as a file, which the browser cached, but then jquery will have to spend x ms to know that that function is not trigger on a page without "clickme" class in it.
EDIT 1:
Ok. One point that I want to make sure people address is what is the effect of having the document.ready function called things that does not exist in the page, will that trigger any type of delay on the browser? Is that a significant impact?
First of all - $("#clickme") will find the id="clickme" not class="clickme". You'd want $(".clickme") if you were looking for classes.
I (try to) never put any actual JavaScript code inside my XHTML documents, unless I'm working on testing something on a page quickly. I always link to an external JS file to load the functionality I want. Browsers without JS (like web crawlers) will not load these files, and it makes your code look much cleaner to the "view source".
If I need a bit of functionality only on one page - it sometimes gets its own include file. It all depends on how much functionality / slow selectors it uses. Just because you put your JS in an external JS file doesn't mean you need to include it on every page.
The main reason I use this practice - if I need to change some JavaScript code, it will all be in the same place, and change site wide.
As far as the question about performance goes- Some selectors take a lot of time, but most of them (especially those that deal with ID) are very quick. Searching for a selector that doesn't exist is a waste of time, but when you put that up against the wasted time of a second script HTTP request (which blocks the DOM from being ready btw), searching for an empty selector will generally win as being the lesser of the two evils. jQuery 1.3 Performace Notes and SlickSpeed will hopefully help you decide on how many MS you really are losing to searching for a class.
I tend to use an external file so if a change is needed it is done in one place for all pages, rather than x changes on x pages.
Also if you leave the project and someone else has to take over, it can be a massive pain to dig around the project trying to find some inline js.
My personal preference is
completely global functions, plugins and utilities - in a separate JavaScript file and referenced in each page (much like the jQuery file)
specific page functionality - in a separate JavaScript file and only referenced in the page it is needed for
Remember that you can also minify and gzip the files too.
I'm a firm believer of Unobtrusive JavaScript and therefore try to avoid having any JavaScript code in with the markup, even if the JavaScript is in it's own script block.
I agreed to never have code in your HTML page. In ASP.net I programmatically have added a check for each page to see if it has a same name javascript file.
Eg. MyPage.aspx will look for a MyPage.aspx.js
For my MVC master page I have this code to add a javascript link:
// Add Each page's javascript file
if (Page.ViewContext.View is WebFormView)
{
WebFormView view = Page.ViewContext.View as WebFormView;
string shortUrl = view.ViewPath + ".js";
if (File.Exists(Server.MapPath(shortUrl)))
{
_clientScriptIncludes["PageJavascript"] = Page.ResolveUrl(shortUrl);
}
}
This works well because:
It is automagically included in my files
The .js file lives alongside the page itself
Sorry if this doesn't apply to your language/coding style.