Foros de discusión

Javascript file loading sequence

Peter Helgren, modificado hace 6 años.

Javascript file loading sequence

Regular Member Mensajes: 124 Fecha de incorporación: 14/11/13 Mensajes recientes
I had some issues with proper page rendering when JavaScript was involved. Particularly "external" JavaScript in files. Typically, I load JavaScript on a page at the bottom and if I need to call an initial function, I put it in a
     $(document).ready(function(){}); 
block. That way I know that the page, including the JavaScript references are loaded before I call any functions.

Following that pattern, I reference the javacsript in the portlet like so in the @Component property annotation:


			"com.liferay.portlet.footer-portlet-javascript=/js/file1.js",
			"com.liferay.portlet.footer-portlet-javascript=/js/file2.js",


Up until a few hours ago, I thought that was correct but after some extensive debugging, it seems like the loading sequence is:

1) Load the portlet template file (FTL in my case)
2) Load the JavaScript files

So the $(document).ready function fires before the JavaScript is loaded. Is that correct? When I moved the functions I would normally call in $(document).ready to the JavaScript file, that function was properly invoked. When it was in the $(document).ready function, it called the function but couldn't find it because the JavaScript hadn't been loaded, or so I assumed.

Did I find a weird corner case or is this how it works (Load template, load JavaScript)?
thumbnail
David H Nebinger, modificado hace 6 años.

RE: Javascript file loading sequence

Liferay Legend Mensajes: 14919 Fecha de incorporación: 2/09/06 Mensajes recientes
Peter Helgren:
Up until a few hours ago, I thought that was correct but after some extensive debugging, it seems like the loading sequence is:

1) Load the portlet template file (FTL in my case)
2) Load the JavaScript files

So the $(document).ready function fires before the JavaScript is loaded. Is that correct?


Well, somewhat. If you're talking about LR7, it uses Senna.js extensively to asynchronously load portlets after the initial rendering. So jQuery's document.ready() will call early because it doesn't really know that the document is not ready.
Peter Helgren, modificado hace 6 años.

RE: Javascript file loading sequence

Regular Member Mensajes: 124 Fecha de incorporación: 14/11/13 Mensajes recientes
OK! Yes, this is LR 7.... You confirmed what I needed to know before I modified a couple of other script files.

My solution, which will probably come back to haunt me at some point, is to just add a third JavaScript file, listed last (may not make a difference) in the @Component annotation that just has the function calls I would normally invoke in document.ready(). So the sequence I am assuming is taking place is:

1) Template loads
2) First JavaScript file loads
3) Second JavaScript file loads
4) Third JavaScript file with the function invocations normally found in document.ready() loads

The only thing I am invoking in the third script file are Ajax functions that populate the page with data which I only want to run AFTER the page loads and AFTER my script files that have the Ajax functions in them have loaded. I left the other entries in document.ready() untouched...like event handlers that really only need the page to be ready.

So far, this has worked but it runs on the assumptions listed above...until it stops working and then I'll need to figure how to handle it next...

Thanks again.
thumbnail
David H Nebinger, modificado hace 6 años.

RE: Javascript file loading sequence

Liferay Legend Mensajes: 14919 Fecha de incorporación: 2/09/06 Mensajes recientes
Have you checked https://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/understanding-your-themes-javascript-callbacks-in-main-js?

Basically we don't use the jQuery(document).ready() function because it is not compatible with async loading. The methods listed in the given link are supposed to be the ones that will work.
Peter Helgren, modificado hace 6 años.

RE: Javascript file loading sequence

Regular Member Mensajes: 124 Fecha de incorporación: 14/11/13 Mensajes recientes
It's probably not relevant but in this case it is a portlet rendering an FTL template (rather than a JSP) the article refers to Themes. Current work around seems to be OK but when I get the chance I'll do some more reading about JavaScript loading in portlets. Always more to learn...
thumbnail
David H Nebinger, modificado hace 6 años.

RE: Javascript file loading sequence

Liferay Legend Mensajes: 14919 Fecha de incorporación: 2/09/06 Mensajes recientes
That link points to the use of, for example:

Liferay.on('allPortletsReady', function() {
    }
);

So unlike jQuery(document).ready() which really doesn't know when all of the portlets have been loaded, the given function will be called when the portlets actually are ready.
Peter Helgren, modificado hace 6 años.

RE: Javascript file loading sequence

Regular Member Mensajes: 124 Fecha de incorporación: 14/11/13 Mensajes recientes
OK. Again, thanks. I'd have to think that through a bit. Almost all the portlets I have have an Ajax component that loads data onto the rendered page so I'd have to walk through the options for invoking an "init" function in those portlets that would call the functions that return the data and populate the page. But that could be a handy, universal way to invoke the function.

Great stuff in LR...much to learn...