5 Most Common Magento Coding Issues to Optimize your site performance

Topics focus on Web Developments, Programming, Database, Digital Marketing Tutorials, Code Snippets, SEO, Social Media Marketing and Inspirational articles.

5 Most Common Magento Coding Issues to Optimize your site performance

5 Most Common Magento Coding Issues to Optimize your site performance

Here, We have 5 Most Common Magento Coding Issues to Optimize your site performance.

The Magento Expert Consulting Group has conducted dozens of code audits of client code bases and mined about 300 common coding issues made by PHP developers. About 28% of the issues affect performance and scalability of the code. The top 5 performance coding issues represent 84% of all performance issues. They were encountered in 96% of client code bases. In this article, ECG presents detailed descriptions of the top 5 magento PHP code performance issues along with the examples of code and recommendations on how to avoid them. Most of the issues are related to inefficient operations, redundant or useless computations and memory misuse. The top 5 are:

• Calculating the size of an array on each iteration of a loop
• SQL queries inside a loop
• Loading the same model multiple times
• Redundant data set utilization
• Inefficient memory utilization

Loops
-> Calculating the size of an array on each iteration of a loop :
A classic example of inefficiency is calling a count() function inside the condition part of a for statement

1
2
3
for ($i = 0; $i < count($rows); $i++) {
   //some code
}

Although count() is fairly fast in regular use, this changes rapidly when it is used in a loop. If the array or collection $rows contains a lot of data, this code is slowed down significantly. Because the PHP interpreter doesn’t perform loop-invariant code motion automatically, a much better way is to move the count() call outside the loop:

1
2
3
4
	$rowNum = count($rows);
	for ($i = 0; $i < $rowNum; $i++) {
	 //some code
	}

-> SQL Queries inside a Loop
Very often developers load Magento models in a loop. For example, they iterate over the array of product IDs to load a product model and process it in the loop:

1
2
3
4
	foreach ($this->getProductIds() as $productId) {
		$product = Mage::getModel(‘catalog/product’)->load($productId);
		$this->processProduct($product);
	}

Instead of loading products in a loop, a Magento data collection can help to load a set of models in a very efficient manner. The following example filters the result set of a collection by an array of product IDs and adds all requested product fields to result:

1
2
3
4
5
	$collection = Mage::getResourceModel(‘catalog/product_collection’)->addFieldToFilter(‘entity_id’, array($this->getProductIds()))->addAttributeToSelect(array(‘name’));
 
	foreach ($collection as $product) {
		$this->processProduct($product);
	}

Model
-> Loading the same model multiple times
Developers sometimes do not consider that model load operation is not internally cached, and each time the load() method is called, one or more queries are ran against the database. Loading the same model several times causes noticeable performance degradation. For example:

1
2
3
	$name = Mage::getModel(‘catalog/product’)->load($productId)->getName();
	$sku = Mage::getModel(‘catalog/product’)->load($productId)->getSku();
	$attr = Mage::getModel(‘catalog/product’)->load($productId)->getAttr();

Each model should be loaded only once (if there is a reason to load it at all) to optimize performance:

1
2
3
4
	$product = Mage::getModel(‘catalog/product’)->load($productId);
	$name = $product->getName();
	$sku = $product->getSku();
	$attr = $product->getAttr();

Another point to consider is that sometimes it is not even necessary to load the model because you don’t need to work with model entity itself. The following code loads a product merely to get the product ID:

1
2
	$product = Mage::getModel(‘catalog/product’)->loadByAttribute(‘sku’, $sku);
	$res[‘id’] = $product->getId();

In this case you can use the native product method getIdBySku() that will work much faster:

1
	$res[‘id’] = Mage::getModel(‘catalog/product’)->getIdBySku($sku);

Collections

-> Redundant Data set utilization
Collections are often used to retrieve only one item by calling the $collection->getFirstItem() method or returning the first item on the first iteration of the loop. A common mistake of inexperienced Magento developers is not applying a limitation on the collection’s query results.
It may be not obvious that the $collection->getFirstItem() method does not modify the collection’s
query results and restrict the result to one item itself. Therefore, if no restrictions are applied before it is called, it will load all the items of the collection as follows:

1
2
3
4
	public function getRandomItem() {
		$collection = Mage::getResourceModel(‘mymodule/my_collection’)->setRandomOrder();
		return $collection->getFirstItem();
	}

Always remember to apply the limitation in the case where the result of the query is a set of more than one item, in order to improve code performance and scalability

1
2
3
4
	public function getRandomItem() {
		$collection = Mage::getResourceModel(‘mymodule/my_collection’)->setRandomOrder()->setPageSize(1);
		return $collection->getFirstItem();
	}

Use the $collection->setPageSize() and $collection->setCurPage() methods to specify the limitation and offset, respectively, or modify the collection query directly:
$collection->getSelect()->limit().

Sometimes developers want to retrieve the number of items in a particular collection, without further
processing of its items. It such cases most of them use $collection->count() or count($collection)
constructs, which appear to be obvious and natural solutions. However, it is most definitely the wrong way, because all the items of the collection will be loaded from the database and iterated. It is much more efficient to call the $collection->getSize() method instead.

-> Inefficient memory utilization
Using the database adapter method fetchAll() to fetch large result sets will cause a heavy demand on system and possibly network resources. Magento developers often fetch and iterate result sets as follows:

1
2
3
4
	$rowSet = $this->_getReadAdapter()->fetchAll($select);
	foreach ($rowSet as $row) {
	 //process row
	}

On large amounts of fetched data, this code will execute for a very long time and PHP will probably run out of memory. In the following example, each database row is fetched separately using the fetch() method to reduce resource consumption:

1
2
3
4
	$query = $this->_getReadAdapter()->query($select);
	while ($row = $query->fetch()) {
	 //process row
	}

References
Magento – Magento Tips

Add comment


 

Pin It on Pinterest

Share This