Google Optimize JS - jQuery error - asynchronous

I tried optymalize my site with PageSpeed Insights.
This Google tool shows me error :
"Eliminate blocking rendering JavaScript code".
I moved all script code from head at the end of the page.
Error was fixed, but now I get in console error:
ReferenceError: $ is not defined $(document).ready(function() {
The reason of error is probably several js codes in body section.
How I can eliminate this?
Do I must move code from body at the end of the page or there are other solution?

It's a dependency problem, something is using jQuery (probably) before it's initiated. Is the jQuery loader script still in header, or above the script that uses $(document).ready()?
Some scripts are asynchronous and some are not. Keep this in mind also, because if jQuery for instance is loaded asynchronous and is above your script, and your script is loaded synchronous, it might not matter. Your script would still be loaded before the async script has finished loading.
There is no need to place asynchronous script in the bottom of the body - and sometimes PageSpeed is not correct in it's assumptions about block rendering scripts. You can also try the "defer" HTML attribute on the script tags you want to defer after DOM is ready.
http://caniuse.com/#feat=script-defer

Related

Removing render blocking JS and CSS causing issue in my WordPress website

i'm trying to improve speed of my website. i'm using PageSpeed Insights to check my site performance and it was telling me to remove render blocking java script and css. so i did it and know its causing problem in my website design. so what should i do to remove rendering blocking without causing problem in my website design.
Render Blocking CSS
Render blocking CSS will always show on Google Page Speed Insights if you are using external resources for your CSS.
What you need to do is to inline all of your 'above the fold' styles in <style></style> tags in the head of your web page.
I will warn you, this is NOT easy and plugins that claim to do this often do not work, it requires effort.
To explain what is happening:-
A user navigates to your site and the HTML starts downloading.
As the HTML downloads the browser is trying to work out how to render that HTML correctly and it expects styling on those elements.
Once the HTML has downloaded if it hasn't found styles for the elements that appear above the fold (the initial part of the visible page) then it cannot render anything yet.
The browser looks for your style sheets and once they have downloaded it can render the page.
Point 4. is the render blocking as those resources are stopping the page from rendering the initial view.
To achieve this you need to work out every element that displays without scrolling the page and then find all the styles associated with those elements and inline them.
Render Blocking JS
This one is simpler to fix.
If you are able to use the async attribute on your external JS then use that.
However be warned that in a lot of cases this will break your site if you have not designed for it in the first place.
This is because async will download and execute your JS files as fast as possible. If a script requires another script to function (i.e. you are using jQuery) then if it loads before the other script it will throw an error. (i.e. your main.js file uses jQuery but downloads before it. You call $('#element') and you get a $ is undefined error as jQuery is not downloaded yet.)
The better tag to use if you do not have the knowledge required to implement async without error is to use the defer attribute instead.
This will not start downloading the script until the HTML has finished parsing. However it will still download and execute scripts in the order specified in the HTML.
Add async in the script tag and put the css and js in the last of the page

Adding Moment.js CDN Link in HTML

I can't properly add in the CDN for moment.js to my HTML page. I'd rather just add a link in my html than install. Anyone know how to this? I've tried a few CDNs and nothing is working. Is there a reason to put the link in the head vs just before closing body tag with other JS links? I've seen it done both ways.
If you want to point to the latest,
You can link directly from their website.
Here is the link,
https://momentjs.com/downloads/moment.js
You can use the following link for the moment.js:
<script src="https://rawgit.com/moment/moment/2.2.1/min/moment.min.js"></script>
The imports done in the head suppose to load onto DOM before the content of the body vs at the end near the body closing tag, when all the code above supposedly have been load onto the DOM
However, we often deal with async code when working with javascript.
So, if you have a local script that depends on an external CDN library to be available, you can add defer to the end of your local script. the defer will wait for all content to be available on DOM to continue loading.
example:
<script src=xxx" defer></script>
I would place where it looks more cohesive. Perhaps you sign the loads with async and defer to deal with the loading order, depending on the scripts relevance. Find more on the primary discussion.

Wordpress - How to defer parsing of Javascript to execute after DOM loads?

I am using wp_enqueue_scripts() to set my JS files and I am putting them in the footer using the last parameter
But testing in gtmetrix, I still see that I need to defer parsing of Javascript.
How do I defer parsing of Javascript to execute after DOM loads in Wordpress? Is there a parameter perhaps to wp_enqueue_scripts() that can do this?
First if all, wp_enqueue_scripts() will only load scripts in the footer if you set the fifth parameter. Even if you do that, if the file contains content that will execute without user interaction then you should be wrapping that in a jQuery.ready() call.
The latter part has nothing to do with wordpress. That's a basic web development rule.

Chrome Extension: Communication iframe <-> Content Script

Well, a often discussed thing. But I can't get it work. What has to be done:
The Content or Background Script has to communicate with the iframe et vice versa.
The iframe is under my hand, so there is everything possible.
I tried a lot. It doesn't work at all. For instance: If I deploy the content script on every page with allFrames=true via (manifest). Ok, makes sense. The iframe is created later so the trigger won't be called. So let's do this: create the iframe and afterwards sending an executeScript request:
chrome.tabs.executeScript(tabinst.tab_id, { allFrames: true, file:'frame.js'}, function() {
console.log("done");
});
But that doesn't work either. Has anyone a solution to communicate with an XDM iframe and a chrome extension?
PS: How nice it would be if the chrome extension would allow postMessage on iframe
EDIT1:
The code doesn't get injected in the iframe. Scenario:
The file "file.js" has a simple foo function in it. I now apply it with the above statement 2 seconds after the iframe was created and showed. This function foo is not available in the iframe...but is in the content script. The ReferenceError is thrown by trying to execute foo within the iframe (by click).
So, it's not a timing thing. And it doesn't matter if I apply the Scripts via manifest and all_frames true. If that would work, the content_script would be available. But is not.
EDIT2:
#serg
Yeah, thanks, that works! I just got through it. My problem was, that I assumed that when the callback of chrome.tabs.executeScript is called, the requested script is ended and the including DOM manipulation finished. But that's actually not the case. It takes some time till the script in the iframe and the containing listener is ready.
So I had to send a chrome.extension.sendRequest from that script in the iframe and then start some code out of the background listener to manipulate the iframe. Thanks for your help.
PS: It's also possible to do it without "all_frames": true. It just takes some time till the dynamic iframe is ready. With a timeout it works. For the most cases, this is not useful, but maybe someone has another user interaction first.
PPS: I still can't see why it's possible like this, and not possible to send postMessage events. But maybe somewhen this will works.
I just tested and content script is getting injected into dynamically created iframes (I used manifest). I think the problem is you are trying to access content script's function within iframe, which is not allowed.
Inside your iframe you can't just do:
<a onclick="contentScriptFunction()"></a>
You need to be adding event listener from within the content script:
$("a").click(contentScriptFunction);

External JS file in web user control?

In a html page we use the head tag to add reference to our external .js files .. we can also include script tags in the body .. But how do we include our external .js file in a web user control?
After little googling I got this. It works but is this the only way?
ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "MyUniquekey", #"<script src=""myJsFile.js"" type=""text/javascript""></script>", false);
-- Zuhaib
You can also use
Page.ClientScript.RegisterClientScriptInclude("key", "path/to/script.js");
That's the way I always do it anyway
Yes this works too .. but why does all
the script gets dumped in the body and
not in the head??
There's a potential workaround for that here
That's kind of incorrect .. about needing the Javascript in the body.
A Javascript function would sit in the head unexecuted and not at all affected by the fact that elements are still to load.
Often there is a single call at the end of a page to start execution of scripts at the top.
(Other methods available)
The only reason that script gets dumped in the body, is because MS doesn't seem to give 2 hoots about JavaScript.
Shame, because forcing us all to use .NET proper, just makes the world full of sluggish pages that needlessly run back and forth to servers for the tiniest requirmenet.

Resources