Magento的架构设计的非常灵活,官方的考虑是希望架构能够适应可能遇见的所有情况,其中最重要的一部分是EAV模式的设计(也是被很多人又爱又恨的一块)。在实际应用中,每个网站总是有各自实际的固定情况,而不用像官方做产品那样去照顾方方面面,这个时候灵活的架构设计有时候反而会成为系统性能上的负担。不过我给的这个例子不是跟高大上的EAV相关的,也不一定是实际应用中最需要改的位置,只能算是抛砖引玉,给别人也给自己提个醒。
用Magento搭建的卖服装的网站,一般会用可配置商品(Configurable Product)来管理商品,选择颜色和尺码(原生不自带)属性来做配置项。Magento系统的可配置商品理论上可以用三个,四个甚至更多个属性来作为配置项,因此它的代码结构设计上支持可配置商品用无限多个属性配置项,而实际业务中,可配置商品最多会用到两个属性配置项,比如服装类的颜色和尺码(不排除有少数特殊的品类会用到多个,但总归是有限的),这种情况下原生的代码在性能上可能就会成拖后腿的了。
if ($this->_isStrictProcessMode($processMode)) { foreach($this->getConfigurableAttributes($product) as $attributeItem){ /* @var $attributeItem Varien_Object*/ $attrId = $attributeItem->getData('attribute_id'); if(!isset($attributes[$attrId]) || empty($attributes[$attrId])) { $subProduct = null; break; } } }
上面这段代码出自Mage_Catalog_Model_Product_Type_Configurable里的_prepareProduct方法,目的是为了在商品加购物车时验证接收的参数中,属性id(比如颜色默认是80)是否与该可配置商品所含有的配置项属性对应。为了取出商品包含的两个属性的id(以颜色和尺码为例),这里使用了getConfigurableAttributes这个方法来动态的从数据库中获取。而事实上,在网站实际运作中,我们后台添加完属性时就已经知道了这俩个属性的id(颜色系统自带,id为80,新增的尺码在我的开发环境里id是133),没有必要再一次从数据库中去获取。
可能有人觉得从数据库获取一下这个数据所带来的负担微不足道,一方面我上面已经提到只是举个例子,做个抛砖引玉,提醒下大家在开发中可以考虑这个优化角度,另一方面,这个例子其实还是特地挑出来的,getConfigurableAttributes这个方法附带连锁的代码有不少,当颜色属性的选项数超过40个时,每次添加购物车时,这段代码会造成多0.4秒的时间消耗(本机开发环境实测),如果颜色和尺码属性各自的选项数量更大时,这段代码所消耗时间还会更长,相比直接硬编码已知的id80和id133,区别已经到了肉眼可见的程度。至于为什么getConfigurableAttributes方法会有这种情况,我这里就不细说了,有兴趣的可以研究下源码。
回到主题,Magento的架构设计的很灵活,当你自己的网站在某些方面不需要那么灵活时,适当的改造灵活代码为硬编码,也许刚好就能帮助你解决某个困扰已久的性能瓶颈。以上是我的个人见解,欢迎拍砖。