Tuesday, November 11, 2014

Drupal 7 Useful Performance Tips

The below stated points are easy to implement if considered from the beginning of the development. By applying these simple guidelines a substantial performance improvement can be achieved for large Drupal 7 based websites which serves a lot of contents to bigger user base.

1. Use EntityFieldQuery to get data from database since it utilizes entity cache. This is faster than drupal db_query as it do not hit database server, rather than it uses cache tables / memcache.

2. Use AjaxBlocks to render the blocks/sections which should not be cached. This will improve the performance as most of the page will be served from cache. Also ajax request won’t affect page load.

3. While integrating Apache Solr Search, should avoid multiple calls to Solr on page load. Only one call should be made to Solr at page load, and all the other calls need to be fired via ajax after page load.

4. Avoid using views module for very complex displays to avoid unnecessary table joins from views. Develop these using custom codes and implement appropriate caching for these. Views module by default executes many queries which are executed in parallel with actual query which slows down the page execution. Views is good where a simple listing, grid, tabular data display with simple business logic. It is recommended to use custom code to generate the page where business logic is complex and need to alter views query operations.

5. If possible views litepager module can be used for better performance. If any pagination do not have link to go to the last page, there litepager can be implemented. This module is useful where the number of recordset is huge. This module bypasses traditional count query execution to determine total number of recordset which might be costly where there is large number of records.

6. Use varnish reverse proxy cache for anonymous users traffic. As anonymous users are expected to see static content, varnish can serve content directly from load balancer layer rather than hitting apache server and mysql server. Thus server load will be reduced for anonymous traffic.

7. If there are theme switching based on user location / device, then two different varnish cache needs to be configured for different domains (if two separate domain is used for each theme) otherwise have to configure varnish to detect request header at load balancer level.

8. Opt for responsive design rather than theme switching if possible. Theme switching is a conditional operation in drupal while the theme is needed to be changed based on the device. There is an additional overhead for caching functionality if varnish is used, as two different themes will be seen in same url. So it is suggested to use responsive design rather than theme switching for performance optimization benefits.

9. If same function is called multiple times in a page having same arguments, implement the usage of drupal static variables so that the function can early return the result during 2nd time calls onwards without executing the rest section.

10. Drupal Cronjobs should be running via drush. Drupal executes cronjob via drush with better memory management functionality than traditional cron.php execution which overheads apache php process in the server which might impact frontend users. Drush executes cronjobs in command line with separate php process which do not put load on the main php process responsible for generating drupal powered web pages.

11. Web service results should be cached if possible. Webservice is responsible for communication between two servers with different application. Frequently used webservices can cause slowdown a server as it consumes lot of resources (cpu,memory, network, I/O etc) to server data from one server to another server. Read-only web service data can be cached for certain amount of time having an expiry period so that web service will not be called again and again for same resultset reqested by the servers. Thus it also reduces the overhead of server resource utilization. If implemented, it is also to be noted that webservice cache needs to be cleared upon any change of provider’s data so that the consumer server will not get stale data from cache after data manipulation.

12. In mysql server, innodb_buffer_pool_size parameter should be according to the installed physical memory of database server (60-70% of size can be allocated for mysql). This parameter is mysql is responsible to pull the data from Disk to memory and send back that to requested application server. Increasing this parameter will result better performance if it is set to an optimal value based on server’s physical memory.

13. Use CDN or AKAMAI if possible for javascript, css and images only. Browsers can connect upto 4 domains for parallel download of static assets. CDN / AKAMAI provides separate cookie-less domains/subdomains for serving static assets of the webpages (js/css/images) . As a result, browser can parallel download static assets for faster page response.

14. Images should be properly scaled and compressed as per web standard. Force resize should not be done in tags. Images have specific compression rates while used for web pages. Images should be resized/scaled exactly same dimension as per html design. Otherwise, browser will spend extra time for downloading images larger than the standard size.

15. JavaScript and CSS should be aggregated, minified and gzipped. Drupal.org provides contrib advagg module to compress and minify javascript and css files with gzip format. This compressed static assets takes less time to be downloaded by browsers and saves around 80% of network bandwidth. Also number of http calls by browser is also reduced as multiple css and js files are combined into a single minified file during page rendering.

16. gZip compression in apache server should be turned on (apache mod_deflate module) to deliver compressed web pages to the browser to save bandwidth. Gzip compressed web pages have 80% less size rather than uncompressed pages. So pages will display faster in web browsers.

17. Small icons should be placed as a single css sprite image rather than multiple small images. An image sprite is a collection of images put into a single image. A web page with many images can take a long time to load and generates multiple server requests. Using image sprites will reduce the number of server requests and save bandwidth.