How to reduce JavaScript Files in Magento? - javascript

I am new to Magento but work in webdev for several years now.
My goal is to optimise an existing Magento installation in terms of speed.
Looking at all the JS and CSS files used within this installation the first thing I aim for is to combine those file or better reduce the number of modules used. I am aware of the "combine files" function within the config menu, but that does lead to conflicts between jQuery and prototype which is why I am trying to first get an understanding of what types of frameworks/modules etc are used.
This is a list of all JS-files required by the homepage of this installation:
jquery-1.12.3.min.js
prototype.js
ccard.js
validation.js
builder.js
effects.js
dragdrop.js
controls.js
slider.js
js.js
form.js
script.js
menu.js
translate.js
cookies.js
func.js
jquery.easing.1.3.min.js
efects.js
jquery-1.11.0.min.js
jquery-migrate-1.2.1.min.js
jquery.noconflict.js
swiper.min.js
jquery.easing.js
jquery.scrollTo.min.js
jquery.global.js
remodal.min.js
jquery.themepunch.tools.min.js
jquery.themepunch.revolution.min.js
easyzoom.js
ios-orientationchange-fix.js
jquery.swipebox.min.js
jquery.themepunch.plugins.min.js
jquery.themepunch.revolution.js
jquery.slider.js
jquery.selectbox.js
jquery.bxslider.min.js
jquery.tweet.js
cookieconsent.min.js
gtm.js?id=GTM-5W7V6F
analytics.js
ec.js
What would be the best approach to clean up this list in order to keep functionality while reducing request and load?

For starters i see that you load 2 versions of jQuery
jquery-1.12.3.min.js and jquery.easing.1.3.min.js
What i did was combine the javascript files with the config settings like you said and use the jQuery.noConflict() https://api.jquery.com/jquery.noconflict/. Don't use the $ (dollar) sign to use jQuery but write it fully because prototype also uses it and it creates problems sometimes. There will be some problems which you should try to fix. Sometimes it's just adding a ; to the end of the file or function.
I then tried to figure out what code was needed and what wasn't so i could remove some of it.

Magento Inbuilt provide this things
Login admin panel
goto System->configuration->Advanced->Developer->JavaScript Settings and set Merge JavaScript Files to yes
You can do same for css and you will see very few request in your web page

Related

Trying to avoid multiple calls to jQuery in a Domino XPage

I am attempting to use the 'DataTables' table plug-in for jQuery on a simple Domino XPage.
I have loaded the two required libraries from CDN's...
JQuery: ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
DataTables: cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css
I have also tried loading them from local resources (doesn't help).
I then prepare a basic table on my XPage, and include the necessary Javascript to initialise the table...
$(document).ready(function() {
    $('#tableID').DataTable();
} );
When I test the XPage, I continually observe
test.xsp:15 Uncaught TypeError: $(...).DataTable is not a function
I've searched through several forums, and the general consensus is that...
a) I have loaded the libraries in the wrong order (nope!)
b) I have loaded jQuery more than once (how?)
I have many other solutions using Bootstrap and jQuery, and have never run into this issue before. So, I though I might strip the XPage back to bare bones. I got rid of all Dojo elements on the page by adding the following line to the 'xp.properties' file...
xsp.client.script.libraries=none
That actually seemed to work! I no longer observed the error. However, my page no longer looked like it should (for obvious reasons!). I've had to restore the 'xp.properties' file back to its original state, but cannot find out how to avoid the error.
Has anyone successfully used the 'DataTables' jQuery plug-in on an XPage? Any feedback or suggestions would be most appreciated!
Yes I have been doing a load of work on DataTables in XPages so it definitely works! I know your pain though....
The order of your jquery scripts in relation to each other may be okay, however there is a clash with dojo and it's AMD loader, so you have 3 options.
Option 1. Load your jquery scripts before any of the xpages scripts
Option 2. remove the 'amd loader' just before your jquery scripts and then restore it just after
Option 3. modify the javascript of the datatables so it ignores the amd problem
Option 1 : Loading your jQuery scripts first
If you are using resource aggregation, you can use this tip from Sven Hasselbach's blog, in which you use the generic 'headTag' resource tag and it will load first.
http://hasselba.ch/blog/?p=1181
If you want a solution that will work regardless of resource aggregation setting, I have an example on my blog in which you can create a viewRootRenderer which will then allow you to specify that you want a script loaded BEFORE everything else
http://camerongregor.com/2016/09/19/controlling-the-order-of-script-resources-e-g-jquery-with-a-custom-viewrootrenderer/
Option 2. Removing the AMD loader before loading scripts
There is an xsnippet which explains how to remove and then restore the amd loader so that a jquery plugin will load
https://openntf.org/xsnippets.nsf/snippet.xsp?id=hack-to-use-jquery-amd-widgets-and-dojo-together
Sven had already made a similar solution to mine above (viewRootRenderer) in which you can specify which scripts will need the amd loader disabled and it will do this for you, it is available here
http://hasselba.ch/blog/?p=2070
Option 3 : modify javascript of the jquery plugin (datatables)
Mark Roden demonstrated this on his blog. I don't really like doing it but hey it works!
https://xomino.com/category/jquery-in-xpages/
Let me know if any of this works! I hope I'm right, with javascript I never know...

