So I've got a site speed conundrum for you...

Joined
Dec 5, 2014
Messages
107
Likes
108
Degree
1
Check this out:

http://puu.sh/g5qIP/840e324a72.png

(Especially note the time discrepancies between the load-time graph and the hover box)

I know, right? Open that page up in Chrome and you'll see that Pingdom isn't lying. If you've got some extra time, try messing around with the "Concentricity" tool in Chrome and you'll see the animation is choppy and all around unpleasant.

Now here's the weird thing...

Try opening up that same page in Firefox or IE, and voila, everything's snappy as can be...

Haven't tested it on Safari or other Webkit browsers (IIRC Chrome is a Webkit browser but maybe I'm making a fool of myself) so I don't know if it's a Chrome issue or a Webkit issue, but I've never encountered anything like this before.

What's more, I can't for the life of me explain the choppiness of the animations within "Concentricity." It's written in jQuery and is set on a 10ms iteration, but performs much more slowly in Chrome. Once the browser has the necessary JS files, there is absolutely no server communication going on within the execution of the animation, right? Am I crazy?

And before anyone points out the obvious, I know I'm loading jQuery multiple times. I just put this up a few days ago and only made the necessary changes to twentytwelve to get that perfect performance grade. Manual minification will come in due time.

Now, the only thing I could think of is that I'm running this on a shared HostGator server (I know, HostGator's terrible but I'm a cheap fuck and you can't beat unlimited Add-On domains for $9/month... or maybe you can, in which case please enlighten me!) and it is possible that I'm sharing a machine that has been flagged by Google as harmful or compromised or something along those lines, hence the speed throttling in Chrome. However, this is all assumption and I don't even know if this is a real possibility. I just can't wrap my head around this.

I know there are probably better sites to post this on, but I really admire a lot of the people on BuSo and I figured with all the recent interest in site speed this would be an interesting problem for some of them to take a look at.

Thanks in advance for any help and advice!
 
It's not a loading problem, it's a programming problem. I suspect it's your javascript cause a quick glance found this on lines 201 and line 202 of your concentricity.js file:

