Okay I've been doing JS merges for some time now and still can't figure out the logic behind making a successful merge. It comes down to repositioning libraries upwards and downwars on merge list. Sometimes jquery must be on top, sometimes it doesn't. Sometimes fancybox needs to be added as addJs, sometimes as addItem.
So, what is in your experience causing JS libraries to break when you use Magento's merge JS? Are there any rules for sucessful merge?
UPDATE: Just now in my local.xml I moved from
<action method="addItem"><type>skin_js</type><name>js/magiczoomplus.js</name></action>
to
<action method="addJs"><script>jquery/magiczoomplus.js</script></action>
and that solved the magiczoomplus error I was getting on the page. How so?
I'm trying to understand this problem so I can better tackle it in the future
you need to understand the core principle here what conflicts between javascript libraries and what not.
in case of jQuery and Prototype conflict and in Magento:
always include jQuery before any other script on your page , before Prototype is a must
add jQuery.noConflict(); call directly to the end of your jQuery library file
make sure that none of your jQuery based scripts are not using $ as method name (essence of the conflict here)
If there are any problems after Javascript merging is enabled, I always tried to replace minimized Javascript files with non-minimized versions of those files. And it always solved the problems. (I don't know why there are problems with minimized files)
Not alot of options to actually fix merging but
1.) Use group-ing in your local.xml files to ensure a better merge.
http://fishpig.co.uk/blog/why-you-shouldnt-merge-javascript-in-magento.html
2.) Abandon Magento's built-in merging altogether and use Fooman_Speedster instead.
http://www.magentocommerce.com/magento-connect/fooman-speedster.html
The second one has worked perfectly for me so far. I'm using jQuery libraries and even more (Handlebars, etc) and i'm having no problems whatsoever.
What worked for me was moving the jQuery include after prototype and adding jQuery.noConflict(); after the jQuery include.
What works for me after all this time, is:
Always putting jQuery on top, followed by noConflict
Toggling between compressed and uncompressed version of included JS (if you enable gzip compression you should not be worried about the final size - it will be compressed one way or another)
Toggling between addItem and addJs inclusion methods
Randomly repositioning erroring libraries
Related
So I want to use Lazysizes (lazy loading responsive images). Included in my Grunt stack is Responsive Images Extender, which outputs responsive image code (srcset) from simply including an "img" tag with a "src" attribute. Lazysizes requires the "data-srcset" attribute in replace of the "srcset" attribute, however. I added a script to my page that changes the "srcset" attributes to "data-srcset" attributes, but this isn't ideal as images are are already downloaded at runtime. It would be ideal if I could change the tags with Grunt, as there is no advantage in changing them live.
This seems like a very common thing, but I cannot find a good way to do it. String replace doesn't seem like an ideal solution, since it can cause problems if I ever use "srcset=" in my code.
I gave the grunt-responsive-images-extender a major makeover and added the possibility to change the attribute name of srcset to anything you want (data-srcset in your case) via the srcsetAttributeName option.
There is a grunt tans called dom_munger. With dom_munger you can change HTML attributes and do a lot of interesting stuff; however I cannot find a way to change an attribute name to another thing. Perhapse you can have a better luck checking it.
I have a form that normally works with respect to dirtyforms. However, there is one circumstance where a jquery-ui datapicker calendar will pop up the "are your sure" dialog when a date is clicked.
I emphasize that this normally works correctly. The situation is related to the initial conditions of the form data source. Things work when the object being referenced is existing, but not if it is new. So I am sure somewhere there is a difference in the initial conditions of the form. But in theory the form should be identical.
How can I find what is causing the popup so I can fix my issue?
Well, I did find what was causing my problem by comparing the HTML of the working and non-working situations. (Not an easy task since there were many non-relevant differences.)
Seems that the original coder did a strange thing. Left out some Javascript function declarations when the page was "new" but of course did not eliminate the calls on those functions.
So I guess that the javascript errors were the root cause. At least when I include those function declarations everything works correctly.
By default, most anchor links on the page will trigger the dialog. We don't have a hard-coded selector of all potential 3rd party widgets, you must manually take inventory of whether these widgets use hyperlinks and ignore them if they are causing errant behavior.
See ignoring things for more information.
I was unable to reproduce this behavior using Dirty Forms 2.0.0, jQuery UI 1.11.3, and jQuery 1.11.3. However, in previous versions of Dirty Forms, you can probably use the following code to ignore the hyperlink clicks from the DatePicker.
$('.ui-datepicker a').addClass($.DirtyForms.ignoreClass);
I'm building my first ajax-heavy application and am not sure of the proper approach for such things.
If, for example I ajax in a html partial (a form), with:
$('#content').load('form.html');
how should I include the javascript and css?
I can, of course include them in the original document, but that seems wasteful if the form is never loaded. I can inline them (in form.html) with <script> and <style> elements, but that seems like the wrong approach.
You can use a separate JS file and load it using $.getScript() in the .load callback.
Inline CSS should work fine, but since you run the risk of it messing up your main page, you should load it as part of the main page and not with AJAX.
If it were me, though, I wouldn't be afraid to leave a few extra lines of well-targeted JS and CSS code in your main page -- it's more efficient to load it with the other JS and CSS at the beginning, in the same file(s), than to fire off another network connection and wait for it to download.
The $.getScript() would make an additional http request to load the js file that is to be used in form.html.
So, say for example, if you load 20 forms via ajax, you have to make 20+20 http request( 20 for loading js file and 20 for loading the html for forms)
A possible optimized approach is:
loading the all the css ( minified) at the beginning.
IF a single js file is real large even after minifying,
Arrange the js functionality based on the PROABABILITY of use in different files ( (the fewer number of files , the better).
Minify those files and load the file with highest probability at the beginning .
And then use $.getScript() to load the file after checking if the file has already been loaded.
Twofold question.
Using a web template that utilizes AJAX for loading new pages, rather than traditional point-the-browser-to-the-url style, how would one go about adding new script or style tags to the page head as necessary?
I think using jQuery $('head').append(script); works just fine, but (and here's the second half), if I wanted to group all of the scripts that were page-dependent away from those that are universal across the site - how would I do that?
Using a div sounds so enticing since I could print it at the initial page render and just call
$('head div.external').append(script), but still probably a bad idea inside the head.
Is there any other element or method I could use to group these? The goal being to easily remove all of them when the user navigates away from the current page. A smaller consideration is that Google Analytic instructs you to place it at the end of the head tag (I'll be honest, I don't know why being the last script matters), and I don't want my scripts to interfere. Do these even need to be in the head, could I place a div at the end of the body and use that?
Surely the easiest way to do this, if it is necessary, is with classes:
$(script).addClass('external').appendTo('head');
then later:
$('script.external').remove();
I'm honestly not sure what this would achieve, however.
When cached, my starting page only needs to load one element (the "root document") - but then it needs some time until it's rendered completely:
alt text http://www.walkner.biz/_temp/firebug_net.png
The elements following are things loaded asynchronous via JavaScript.
Two questions:
Why does it take so "long" from loading the root document until the DomContentLoaded-event?
Does it make sense to load some not-so-important things asynchronously? Is it important to have the DmoContentLoaded-event as early as possible? Unfortunately there's not much documentation about that event, but I don't think it's the moment when the page is displayed, is it?
I'm not sure YSlow is gonna help him as that will download all elements for a page and run performance tests on them, whereas swalkner's problem is how long it is taking to render the HTML page itself when all other elements (images, CSS, etc) are cached.
At least that's what I think he's saying.
In the original question you said, "The elements following are things loaded asynchronous via JavaScript." but then listed nothing. What is loaded?
I would suggest checking for Javascript errors in the first instance. Then try removing some of your asynchronous loading calls one by one until you hit the bottleneck. In fact, remove them all, how long does the downloaded HTML take to render? Take that time and work from there.
Is your HTML document very big? Does it use lots of inline styles that could be in the CSS file?
Perhaps if you posted a link to the site then people would have a look at it.