Bundle is loaded in the wrong order

In my _Layout view I'm including the following scriptbundle:
bundles.Add(new ScriptBundle("~/bundles/js").Include(
"~/Scripts/jquery.min.js",
"~/Scripts/jquery-ui.min.js",
"~/Scripts/bootstrap.min.js",
"~/Scripts/jquery.flot.categories.js",
"~/Scripts/jquery.flot.js",
"~/Scripts/jquery.flot.min.js",
"~/Scripts/jquery.flot.orderBars.js",
"~/Scripts/jquery.flot.pie.js",
"~/Scripts/jquery.flot.resize.js",
"~/Scripts/graphtable.js",
"~/Scripts/fullcalendar.min.js",
"~/Scripts/chosen.jquery.min.js",
"~/Scripts/autoresize.jquery.min.js",
"~/Scripts/jquery.autotab.js",
"~/Scripts/jquery.jgrowl_minimized.js",
"~/Scripts/jquery.dataTables.min.js",
"~/Scripts/jquery.stepy.min.js",
"~/Scripts/jquery.validate.min.js",
"~/Scripts/jquery.cookie.js",
"~/Scripts/raphael.2.1.0.min.js",
"~/Scripts/justgage.1.0.1.min.js",
"~/Scripts/glisse.js",
"~/Scripts/styleswitcher.js",
"~/Scripts/moderniz.js",
"~/Scripts/jquery.sparkline.min.js",
"~/Scripts/slidernav-min.js",
"~/Scripts/jquery.fancybox.js",
"~/Scripts/main.js",
"~/Scripts/application.js",
"~/Scripts/excanvas.min.js",
"~/Scripts/float.settings.infobox.js"
));
The thing is; when I load the page and look at the network traffic I see that jquery-ui.min.js is loaded first (before jquery.min.js)!
Here is the order in which they load in:
I thought the scripts would load in the order I specified them in. Am I wrong? And if so, how should I load them in the proper order?
EDIT:
I tried adding a custom sort as described here:
http://stevescodingblog.co.uk/changing-the-ordering-for-single-bundles-in-asp-net-4/
However I get the following error when building the project:
Error 1 'Namespace.AsIsBundleOrderer' does not implement interface member 'System.Web.Optimization.IBundleOrderer.OrderFiles(System.Web.Optimization.BundleContext, System.Collections.Generic.IEnumerable)'
Some things that can cause this problem:
Buggy version of ASP.NET Web Optimization Framework. Update to 1.1.3 or later.
Explicit names are always processed before symbolic names.
Explicitly named dependent of symbolically named libraries
Knockout-jqueryui.js doesn't have a version in its name. It depends on jQuery and jQuery UI. Both of these have versions in their names. If you use symbolic names like jQuery-{version} to refer to these libraries, because knockout-jqueryui is named explicitly, it will be loaded in the first pass - before its dependencies.
Either name the versions explicitly or fudge a version number into the dependent library name and make them all symbolic.

Grails - Redeploy after javascript change

Recently I added conf/ApplicationResources.groovy (using resources plugin) file to my project structure. Here I keep my modules definitions for javascript and css libraries. Before, I was importing libraries with classic g:javascript tag.
Now every time when javascript code changes (while server is running) I get client side js error saying
"Uncaught SyntaxError: Unexpected end of input".
So for each javascript change application needs to be redeployed, what I dont want.
I have also declared .js files to be excluded from resources plugin pattern, but the problem remains. Any advice/help will be appreciated.
Solution from Sérgio Michels that worked:
Add to Config.groovy: "grails.resources.debug = true;"
To avoid cache issues with the Resources plugin, in all my projects I'm using the config grails.resources.debug = true in Config.groovy.
You still use <r:require modules=""/> in your GSP, but in development mode the source will show all files included instead of merging them.

Best way to import JavaScript files into one file?

