One of my recent clients insisted that his shopping cart be created in WordPress and WP e-commerce. He made this decision because he wanted the software to be free, and that is one of the strengths that the Free/Open Source Software (FOSS) community has been leveraging for a long while. I even agree with some parts of the philosophy.
Unfortunately several of his products are highly customizable. When I say “highly,” I mean that there are over 2200 possible variations for at least two of his products. That is easy to understand when you start to talk about Color Choices x Length x Logos x &c. There are 10 variation categories. WP e-commerce wants to create a separate product item and title for each one of these so that you can clearly distinguish between what was purchased.
The endeavor is noble. I like to see exactly what the customer purchased. But WHY do we have to generate 2200+ unique titles when we save a product? And worse, WHY do we have to keep all of these possible modifications in server memory at the same time? Even worse, WHY do we have to see all 2200+ product titles the next time we try to edit the product? On the same page? The plain listing is more than 5 MB of HTML.
In a world where 8 GB of memory is becoming common, that may not sound like much but the parsed HTML is larger than what gets sent over the wire and browsers keep that data in memory for the sake of your “Back” button. There are also people who access their websites over cell phone networks or other mediums that charge by bandwidth usage. My client said that this “locked up” his computer—which probably just means that it was brought to a crawl. 5 MB can take a while to download and parse, especially on older hardware.
I modified WP e-commerce to generate these titles “as needed” instead of during product creation, and to not show the product modifier titles while editing the product (seriously, who is going to customize 2200+ titles for a single product?). That was when I noticed the next issue. After we configure the variations, you can view the product within the shopping cart. There are dropdowns for you to use in selecting your product modifiers, and then an AJAX request is fired off to ask how much the product is with those modifiers. I was getting errors like this from the AJAX query:
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 72 bytes) in ...
We exceeded 64 MB of memory in a price lookup? I mean, this is WordPress but 64 MB? It did not look like the code was dying near anything that I had modified, so I verified that it was not my fault with a Google search. Sure enough, this appears to be a common problem. And here I thought my custom shopping cart software was using a lot of memory at 6 MB per page load, or that a commercial solution was bad at 15 MB. I had to up the WordPress memory limit to a 128 MB cap per page load.
Despite my actions, one of the long-time users asked about this so non-nonchalantly that I am still shaking my head:
Hmmm why not just up the PHP memory limit?
We should not have to. That is a lot of server memory to expend on an AJAX request which happens every time an end user clicks on a dropdown.
I offered to patch some of these issues so that my client could upgrade his software without fear of losing our ‘customizations,’ my forum post was deleted. Maybe I have to purchase “Premium Support” to contribute a fix? Sometimes “free” is not always better.
UPDATE: After rewriting their product modifier code, the administrative product listing page was still maxing out its execution time on a semi-regular basis. It turns out that WP e-commerce loads all of the product’s variations (some have 2200+!) for each and every column in the table. There are 10 columns, multiplied by the default pagination of 20 products. On this site alone, that opens the possibility of WordPress processing over 440,000 table rows through filters and whatnot on a single page load. Of course this total depends on the exact products that appear on the page, but the right search terms will work wonders for killing server CPU.