Code:
$(document).ready(function() {
    $(window).load(function() {

you have both...

I suspect there may be other problems if something like this was overlooked. (hint: remove the 'window' one)
 
Man, you are exactly the person I hoped would see this but I have no idea where you find the time...

Now I was under the impression that all functions should be initiated by a $(document).ready() call, which then goes on to fire the other functions. You might have noticed I have a function in there called perfectCircle() that sets the height of the divs equal to their width to get that concentric circle effect. Without it, I end up with something that looks like an oblong mess rather than perfect circles. I have that firing within the $(window).load() because I assumed the CSS needed to apply width: 100% before running that perfectCircle() function. Is CSS included in checking for $(document).ready()?

I've used $(document).ready() to make calls to $(window) functions before without running into this issue, but usually through a standalone function, ie $(document).ready(primaryStartup) rather than $(document).ready(function(){...}), could this be the issue?

I'm going to test your solution and try and answer these questions on my own, but hopefully outlining this train-of-thought helps me save face a little bit if the problem turns out to be something so simple :smile:

Thanks for taking the time!
 
I dunno man, I just know the problem isn't site speed. There are more problems to be honest. You've got functions within functions. applyColorsOut, ApplyColorsIn, colorLighten, and colorDarken are All within the applyColors. That's just not how I would implement it, maybe this works in javascript but I dunno my gut tells me that's causing loops - but I could be completely off, I'm not in my coding mode.
 
Just tested your solution but had no luck :(

I verified that Chrome wasn't using a cached version of concentricity.js, and tried it with using only $(document).ready() and $(window).load(), and neither provided any noticeable improvement.

I did verify that CSS styles had been properly applied by the time $(document).ready() fired, so that's good to know. Still, after some reading I also verified that it's acceptable practice to use $(window).load() inside $(document).ready(), and as I've said before I have used this combination in the past when I needed functions to fire when the DOM loads but then had others that needed to wait for images to render before firing, so I don't think this is the issue.

Also, if this were the case I feel as though I would see some issues on alternate browsers. That's the weirdest thing in all of this, as far as I can tell it is a Chrome specific issue. I mean, one of jQuery's big selling points is cross-browser compatibility, right?

Could it be an issue with the Chrome-specific Javascript jQuery links to when using these handlers?
 
No problem, it's my issue not yours and I'm grateful for you taking the time to help. I'm just confused...

As for the functions within functions, their scope only needs to apply within the applyColors() function and I know I've read about using functions within functions to create the illusion of function privacy, which I believe can't be explicitly set in JS. I don't know if I'm explaining that correctly because I read it a while ago, but I know they talk about functions within functions in "Learning Javascript Design Patterns".

It's worth a shot though, I'll give it a try.

Thanks again.
 
Also, I would take out one of the jqueries first... that might be causing all sorts of mix ups as well. It's better to start on a solid foundation to element any potential misfirings of code cause of conflicts.
 
Done with this for tonight.

Makes sense about the multiple jQuery loads, but sadly didn't solve the issue,

Tested with and without nested functions, with and without setTimeout(), tested alternate themes, tested from different devices, restructured the code to make all initial variable declarations at the start of each function, nothing seems to make a difference.

End results:
concentricity.js
http://puu.sh/g5UCW/d2362d79b8.png

no concentricity.js
http://puu.sh/g5UKI/df1e223575.png

So obviously there is something going on with concentricity.js, but even still I've gotten sites twenty times this size to load in under 800ms on a shared HostGator server. And it still doesn't explain the perfect load times on other browsers after a full cache clear.

Tomorrow I'm going to migrate it to another server I have access to to see if it makes a difference. I'd really love to know that I'm not such a terrible programmer that I can unintentionally tank a site in under 9kb...

I picked a bad month to stop smoking!
 
The server would not be my guess. You're pulling down just a few very small files and they are executed on the client side. This is something that even poor quality servers can easily manage. So, the thing here is, you have this code executing on the client side, and being that you don't see this problem (and neither did I when I took a quick look) with Firefox but with browsers that use Webkit, this highly suggests a code issue and a client-side problem as @CCarter pointed out, because you're dealing with a different JS engine and events/callbacks are handled a bit differently.

Listening to $(window).load within $(document).ready is ok. You're basically saying "Wait till after the DOM and all resources are loaded, then fire whatever. It's the "whatever" I'm worried about. My thinking is there's some weird stuff happening that's causing client side processing/rendering slowness.

To summarize, you have the resources loading and you've already hooked into $(document).ready and $(window).load to state that you want to wait till all is said and done, then go ahead and fire your callbacks. During the callbacks, something is happening on the client side that is causing whatever issue you're having.

I would take a look at the following
  • Are you deferring the js (i.e. asynchronous loading)? Try not doing that just to see if anything changes.
  • Are you using other plugins that are hooking into $(document).ready and the like? Also take a look to see if there's any reference to document.onreadystatechange and listening for document.readyState == "complete" .
  • You might want to consider firing any post DOM rendering events a bit late, via an interval.
I'm putting my money on client-side code, not server-side. Hope this helps.
 
You know what @SmokeTree , there is another file further down the page, that is firing a jquery function as well, that might be causing the conflict. Maybe moving the js file until after that navigation.js file executes might solve all your problems, cause it was using the jquery.ready stuff as well. (This is going off of memory)
 
@CCarter I think you nailed it man, good call. This caused me to take a more in depth look, and I think the problem might be here. This is calling perfectCircle() and the resulting rendering every time the browser page resizes.:

Code:
$(window).resize(function() {
    perfectCircle();
});

Try taking that out and see what happens. This could be that webkit is having to go through perfectCircle() a lot of times because $(window).resize is firing more than once. Just a thought but I think we're on the right track.
 
T5gmr4h.gif
 
I'm also wondering if perfectCircle() is causing the window.resize to fire, setting up some kind of loop condition. Just speculating here. Should definitely be enough to track it down.

<3
 
Last edited by a moderator:
Awesome ideas, I'll get right on some new tests to see if anything here solves the issue.
 
An update:

Still not solved, but I think we're getting closer.

Completely removed the $(window).resize call, but I'm still running into WebKit rendering issues.

Restructured the code to put all JS scripts just before </body>, in the order jQuery -> Navigation -> Concentricity. No luck. I also switched out my server copy of jQuery for the Google hosted library to make that a constant of sorts.

So then I started gutting concentricity.js. Here's our starting point, perfectCircle() is called once initially, but no longer called on $(window).resize:

(I do understand that this is a client-side issue, not a server-side issue, I'm simply using these speed tests to illustrate the time it takes to fully render all elements on the page)

http://puu.sh/g6xg6/bc5f157c26.png

So then, I removed the perfectCircle() call altogether, and here's the result:

http://puu.sh/g6xbr/a548214a58.png

A huge improvement, but still not solving the rendering issue. perfectCircle() iterates over the twenty concentric circle divs to set each one's height equal to it's width, like so:

Code:
function perfectCircle() {

	$('.circle-holder').each(function() {

		$(this).css('height', $(this).innerWidth());

	});

}

Correct me if I'm wrong, but I believe this means that the rendering isn't getting any faster, the browser just has 20 less rendering jobs to complete, resulting in that load time decrease.

So then I removed concentricity.js altogether, and here's the result:

http://puu.sh/g6wHP/68900ba0be.png

So based on this, I don't think concentricity.js is the cause of the rendering issue, as I still run into rendering issues in Chrome with things like the "responsive" aspects of TwentyTwelve, which are driven purely by CSS media queries.

So here's the result after removing all JS files. I also checked the page source to make sure no inline JS was being added. The only script in the source was the IE shim, which was commented out because I was using Chrome:

http://puu.sh/g6z1N/dda5e94653.png

In visiting the site, the CSS rendering issues remain. After resizing the window, it takes several seconds to apply the CSS media queries and resize percentage-based width elements and apply/remove floating from the sidebar.

Here are the only customizations I've made to my version of TwentyTwelve:

Functions.php
Code:
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );

function remove_open_sans() {
   wp_dequeue_style( 'twentytwelve-fonts' );
}

add_action('wp_print_styles','remove_open_sans');

function no_more_jquery(){
    wp_deregister_script('jquery');
}

add_action('wp_enqueue_scripts', 'no_more_jquery');

Style.css
Code:
.circle-holder {
	width: 100%;
	padding: 5%;
	box-sizing: border-box;
	border-radius: 100%;
	background: #ddd;
	text-align: center;
}

I also added the three scripts (jQuery -> Navigation -> Concentricity) just before </body>, but these aren't present in the no JS version that still has issues with rendering.

Please let me know if I misunderstood any of the issues you addressed above, as I'm happy to go back and retest anything previously mentioned. I've re-included the three JS files (with the initial perfectCircle() call) in the live version of the site if anyone else wants to visit http://morg.rocks to take a look.

Turns out Morg does not rock so much!

And thanks again for taking the time and effort to look at this, I really do appreciate it. Hope everyone has a good Saturday!
 
Hmm, this really IS kinda odd, but I've seen problems with CSS rendering across different browsers that can be pretty significant. For one, I know that "border-radius" is a particularly "expensive" CSS property in webkit and that might be part of it, or even most of it. Maybe try going through the CSS bit by bit and commenting out anything that requires the browser to do extra work to render, starting with the "border-radius".
 
No luck. After dinner I think I'm gonna do a full WP reinstall because more and more it looks like this issue runs deeper than just my additions. I noticed this morning that my admin bar "customize" link 404s, so I'm praying it's something as simple as a minor timeout or something during the initial quick-install.
 
...or at least that was the plan, until SOMEBODY got me reading old Fravia and Company essays late into the night.

But got cracking again early this morning and, happy to report, solved:

Turns out WebKit has a hell of a time rendering percentage-based padding for twenty nested html elements. A quick conversion to pixels got everything rendering much faster.

Still have some stuff to test (adding back in setTimeout(), etc) but I think this is all stuff I'll be able to handle on my own.

@SmokeTree What you suggested about firing post-DOM rendering functions late through an interval, would that have an effect on reducing site speed? Sort of like tricking Pingdom/Google into thinking the page has finished loading before all the rendering is actually completed? This is just a personal site that I have no interest in ranking or anything like that, you just got me thinking...

Anyway, thanks for working through this with me, back to lurking...
 
What you suggested about firing post-DOM rendering functions late through an interval, would that have an effect on reducing site speed?

It can have an effect on perceived load speed. I'll explain what happens. When you use setTimeout(), you're saying "yield the thread to the browser for the interval specified", which basically tells the browser to continue to do what it was doing (i.e. rendering) then pass back to JavaScript when the interval is up. Being that JavaScript is single threaded, setTimeout() is not going to tell the browser to spin up a new thread, it's just going to pass control between browser and JS.

A trick sometimes used, is to set up a series of chained functions with setTimeout() intervals of 0. Basically what happens is the interval of 0 will first yield the thread to the browser then back to the JS function being called. So if you need to run a series of functions and you don't want to block rendering the whole time, you can use setTimeout() with the interval at 0 in between the function calls to pass control back and forth.

As to whether it's going to have a significant effect with Pingdom/Google, honestly that could depend on a lot of things, such as how far the parsers on said sites are going to call a page "loaded". Try a few tests and compare results. The rabbit hole of performance optimization can go as deep as you like, there's always something to improve.

Glad you got the rendering thing straight with the site and webkit. Also glad you spent a bit of time reading through some of those old essays from +Fravia, +ORC and crew :smile:
 
Back