News:

Support the VirtueMart project and become a member

Main Menu

Site too slow

Started by iMilazzo, October 23, 2012, 20:06:21 PM

Previous topic - Next topic

jt2012

Slow page loading times are caused by extremely poorly designed code which is running way too many MySQL queries. This slowness is further compounded by the code returning an unnecessarily huge amount of JavaScript code to the client (eg. on my site, the "html" file returned by PHP is 800kB). What's worse is that this JS code appears to have no real purpose on the page it's being produced for.

This problem affects the category pages - the pages before getting to specific product detail. It is especially a problem for us because we have thousands of products and it seems to be trying to create a product "family tree".

Of course, this isn't necessarily the cause of all cases of slowness.

jt2012

For those of you still having trouble with the slowness of your VirtueMart cart, and for those
of you brave enough to venture into the abyss of VirtueMart code...here's the fix I made
for the site I'm working on. This *may* work for you depending on what version you have
and what plugins you have.

Before you begin, you should know that the main cause of slowness described in this thread
IS caused by poorly written code making far too many DB queries. It is VERY bad practice to be
doing this, even on a fast server. The solution is to stop the onslaught of queries by disabling
specific code when it is called by the category page. Doing so will also cut down on the amount
of useless JS code that is returned.

First, find this file: /administrator/components/com_virtuemart/models/product.php
(or something similar as the equivalent may have been spewed some place else in a different
version). Now you need to find line 856 (or somewhere in the general vicinity) where the
rampant code is this:

// set the custom variants
if (!empty($product->virtuemart_customfield_id)) {
$customfields = VmModel::getModel ('Customfields');
// Load the custom product fields
$product->customfields = $customfields->getProductCustomsField ($product);
$product->customfieldsRelatedCategories = $customfields->getProductCustomsFieldRelatedCategories ($product);
$product->customfieldsRelatedProducts = $customfields->getProductCustomsFieldRelatedProducts ($product);
//  custom product fields for add to cart
$product->customfieldsCart = $customfields->getProductCustomsFieldCart ($product);
$child = $this->getProductChilds ($this->_id);
$product->customsChilds = $customfields->getProductCustomsChilds ($child, $this->_id);
}


Subdue it by changing it to this:

// set the custom variants
if (!empty($product->virtuemart_customfield_id)) {
if (class_exists("VirtuemartViewCategory") != true) {
$customfields = VmModel::getModel ('Customfields');
// Load the custom product fields
$product->customfields = $customfields->getProductCustomsField ($product);
$product->customfieldsRelatedCategories = $customfields->getProductCustomsFieldRelatedCategories ($product);
$product->customfieldsRelatedProducts = $customfields->getProductCustomsFieldRelatedProducts ($product);
//  custom product fields for add to cart
$product->customfieldsCart = $customfields->getProductCustomsFieldCart ($product);
$child = $this->getProductChilds ($this->_id);
$product->customsChilds = $customfields->getProductCustomsChilds ($child, $this->_id);
}
}


That code is adding an if statement (essentially saying "if it's the category page being
executed, then don't bother running this code") around the code that ultimately causes
all of the unnecessary DB queries and JS code.

Notice that this mod still allows the code to be run for the product detail pages, which is
where the queries and JS code are actually useful. This code is decent on the product detail
page because it only runs queries relative to one particular product, instead of for each and
every product listed in the category page.

After you've made the mod, make sure you thoroughly test your site, because there's no
telling for certain how widespread the effects of this mod might be in your version/settings
unless you test it.

Also, don't be surprised when an update totally wipes your mod by replacing it with the
good ol' poorly written code.

bytelord

Hello,

Nice suggestion, but some people works with custom fields on the category view also (some advanced template edits).
If you take a look on the current product model (vm2.0.14) you will see that this area so been working and will be moved on the view model for product details page (custom fields for related products/categories).

Thanks for the code snippet.

Regards
Production: Joomla 2.5.8 | VM 2.0.14 | PHP 5.3.13
Testing     : Joomla 2.5.8 | VM 2.0.16 | PHP 5.3.8
Testing     : Joomla 2.5.8 |    VM 2.1   | PHP 5.3.8

- Don't Forget to mark thread as solved when it is solved!
- Please do not PM with support questions, use the forum!

jjk

Quote from: jt2012 on November 12, 2012, 18:22:14 PM
Slow page loading times are caused by extremely poorly designed code which is running way too many MySQL queries. This slowness is further compounded by the code returning an unnecessarily huge amount of JavaScript code to the client (eg. on my site, the "html" file returned by PHP is 800kB).

Well, my live site probably has less products than yours, but when I read the description of your speed problem, I doubt the number of MySQL queries is the problem on your site (how much time did you gain with your code?), because even though there are many, they are running very fast. On my site I have up to 600 queries for a category view, but still the site is very fast, even on the cheap 4.5 dollar per month shared server the site is hosted on. Also, if I look at my site with 'Firebug' enabled, the html part is only between 4 and 6 kb.

Which versions of Joomla and VM2 are you using - and can you provide a link where we can see your speed problem?
Non-English Shops: Are your language files up to date?
http://virtuemart.net/community/translations

franzpeter

It is true. Using Joomla menu for linking to VM categories slows down the page. Using VM landing page as start page slows down too. And if the VM landing page is used to display random, featured or newest products, that slows even much more the whole page. Joomla menu is normally not slow, but it is obvious that the VM component produces some problems by just get linked to Joomla menu (without displaying pages), just because it is inside a Joomla menu with variious instances. So it is a VM problem.
The VM landing page uses a huge query to get main categories and all products and then it filters out the needed products for example (featured, newest, random) with case statements. Maybe it would be better to not use case statements and instead use different queries to filter the products.
Example: featured products have an additional entry in the database table (0 or 1). It is much faster to use a query to find those products with '1' or with the newest date, than to query the whole product table and filtering by case. Both methods work and the code with the case statements looks more elegant, but it is much slower.

Milbo

One big trouble, that the customfields are always loaded is removed in vm2.1

That vm is slower due menu items is imho due the sef. We added statics to the router, so we reduced the sql drastically. The version 2.0.14 is already a lot faster then 2.0.12
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/