homepage Welcome to WebmasterWorld Guest from 54.145.183.169
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
Loading widgets on click
Loading Addthis script only if clicked on by visitor
Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 7:08 pm on Mar 11, 2013 (gmt 0)

I'm not usually in this part of the forum, excuse my ignorance, but I haven't found anything after a search.

Has anyone tried to load the social sharing widgets (Addthis in our case) only onclick.

It was one of the ideas mentioned in a great presentation by Vitaly Friedman. If this worked it would cut the size of our pages in half, as well as better privacy.

We have the usual Addthis orange icon that opens on hover over, plus the email tell a friend which is great, but is it possible to code their js so that they only load if the visitor actually clicks on them. I presume there'll be a second or two while the script loads but hopefully just 1 click will be necessary.

What do you guys think?

 

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 7:26 pm on Mar 11, 2013 (gmt 0)

I haven't tried it myself, but I would suspect that there might be enough of a delay to make it seem unresponsive. Something to consider... maybe load it asynchronously when the page finishing loading (on the window onload event, load your library). That way, the page is still responsive more quickly.

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 7:45 pm on Mar 11, 2013 (gmt 0)

1. Looking at the waterfall chart of my site currently it averages out at around 500-800ms to load the 3 parts of addthis (js, css and something I presume is an iframe). In my opinion this is tolerable because:
2. I'll be converting the facebook share, tweet this and linkedin share icons to their normal sharing link (not widget). Along with print and bookmark these make up well over 90% of the sharing activity on our site. Given only about 2-5% of our visitors actually share, it's at the very most 0.5% of our visitors that actually need to use the Addthis widget.
Asynchronous works up to a point, though it's still a big pain point on mobile, as well as the privacy and tracking problems these widgets have.
IMO loading the whole widget for everybody is quite a performance hit considering the entire rest of the website is around 50Kb and 6 requests.
Any pointers is terms of code? I wasn't able to find much except the gmail lazy load code (which I haven't got to work).

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 7:53 pm on Mar 11, 2013 (gmt 0)

Fair enough.
Do you use any libraries like jQuery, YUI, etc.?

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 8:06 pm on Mar 11, 2013 (gmt 0)

No libraries - I like to keep things lean and fast. Even our sprite is a base64 data image :)
The site is pretty heavily optimised, and this is one of the remaining big wins in terms of speed, as well as ticking lots of other boxes.
If it helps I can paste in the standard anonymised addthis code.

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 9:11 pm on Mar 11, 2013 (gmt 0)

In that case, you'll be handling all of the AJAX interaction with plain old JavaScript. Perhaps something like this:


<script type="text/javascript">
function loadScript(src, callback) {
var s, r;
r = false;
s = document.createElement('script');
s.type = 'text/javascript';
s.src = src;
s.onload = s.onreadystatechange = function() {
if (!r && (!this.readyState || this.readyState == 'complete')) {
r = true;
if (callback !== undefined) {
callback();
}
}
};
document.getElementsByTagName('script')[0].appendChild(s);
}
loadScript('http://www.example.com/addthis.js', function () {
// Whatever initialization code addthis requires
});
</script>

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 9:36 pm on Mar 11, 2013 (gmt 0)

It's possible (probable) that I'm using that code example wrong, but it doesn't seem to work when I tested it out, with the script still loading automatically.
Maybe I'm not including the right parts in the 'whatever initialization code....' part.
The Addthis code isn't very straightforward - there are 3 parts to it and I'm not sure what goes where:
<a href="http://www.addthis.com/bookmark.php?v=250&amp;pub=example" class="addthis_button_compact">Share</a>
<script type="text/javascript">var addthis_use_addressbook = true; addthis_config = { data_use_cookies: false } </script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#pub=example"></script>

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 10:59 pm on Mar 11, 2013 (gmt 0)

Maybe something like this:
<a href="http://www.addthis.com/bookmark.php?v=250&amp;pub=example" class="addthis_button_compact">Share</a>
<script type="text/javascript">var addthis_use_addressbook = true; addthis_config = { data_use_cookies: false };
loadScript("http://s7.addthis.com/js/250/addthis_widget.js#pub=example");</script>

(and of course, the code in my last post above this)

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 12:49 am on Mar 12, 2013 (gmt 0)

FYI, I tried it and it worked. Let me know if you have any problems with it. :)

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 12:56 pm on Mar 12, 2013 (gmt 0)

Thanks Fotiman!
Here's the code I understood, and it seems to work (dreamweaver's giving me an error on the second <script type..> though):

<script type="text/javascript">function loadScript(src, callback) { var s, r; r = false; s = document.createElement('script'); s.type = 'text/javascript'; s.src = src; s.onload = s.onreadystatechange = function() { if (!r && (!this.readyState || this.readyState == 'complete')) { r = true; if (callback !== undefined) { callback(); } } }; document.getElementsByTagName('script')[0].appendChild(s);}<a href="http://www.addthis.com/bookmark.php?v=250&amp;pub=example" class="addthis_button_compact">Share</a>
<script type="text/javascript">var addthis_use_addressbook = true; addthis_config = { data_use_cookies: false };
loadScript("http://s7.addthis.com/js/250/addthis_widget.js#pub=example");</script>


It's working too well - there's now nothing to click on to load and call the script :)

This morning I've tried moving this (<a href="http://www.addthis.com/bookmark.php?v=250&amp;pub=example" class="addthis_button_compact">Share</a>) down to below the </script>, tried adding onMouseOver="javascript:loadScript()" to another link after the script (which would also cut down the latency), but it's either not loading at all, or when clicked it goes straight through to the full sharing screen instead of just opening the toolbox.

Any suggestions?

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 1:26 pm on Mar 12, 2013 (gmt 0)


