Putting the Brakes on SharePoint with JQuery
For the better part of the last year I’ve been watching from the sidelines as nearly the entire SharePoint community jumped on the JQuery bandwagon. It seems like every year some new thing comes along which will make SharePoint sing and dance like a Broadway musical (remember 2007 – the year of AJAX?). Blog after blog has popped up with tips and tricks on how to do nearly everything with javascript, from fetching list items with web services to making pretty lightbox effects out of picture libraries. Ok, that’s cool and all, but the one question nobody seems to be asking is: will it scale?
Putting aside the obvious shortcomings of doing all sorts of programmatic gymnastics with uncompiled, loosely-typed, client-side code, let’s pause a minute to consider what impact JQuery may have on performance. There’s nothing magic about JQuery itself; much like LINQ, it simply provides less-obtrusive language semantics in order to make common tasks more efficient. If you look into the source script you’ll see that it’s mostly a bunch of arrays being populated with getElementById calls and regular expression searches – not exactly rocket science.
In most of the examples I have seen, JQuery is being used to modify the user interface by changing elements of the document object model (DOM) after it has been sent down to the client by the server. The average SharePoint page has more than 1,000 elements in the DOM right off the bat before adding any web parts or publishing field content; add to that some of the really funky code that the OOTB web parts produce, along with a list view or two, and you can easily end up with pages that have thousands of DOM elements. That’s a lot of stuff to process in client-side code. All that iterative selecting, searching and modifying that JQuery does in the background to manipulate these elements takes time – the bigger the page, the more work has to be done before the final content is rendered in the browser. Considering that SharePoint pages aren’t exactly optimized for performance right out of the box, and how much time and effort is spent trying to shave a few seconds off of average page load times, is it really a good idea to start mucking around with the DOM just to produce some fancy visual effects?
I remember having a conversation over dinner at DevLink last August with Dennis Bottjer. Dennis was convinced that JQuery was the answer to many a developer’s frustrations with the SharePoint UI and customizations in general. I conceded that he was probably right, it would catch on and spread like wildfire, but I was concerned that overuse would lead to performance problems. We went back and forth about it for a while then let the matter drop but the more I see it being used (you were right on that score, Dennis) the more I am troubled by its impact on high-volume sites, especially enterprise portals and public-facing web sites, and the lack of any substantive performance discussion in the greater community.
In order to validate my theory that even simple JQuery functions can put a damper on SharePoint performance (or, should the results prove positive, at least put my mind at ease), I set up a very simple test scenario. I created a web part page in a WSS site in SharePoint 2007 then added an out-of-the-box list view web part to the page which rendered a view of the first 500 items in a custom list. I then copied the JQuery scripts to a subfolder in the /_layouts directory and added a <script> link in the <head> tag of the master page. Finally, I added a content editor web part with a JQuery function that changed the background color of every other item in the list view to yellow, like so:
$(".ms-alternating").css("background-color","yellow");
I then fired up SharePoint Performance Manager to assess the render time of the page both with and without the JQuery CEWP. An empty CEWP had an average execution time of around four seconds (which is scary in and of itself – I need to look into it further and figure out why that particular web part is so slow even with no content); adding the function to change the row styling increased the execution time by about a second. I flipped it on and off twenty times using ten sample page loads for each configuration and the results were relatively consistent – in my test environment the JQuery took about a second on average to do its work. The overall effect on page render time was rather less due to multithreading, working out to about a third of a second. Ok, that confirmed my basic theory but there were no real surprises and a third of a second doesn’t stop the world from spinning (although, to be fair, many dotcoms have spent millions of dollars in infrastructure for the sole purpose of reducing load times by a fraction of a second).
The next step was to set up a series of load tests to ascertain the impact of the JQuery operations when multiple simultaneous requests were involved. I configured a single-page web test in Visual Studio Team Test and dropped it into a load simulation of 100 concurrent users over a three minute period. This is when things got a bit more interesting. Overall page load time without the JQuery code went up from around six seconds to about eleven seconds (an 80% increase, which is to be expected on a single virtual machine with only 4GB of allocated RAM) but when I added the JQuery function to the CEWP it shot up to thirteen seconds – not at all what I was expecting. I ran the tests a dozen more times with similar results. While the base page load time increased by 80% the JQuery impact on page load went from a third of a second to two whole seconds – a 600% increase! That’s more than statistically significant – that’s downright worrisome.
So what gives? Admittedly, my test environment isn’t anywhere close to "real world" – your mileage may vary depending upon the server and network infrastructure, client connection, amount of concurrent requests, and, of course, the exact nature of the JQuery methods being executed. But the results were pretty clear – under load the javascript performance was less than stellar. I would be very concerned about this type of code in a high-traffic environment; in fact, I would almost certainly call this out in a performance assessment as a critical blocking factor.
The takeaway here is to be very careful what kind of JQuery operations you are performing on your SharePoint pages. In most real-world scenarios I doubt whatever client-side functions are being performed would have a drastic impact on performance – typical enterprise portals just don’t get that much simultaneous load. That being said, I would steer clear of JQuery in most high-traffic situations, especially home pages for popular WSS sites, shared application pages (like viewlsts.aspx) and any public-facing MOSS publishing pages. I’m especially troubled by JQuery inside of content editor web parts, as the CEWP by itself appears to be rather burdensome even without additional scripts, and would much prefer to embed the scripts directly (either in the master page or as a custom control) if I absolutely had to implement some fancy DOM-manipulation scripts.
Don’t get me wrong – JQuery has a lot of benefits, not the least of which is the ability to write complex query logic with relatively little code; however, its use in performance-sensitive environments could be more trouble than it’s worth. As with all things SharePoint, there’s more than one way to skin the cat and other methods may achieve the same results while introducing less overhead. Use it if you must but test, test, test before going into production or you may get a nasty surprise when that fancy new MOSS portal goes live.
UPDATE
As expected, this topic has generated some discussions in the community, which is exactly what we need. Here are some links to related posts:
Marc Anderson – Putting the Brakes on SharePoint with JQuery – or not
Dennis Bottjer – Stop, Think, Dev SharePoint
Eric Shupps – Follow-Up on JQuery and SharePoint Performance
UPDATE 2
Many people have rightly pointed out that my load tests were not real world (whcih I did mention in the post) and not really applicable to client-side script processing. That’s caused a lot of confusion and is fair criticism. I was going for the impact that the CEWP’s and List Views had on each other under load and got distracted by the strange results I was getting from the CEWP’s – I should have separated the two discussions. To that point, I have discovered some interesting things about how the CEWP’s work and will be posting on it in the future as soon as I have a chance to compare them with the 2010 version. See my second post (linked above) for more discussion of render time performance as opposed to load time.
So often people don’t think about larger architectural issues when touting customizations. Thanks for having this discussion since performance & scalability are always on my mind. At least I’m not the only one and I appreciate your testing.
So often people don’t think about larger architectural issues when touting customizations. Thanks for having this discussion since performance & scalability are always on my mind. At least I’m not the only one and I appreciate your testing.
Avoid using jQuery in public-facing MOSS publishing pages? I disagree with that advice. Do you have any idea how many high-profile public-facing web sites use jQuery?
Also, I don’t really see how the results of your load tests actually represent a real-word problem. Why are you performing 100 simultaneous requests when you are testing performance of a client-side solution?
If I missed your point, please do let me know 🙂
Hey Eric!
Do you think this is something you’re going to look into any further? Reading your write-up has really piqued my curiosity.
Personally, I’m less concerned about client-side performance effects than I am about true scalability and the impact that out-of-band JQuery calls might have on the back-end systems. I work on the type of high-volume, publicly-facing Internet sites you mentioned; if JQuery adds some overhead on the client-side, I’m not going to be too concerned. If those calls or their semantic peculiarities adversely affect server performance, I’m going to take notice.
Reading through your post made me wonder:
1. Was BLOB caching for .js enabled?
2. If the answer to #1 is “no,” what effect is observed if it is?
3. How would the timeline for the calls look under something like VRTA or Fiddler?
… and of course …
4. What’s up with the CEWP baseline processing time?
At the end of the day, I wouldn’t expect JQuery and its calling semantics to be any different on back-end system scalability than other AJAX-style calls. I just haven’t done any work to confirm that hypothesis.
Do you think you’ll be digging any deeper?
No, you didn’t miss the point at all. What I’m really focusing on is JQuery and SharePoint. A lot of this has more to do with SharePoint than with the other technologies being employed. Most public web sites don’t have all the fat on them that MOSS does; my main point is if you’re gonna use JQuery with MOSS then test the heck out of it and make sure it’s not adding additional weight to an already weighty framework. You’d be amazed how many big sites I run across that have done very little to optimize SharePoint’s bloat then complain about performance. Just another thing to be careful about, that’s all.
No, you didn’t miss the point at all. What I’m really focusing on is JQuery and SharePoint. A lot of this has more to do with SharePoint than with the other technologies being employed. Most public web sites don’t have all the fat on them that MOSS does; my main point is if you’re gonna use JQuery with MOSS then test the heck out of it and make sure it’s not adding additional weight to an already weighty framework. You’d be amazed how many big sites I run across that have done very little to optimize SharePoint’s bloat then complain about performance. Just another thing to be careful about, that’s all.
Sean,
Yes, BLOB caching was on and IIS compression was set to 7, although neither has much effect on actual processing of the javascript functions. Interestingly, I saw some strange effects when switching from the uncompressed JQuery library to the .min version of the library but they were very inconsistent. I didn’t call them out as I really need a more scalable lab environment to delve into them.
As for Fiddler, the raw page delivery should be about the same as the visual studio tests but the problem is that those tools can’t analyze the web parts individually (which is why we wrote Sonar/Performance Manager in the first place). I did verify with Fiddler that the JQuery script was getting properly compressed and that the .min version was the correct size but I didn’t use that tool for any baselining.
I am going to look into this more in 2010 to ascertain the effects of HTTP throttling and some of the new list view optimizations. As for the CEWP, I have no idea what’s going on with that web part. There’s no reason for it to require that much time to render. I’m hoping that they’ve optimized this in 2010 but it’s too soon to do any real performance testing in the Beta version – we’ll have to wait for RTM to analyze it further.
Sean,
Yes, BLOB caching was on and IIS compression was set to 7, although neither has much effect on actual processing of the javascript functions. Interestingly, I saw some strange effects when switching from the uncompressed JQuery library to the .min version of the library but they were very inconsistent. I didn’t call them out as I really need a more scalable lab environment to delve into them.
As for Fiddler, the raw page delivery should be about the same as the visual studio tests but the problem is that those tools can’t analyze the web parts individually (which is why we wrote Sonar/Performance Manager in the first place). I did verify with Fiddler that the JQuery script was getting properly compressed and that the .min version was the correct size but I didn’t use that tool for any baselining.
I am going to look into this more in 2010 to ascertain the effects of HTTP throttling and some of the new list view optimizations. As for the CEWP, I have no idea what’s going on with that web part. There’s no reason for it to require that much time to render. I’m hoping that they’ve optimized this in 2010 but it’s too soon to do any real performance testing in the Beta version – we’ll have to wait for RTM to analyze it further.
Eric,
Great Post. This is an important conversation to have. I posted some additional thoughts and this time I wasn’t eating dinner. 🙂
http://www.drowningintechnicaldebt.com/DennisBottjer/archive/2009/12/22/perhaps-ndash-stop-think-dev-sharepoint.aspx
Eric,
Great Post. This is an important conversation to have. I posted some additional thoughts and this time I wasn’t eating dinner. 🙂
http://www.drowningintechnicaldebt.com/DennisBottjer/archive/2009/12/22/perhaps-ndash-stop-think-dev-sharepoint.aspx
Did you look at perhaps using Google’s CDN to deliver the jQuery files? This could vastly improve performance for externally facing sites.
Whilst I agree that poorly written and thought about jQuery code could really damage performance on the client side, it’s a damn site less dangerous than poorly written server side code! Either way it’s still crappy code!
Client side code should not impact scalability unless you are loading code from the server via web-services. However you would be loading this data regardless and as long as you are not loading redundant data you should see a performance boost.
Using jQuery to add css markup may appears a bit pointless but this does actually reduce the HTML file size you are sending down the line, so could reduce download latency which is always going to be the biggest bottleneck.
It’s always wise to remind people that you have to use technology appropriately – but jQuery can bring a lot to the table and should not just be discounted. I think the one thing you do show is that you should always perform (as close to) real world performance testing as you may be surprised by what it throws up!
Did you look at perhaps using Google’s CDN to deliver the jQuery files? This could vastly improve performance for externally facing sites.
Whilst I agree that poorly written and thought about jQuery code could really damage performance on the client side, it’s a damn site less dangerous than poorly written server side code! Either way it’s still crappy code!
Client side code should not impact scalability unless you are loading code from the server via web-services. However you would be loading this data regardless and as long as you are not loading redundant data you should see a performance boost.
Using jQuery to add css markup may appears a bit pointless but this does actually reduce the HTML file size you are sending down the line, so could reduce download latency which is always going to be the biggest bottleneck.
It’s always wise to remind people that you have to use technology appropriately – but jQuery can bring a lot to the table and should not just be discounted. I think the one thing you do show is that you should always perform (as close to) real world performance testing as you may be surprised by what it throws up!
Eric, could you further explain what you mean by the following?
“I would steer clear of JQuery in most high-traffic situations, especially home pages for popular WSS sites, shared application pages (like viewlsts.aspx) and any public-facing MOSS publishing pages.”
Are you really saying that ANY jQuery script is bad in a high-traffic (SharePoint) situation?
Jaap
Well browsers are also undergoing changes. JavaScript engines are becoming much much more efficient, and CPUs running these browsers are also becoming much more powerful. I don’t see an issue with performance scaling. Though such fragmented code especially in JavaScript becomes unmaintainable
really quick, and can be quite error prone. If anything, your developers can’t scale 🙂
S
Jaap,
Nope. I’m saying be careful anytime you introduce code that manipulates SharePoint pages. That includes server-side code as well, not just JQuery, although that was the topic of the post. When performance is paramount you have to make decisions that my not seem as important in smaller environments. As Aaron pointed out – and he’s right – the markup SharePoint generates is bad enough; be careful not to make it any worse.
Good points Eric, although i’m concerned about you raising issues with “load”. I would agree with what others pointed out around the page weight increasing with jQuery and that content delivery should be used to mitigate this.
If you are testing client side code, load isn’t going to be affected unless the client side code is calling back to the server such as to web services. I have seen issues here where a server side call would be more efficient.
I would agree that performance on the client side with lots of jQuery dotted around can impact the user experience especially in older browsers.
I wrote a post a while back on this too called “jQuery the SharePoint band-aid”:
http://wss.made4the.net/archive/2009/02/23/jquery-the-sharepoint-band-aid.aspx
I’ve also recently just interviewed SharePoint jQuery CodePlex library guys Marc Anderson and Will Lawrence here that is relevant:
http://www.sharepointdevwiki.com/display/SPPodCasts/Home
Have a great Christmas mate 😉
Eric, I can spot a couple mistakes in your post. A major one in my opinion is that you are sticking to unit testing (single page load), and missing the big picture.
Try thinking use case instead. Imagine for example a user getting a list of items that he/she needs to slice and dice. Do it server side through standard SharePoint tools (list views, column filters), then through client side code.
Christophe
Eric, I can spot a couple mistakes in your post. A major one in my opinion is that you are sticking to unit testing (single page load), and missing the big picture.
Try thinking use case instead. Imagine for example a user getting a list of items that he/she needs to slice and dice. Do it server side through standard SharePoint tools (list views, column filters), then through client side code.
Christophe
You rightly say that anything that is overused can lead to performance degrade. But you are wrong about jQuery slowing down the Sharepoint Site. I have used jQuery not only in SharePoint but also major .NET applications and found that it had a profound impact on improving performance. ASP.NET controls just do not provide the facility for power packed performance for large amounts of data. jQuery adds to that and also provides a clean and fast way of accessing dom elements. Of course, if you write inefficient code, it will make things slower.
You rightly say that anything that is overused can lead to performance degrade. But you are wrong about jQuery slowing down the Sharepoint Site. I have used jQuery not only in SharePoint but also major .NET applications and found that it had a profound impact on improving performance. ASP.NET controls just do not provide the facility for power packed performance for large amounts of data. jQuery adds to that and also provides a clean and fast way of accessing dom elements. Of course, if you write inefficient code, it will make things slower.
hi
i am compare one custom column with current time
give me any code and forward to my mail id:
remoyen@gmail.com
jQuery is the best thing to happen to the web and SharePoint both.
Dynamic, browser abstraction, loosely coupled, separation of concerns, client-side interactivity : this reads like a list of why to use jQuery, not a reason to worry about it.
Design, architecture, performance – yes, think of them all, but definitely have jQuery in the tool bag.
My guess is that it will be included OOTB in the next version of SharePoint, as it is in ASP.NET