I have a background in coding in languages that have a concept of "classes". Now that I am coding JavaScript, I would like to code in a similar way so that each object oriented "class" I create is its own separate file.
see Accessing "Public" methods from "Private" methods in javascript class
see http://phrogz.net/JS/classes/OOPinJS.html
In other languages, I would create import statements at the top of the class file to ensure other custom classes that were used within a class file so that the other custom classes were compiled into the final binary.
Of course JavaScript is not a compiled language; however, I would still like to be able to be include some kind of "import" statement at the top of custom class files so I could ensure the imported JS "class" file was available for the user's browser to download.
It would be ideal if there were a 3rd party tool that combined all of my separate class files into one JS file so the browser only had to make one HTTP request for a single JS file instead of many calls for each indicidual JS "class". Does anyone know if such a tool exists where it would do the following:
allowed me to choose which JS files that I wanted to include in a single JS file
crawled thru the files I selected in step 1 and found all the "import" statements at the top of each custom "class" file. These "import" statements could simply be specially formatted comments in the code that the 3rd party recognizes as import statements.
The 3rd party would then create the single JS file with all of the files that were selected from step 1 and from all of the imported files that were found in step 2.
Some popular JavaScript frameworks seem to do just that. For example, jQueryUI allows you to customize the download of a single jQueryUI source file by allowing the user to check off which objects you want to use. If you uncheck an element that is needed for an item that you checked off, then the form tells you that there is a dependency you need to rectify before being able to proceed to download the file.
see http://jqueryui.com/download/
So is there a 3rd party tool that allows a developer to use some kind of "import" statement comment to ensure that many dependent JS files (and only the ones that the developer needs) to be combined into a single JS file?
RequireJS was built for exactly this purpose.
Have a look at Require.js. It lets you import various javascript files in a modularized fashion and add the required dependencies between them. Also at the end you can minify them all into one single JS file using r.js
A trivial batch file can do this for you:
#for %i in (classes/*.js) type %i >> build.js
This works best if your JS source files are all in one folder, and this example assumes that folder is named classes. It gets a bit more complicated if you have subfolders, but a similar principle can be applied.
Have a look at GruntJS, JQuery uses it for building. If you don't care for HTTP requests, you can use already mentioned RequireJS, which also has nice async methods to load files, which can improve perfomance in some situations.
Check out this class https://www.youtube.com/watch?v=KnQfGXrRoPM
This allows for importing on the fly within classes. also it allows
for importing all classes within an folder and all of its sub folders.
and its really simple because it is just a prototype function added to String.
just by adding the importer class you will call in classes like "com.project.Classfile.js".import();
or "com.project.*".import() to get all sub-classes.
fork on - https://github.com/jleelove/Utils

Injecting JQuery Cross-Domain

Is it safe to inject JQuery's script using JsonP?
The installation of my web application is - adding a script to a customer's website (like google analytics). I was thinking of using JQuery on the customer's website, as part of my own injected script.
I was wondering, if there is some kind of risk?
The application needs to support any kind of website.
Thank you
Yaron
Its hard to tell what you are doing with your library, but it seems you are building some type of widget for use on multiple sites.
From here down has been updated after an enlightening comment from #K Prime caused me research exactly how you could include two copies of jQuery if needed:
It is generally bad to use jQuery if you are building a widget that will live on a site outside your control, and will be added to the site with a "copy this embed code and paste onto your site" type of functionality. (Of course jQuery widgets and plugins abound, but these are normally chosen and installed/implemented by developers not a generic "copy-n-paste" widget type implementation)
Probably the biggest reason (after realizing you can run two copies of jQuery on the same page) is the file size increase. Whether it is warranted will depend on your particular needs and function. Simple small widget = straight JS. Complex website front-end extension, then it probably is worth the file-size increase.
To include it properly (so you don't run into conflicts on their site) follow a workflow that looks something like this:
Dynamically add jQuery to their page using the Google APIs as mentioned on the other answers here.
Run var mywidget_jQuery = $.noConflict( true ); which will restore the original meaning of $ and restore the original meaning of window.jQuery.
Dynamically add your script file, but be sure to wrap the entire thing in a self executing anonymous function like this:
JS
(function($){
... Your code here ...
})(mywidget_jQuery);
Now, you can safely use $ inside your special function and all the jQuery features you want without issue.
Extra credit You could wrap steps 1 and 2 in an if statement that tests if window.jQuery is defined and if it, test if jQuery.fn.version is high enough to run your code. If either test fails, then run steps 1 and 2. If it passes, however, then just run var mywidget_jQuery = window.jQuery so the script you include in step 3 will still run.
You can add jQuery to a website by simply adding a <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.js" /> element.
However, make sure to call jQuery.noConflict() in case they use a different $ keyword.
If you're just after a reference to the library, why wouldn't you just link to the API hosted on Google Code?

Categories