Overcoming long Views rendering time on Drupal sites

Published Wed, 2012/02/29 - 22:21, Updated Thu, 2012/03/01 - 12:55

A client contacted us to assist them in finding a solution for slow page times for their site.

All the pages of the site were slow, and taking 2.9 to 3.3 seconds.

Upon investigation, we found that one view was responsible for most of that time.

However, the query execution itself was fast, around 11 ms.

But, the views rendering time was obscenely high: 2,603.48 ms!

So, when editing the view, you would see this at the bottom:

Query build time        2.07 ms
Query execute time     11.32 ms
View render time    2,603.48 ms

Since this view was on each page, in a block on the side bar, it was causing all the pages of the site to be slow.

The underlying reason was really bad coding in the views-view--viewname.tpl.php, which is too long to explain. But the gist of it is that the view returned several thousands rows of taxonomy terms, and was was supposed to render them in a tree. However, the actual view template just looped through the dataset and did not do much and displayed static HTML in the end!

The solution for this was quite simple: enable Views caching.

Global Caching

If most of your visitors to the site are anonymous (i.e. not logged in to Drupal), then it is simpler and better to use global caching.

To do this, go to the view's Defaults, then Basic settings, then Caching. Change to Time Based, then select at least 1 hour for each of Query results and Rendered output.

Block Caching

If your site has a significant portion of its visitors logged in, then you can be more granular in caching, per role, per user, ...etc.

To do this, go to the view's Block menu on the left, then Block settings, then Caching.

You can select various options, such as per role, or per user, depending on the specific block.

Remember that you have to do this for each block display, if you have multiple blocks for the same view.

Now, save the view, and you will see a positive impact on performance of your pages.

What is view render time

I have the exact website installed on a cloud vps and on a development shared server. In views, whenever I click the update preview button, on the vps the Query execute time is low but the View render time is always higher than on the shared hosting server. For example:
VPS:
Query build time 2.27 ms
Query execute time 0.57 ms
View render time 352.36 ms

Shared:
Query build time 2.45 ms
Query execute time 1.11 ms
View render time 338.7 ms

Most of the time the view render time on the vps is far higher than shown above. What is view render time, and why is it taking longer on the vps? Thank you.

Insignificant

Such small difference of a few tens of milliseconds or less is insignificant. If you run the queries several times, you will get different numbers all the time.

Do not build any conclusion on such small differences.

I wonder if you could

I wonder if you could elaborate on the various block caching methods? I see several options some of which you mentioned. ( I am using Views 3 for Drupal 7).

I see:

Cache once for everything (global)
Per page
Per role
Per role per page
Per user
Per user per page

Are there advantages or disadvantages to each? Great post, thanks!

Types of cache

What you need to understand is how the block/view/page will be used and then you can choose each cache type, in preference the general as you can choose.

Global cache:
If this output is general (like an information about the site, or the owner of the site, or anything that will not change on any context, only with time or never change at all)
Per page:
You can have for example a block that shows some extra information about each page, like a exposed form or a block that shows some node information on a side, this is different on every page, but doesn't change per user, or anything else, you can use cache per page
Per role:
Let's say that you have a block that shows some information for some users depending on their role, if for example they are editors then it shows some links or info, and if they are subscribers then it shows other info, or if they are visitors something and if they are registered users something else (being the same information for all the users of the same role) then you can cache per role.
Per user:
A common example is where it shows the information of the logged in user and a login form if they are not authenticated, this is something you can cache per user.

Per role per page and Per user per page is when you show a different information on each page per each user/role.

Now, as I said, you should choose the more general as possible.
If you choose global, you end up with just one block of cached information, that is very light, per page, you will have one cached set of information for each page where that block/view shows up, so, do the math.
If you choose per role, you will have as many sets of information as roles you have (usually just a few), this tends to be good.
Per user, you will have as many as your users accessing that information, this could be good or not, depending on how many users you have accessing that.
And per user per page or per role per page, well, do the math here, multiply number of users/roles agains the number of pages where the information is shown, this should be your last option.

So analyze well the use of the information, what changes inside that information and related to what, and you will have the answer to which cache to use.

Nestor

Caching per user?

Does this work per-user? That is, I have a block that's different for each user. Does this cache the view globally? Or will it cache a different query for each user?

Thanks!

Yes, We Can ...

Yes, you can do that.

I updated the article to include a section for that.

If the .tpl file was poorly

If the .tpl file was poorly designed, wouldn't the better solution be to fix it? It seems that caching just masks the problem.

If you occur to decide on

If you occur to decide on global, you wind up having just one mass of cached facts, that is definitely very light source, per web site, you will need just one cached range of information for each and every page everywhere that block/view comes out, therefore , the actual mathematical. If you occur to decide on per role, you will need numerous sets associated with as characters you may have (usually a few), that is frequently excellent. Every user, you will need possibly your personal users accessing this information, this is excellent not really, determined by just how many users you may have accessing this. And every user per web site as well as per role every page, very well, the actual math the following, multiply volume of users/roles again how many websites where the facts is revealed, this could become your latter.

Yes, ideally

Yes, ideally, that is the ultimate solution.

But as I said, it is more complicated than that, and while a proper solution is being sought, caching is the solution.

And the article is about using caching regardless if it is good code or bad code, and watching out for rendering, not only query execution time.

Is your Drupal or WordPress site slow?
Is it suffering from server resources shortages?
Is it experiencing outages?
Contact us for Drupal and WordPress Performance Optimization and Tuning Consulting