...ntsByTagName('script')[0].appendChild(s);}<a href="http://www.addthi...

You're missing a closing </script> tag before your <a>. :)

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 1:41 pm on Mar 12, 2013 (gmt 0)

That's got rid of the error, but now we're back to the script always loading again.
Maybe it's the bookmark.php that's calling something? Would something like this help:
loadScript("http://s7.addthis.com/js/250/addthis_widget.js#pub=example";"http://www.addthis.com/bookmark.php?v=250&amp;pub=example class='addthis_button_compact'>");

I'm a bit out of my depth here as you can see!

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 1:58 pm on Mar 12, 2013 (gmt 0)

It's the call to loadScript that's loading it, so you would want to move that to your onclick handler. Note, though, that you'll want to set some global flag when it has been loaded to prevent loading it multiple times. For example:

var triggerElement = document.getElementById('trigger'),
addThisLoaded = false;
trigger.onclick = function () {
if (!addThisLoaded) {
loadScript("http://s7.addthis.com/js/250/addthis_widget.js#pub=example",
function() {
addThisLoaded = true;
});
}
};

Then in your markup, give whatever element is supposed to be the trigger for loading it an id of 'trigger' (or change this code example to get the element however you like). :)

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 2:19 pm on Mar 12, 2013 (gmt 0)

Some of those terms are starting to look familiar, trigger and id I've come across before in my searches - learning a lot today!
I'm not sure how that last code block you posted, however, fits in with the (corrected) code I posted in message 4553904 - is it a separate <script></script> or does it slot into the other list of vars in the last 2 lines?

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 2:28 pm on Mar 12, 2013 (gmt 0)

Note, trigger is not a specific term that's necessarily common, I just used it because you're going to have some element that, when clicked, is going to "trigger" the loading of your script. Here's an example where I've made that Share button the trigger:

<script type="text/javascript">
function loadScript(src, callback) { var s, r; r = false; s = document.createElement('script'); s.type = 'text/javascript'; s.src = src; s.onload = s.onreadystatechange = function() { if (!r && (!this.readyState || this.readyState == 'complete')) { r = true; if (callback !== undefined) { callback(); } } }; document.getElementsByTagName('script')[0].appendChild(s);}
</script>
<a id="trigger" href="http://www.addthis.com/bookmark.php?v=250&amp;pub=example" class="addthis_button_compact">Share</a>
<script type="text/javascript">
var addthis_use_addressbook = true; addthis_config = { data_use_cookies: false };
var triggerElement = document.getElementById('trigger'),
addThisLoaded = false;
trigger.onclick = function () {
if (!addThisLoaded) {
loadScript("http://s7.addthis.com/js/250/addthis_widget.js#pub=example",
function() {
addThisLoaded = true;
});
}
};
</script>

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 4:51 pm on Mar 12, 2013 (gmt 0)

Now we're cooking!
After clicking it was always going straight through to the 'more sharing options' page rather than just the menu popover, which is not ideal. It seems the click both calls loadscript AND the addthis 'more options' menu for some reason.
So I changed 'trigger.onclick' to 'trigger.onmouseover' and voila, it opens (quickly at that) when mousedover (still to test on touch though).
There's just 1 last thing to sort - do you know if it's possible to change the id trigger to a class, or similar?
The reason is that there are 2 icons that trigger the lazy loading of Addthis - the orange square icon and the tell a friend feature. I can't add an id to both of them otherwise neither of them will work, and it seems overkill to duplicate the second part of the script above with another id name.

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 5:03 pm on Mar 12, 2013 (gmt 0)

do you know if it's possible to change the id trigger to a class


Yes, it's possible (though not as easy). Using an id is easy simply because the DOM provides the getElementById method, which is supported in all browsers. However, the getElementsByClassName is not supported by IE8 or below, so if you want to support those browsers, you can't rely on it, which means a more involved approach is needed to find the elements. You could write your own method for searching the DOM by classname (if you were using one of libraries like jQuery, that functionality is provided for you).

However, you could rework the above code to use multiple ID's but still not be "overkill":



var triggerElements = [
document.getElementById('trigger'),
document.getElementById('trigger2')
],
addThisLoaded = false,
i;

for (i = 0; i < triggerElements.length; i++) {
triggerElements[i].onmouseover = function () {
if (!addThisLoaded) {
loadScript("http://s7.addthis.com/js/250/addthis_widget.js#pub=example",
function() {
addThisLoaded = true;
});
}
};
}

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 5:26 pm on Mar 12, 2013 (gmt 0)

I think it's a winner - let me know how I can buy you a beer!
The behaviour in touch is a little odd - you have to tap twice to open the tell a friend email dialog box, but maybe I can add a title attribute or alert onclick to let let users know, and the orange icon menu opens another page with all sharing options, which I think is acceptable behaviour on mobile and given the other 'common' options.
On desktop it works exactly as it currently does, just hovering over and within about 500-700ms cache cleared (YMMV).
Hopefully more people will see this thread, apply to it to other widgets and cut some serious fat off our pages, especially on mobile responsive sites!

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4553579 posted 5:38 pm on Mar 12, 2013 (gmt 0)

Glad to help. :)


The behaviour in touch is a little odd - you have to tap twice to open the tell a friend email dialog box

No "onmouseover" concept for touch. :)

Perhaps you could add a listener for the "touchstart" event, and use that to load the script if they are touching one of the triggers? I don't know how responsive that would be or if it would still trigger the link before it finished loading the script, but might be something worth looking into. :)

Alex_TJ

5+ Year Member



 
Msg#: 4553579 posted 5:44 pm on Mar 12, 2013 (gmt 0)

That's a whole new event for me, time to start reading up.
Thanks again Fotiman!

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved