It’s the WordPress plugin for webshops, without a question. For a shop that is not running WooCommerce with thousands of products, it has a very nice performance, too. However there are limitations and drawbacks running WooCommerce with many products. That’s mostly because it is build upon the WordPress database scheme, which forces WooCommerce to save much data in the wp_postmeta table.

For a shop that is not running WooCommerce with thousands of products, it has a very nice performance, too.

In my current installation, WooCommerce creates 26 meta-fields for each product, so the product related meta-table rows would grow beyond a million for more than 38 461 products. Adding other theme and plugin related fields, you might cross that mark much earlier. Dependent on your server architecture, such a big meta-table, can make some database queries really slow.

… product related meta-table rows would grow beyond a million for more than 38 461 products.

Running such a big shop should make you think about your server architecture. The odds are high that you can’t avoid an upgrade in the long run. However, sometimes a quick workaround is the only way to make things running again. Following two quick and dirty fixes to make your admin panel faster, when running WooCommerce with thousands of products.

WooCommerce Status Dashboard

With WooCommerce activated, you see a admin dashboard widget, that sums up you WooCommerce status, with sales per month, most sold product, order status and stock status. As it turns out, are the stock status queries very slow, dependent on the meta-table size. Here is how to turn of them in your functions.php file:

function themeslug_deactivate_stock_reports($from) {
 global $wpdb;
 return "FROM {$wpdb->posts} as posts WHERE 1=0";
}
add_filter( 'woocommerce_report_low_in_stock_query_from', 'themeslug_deactivate_stock_reports' );
add_filter( 'woocommerce_report_out_of_stock_query_from', 'themeslug_deactivate_stock_reports' ); 

Note, that turning of these reports will result in 0-values in your dashboard!

woocommerce-status-dashboard-query

 

Slow Edit WooCommerce Product for WordPress >= 4.4.0

Another effect of a big meta-table is the product edit page in wp-admin (it affects even the edit page of posts and pages). Since WordPress 4.4.0 there is made an extra query to the meta-table, which might couse long loading times. And of course there is a hook too disable it. Place the following code in your functions.php file.


function themeslug_postmeta_form_keys() {
 return false;
}
add_filter('postmeta_form_keys', 'themeslug_postmeta_form_keys');

Be aware that even this fix not only makes the edit page faster, it turns even off functionality in the meta-field box!

Other measures

There is much more you can do, to make WooCommerce with thousands of products faster, like optimizing your server architecture or using tools like Elastic Search or Redis Cache. If you need to use the above workarounds, you always should consider some of these measures in the long run!

A couple of months ago, I’ve heard the first time about Grunt. I wasn’t that impressed. It seemed to be like a more advanced CodeKit, which was compiling my SASS and JS at the time. So I forgot about it, proving once again, that I just not am an early bird :/ Of course the buzz got too big for being ignored and now I am all into Grunt, Yeoman and even Gulp as everyone else.

Using Grunt for some time now, I’m beginning to realize that it not only improved my workflow, but changed it. So this article is not about learning Grunt, there already are some of them out there. It is about why I think Grunt, or more generally task managers like Grunt will really make a difference in how web-developers do their work.

A plattform independend foundation

But first some basics. One of the most important things about Grunt is that it is based on node.js and really runs platform independent. Also with node.js comes its community, producing an impressive amount of functionality. All the node modules they are developing, from 100% javascripted ssh-clients to complete test frameworks, can be used with Grunt.

Then there is npm, the node.js package manager. It lets you easily define all dependencies on a project bases. If you have to use the compass mixin library in one project and want to use bourbon in another, one line in your projects packages.js and a npm install fixes it.

Last but not least the node.js world is all javascript. That is so important because all web-developers, despite their back-end programming language preferences, know javascript. For a web-developer there are basically no hurdles to getting started with Grunt.

All in all node.js is a stable, well used and tested development foundation, with a living community and a huge amount of functionality packed in modules ready to download. Everything you need for your development workflow is already there. Grunt just helps you to bundle it all together.

Coding workflows

So, why is this such a big change? Before Grunt I already had a workflow. Or a kind of workflow that stayed pretty much the same for every project I was working on, but not entirely the same. This workflow even had multiple phases, like development, testing, bug-fixing and deployment and everyone of them had different tasks. To remember all these at the right time can be impossible sometimes. I don’t know how many times I’ve forgotten to merge and compress CSS for deployment or to do a last coding standards check.

Grunt is helping with these tasks, by just letting you write them down and executing them automatically when you need them. That’s what a task-manager should do. But Grunt, and that’s my point, is doing something more. It doesn’t only automates the tasks you have done before, it makes you build, rethink and structure them consciously. You have to think about what your workflow should look like in the beginning of a project and you have to refactore your workflow as the project evolves.

What I mean is: with Grunt we have begun to code our coding workflows. Just as we code our tests when we do unit testing. You might think thats no big deal, nothing a couple of bash-scripts doesn’t solve. I agree, technically it is nothing revolutionary. Yet, I think Grunt will change a lot for web-developers, because it is so well suited for sharing.

Sharing and evolving workflows

A Google search on gist “gruntfile.js” returns more than 5000 hits. So it seems that we are not just coding workflows with Grunt, we’ve even started to share them. I’m convinced thats because of the facts about node.js I’ve named before and that every web-developer is able write some javascript tasks in no time. That is the good thing with coding workflows. We are so incredibly good at improving our code. We already have a huge community, doing nothing else than improving code all the time. So, now our workflows have become formalized code, we can improve them the same way. We can share them on Github, ask about them on Stackoverflow, discussing them in our blogs or compare them to others workflows.

So I think, over time, this will change a lot about how web-developers work. That said, the perfect finish to this article seems to be my own gruntfile.js, defining my current WordPress theme workflow:

module.exports = function(grunt) {

	grunt.initConfig({

		pkg: grunt.file.readJSON('package.json'),

		// chech our JS
		jshint: {
			options: {
				"bitwise": true,
				"browser": true,
				"curly": true,
				"eqeqeq": true,
				"eqnull": true,
				"esnext": true,
				"immed": true,
				"jquery": true,
				"latedef": true,
				"newcap": true,
				"noarg": true,
				"node": true,
				"strict": false,
				"trailing": true,
				"undef": true,
				"globals": {
					"jQuery": true,
					"alert": true
				}
			},
			all: [
				'gruntfile.js',
				'../js/scripts.js'
			]
		},

		// concat and minify our JS
		uglify: {
			dist: {
				files: {
					'../js/scripts.min.js': [
						'../js/scripts.js'
					]
				}
			}
		},

		// compile your sass
		sass: {
			dev: {
				options: {
					style: 'expanded'
				},
				src: ['../scss/style.scss'],
				dest: '../style.css'
			},
			prod: {
				options: {
					style: 'compressed'
				},
				src: ['../scss/style.scss'],
				dest: '../style.css'
			},
			editorstyles: {
				options: {
					style: 'expanded'
				},
				src: ['../scss/wp-editor-style.scss'],
				dest: '../css/wp-editor-style.css'
			}
		},

		// watch for changes
		watch: {
			scss: {
				files: ['../scss/**/*.scss'],
				tasks: [
					'sass:dev',
					'sass:editorstyles',
					'notify:scss'
				]
			},
			js: {
				files: [
					'<%= jshintTag %>'
				],
				tasks: [
					'jshint',
					'uglify',
					'notify:js'
				]
			}
		},

		// check your php
		phpcs: {
			application: {
				dir: '../*.php'
			},
			options: {
				bin: '/usr/bin/phpcs'
			}
		},

		// notify cross-OS
		notify: {
			scss: {
				options: {
					title: 'Grunt, grunt!',
					message: 'SCSS is all gravy'
				}
			},
			js: {
				options: {
					title: 'Grunt, grunt!',
					message: 'JS is all good'
				}
			},
			dist: {
				options: {
					title: 'Grunt, grunt!',
					message: 'Theme ready for production'
				}
			}
		},

		clean: {
			dist: {
				src: ['../dist'],
				options: {
					force: true
				}
			}
		},

		copyto: {
			dist: {
				files: [
					{cwd: '../', src: ['**/*'], dest: '../dist/'}
				],
				options: {
					ignore: [
						'../dist{,/**/*}',
						'../doc{,/**/*}',
						'../grunt{,/**/*}',
						'../scss{,/**/*}'
					]
				}
			}
		}
	});

	// Load NPM's via matchdep
	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

	// Development task
	grunt.registerTask('default', [
		'jshint',
		'uglify',
		'sass:dev',
		'sass:editorstyles'
	]);

	// Production task
	grunt.registerTask('dist', function() {
		grunt.task.run([
			'jshint',
			'uglify',
			'sass:prod',
			'sass:editorstyles',
			'clean:dist',
			'copyto:dist',
			'notify:dist'
		]);
	});
};

SASS/SCSS and Grunt are fantastic tools to organize and automatize css development. With some easy adjustments you can even make grunt to compile your css for multiple color schemes.

Build your base SASS color scheme

The easiest way to prepare your files for auto-compiling SASS color schemes is to create a color variable for every color you want to change in your schemes. You should do that in a separate section of your code, so you can easily copy all color variables and create a new color scheme. The only thing you have to think of is to add the default-attribute to the variables, so they can be overridden. I usually and up wit a section like that in my styles:


/*
 * Default colors
 */

$light: #fafaf9 !default;
$dark: #111111 !default;

$color-1: #ef4f47 !default;
$color-2: #75d9c6 !default;
$color-3: #ffe851 !default;

Preparing additional SASS color schemes

The next step is to create all color scheme files. Create a folder called schemes or something like that put a file with the name color-scheme-1.scss in it. This file should define your color variables again (without the default-attribute) and include all other styles after the variables.

/*
 * Color scheme 1
 */
$light: #efefef;
$dark: #222;

$color-1: red;
$color-2: green;
$color-3: blue;

@import "../style";

Now you can create as much SASS color scheme files as you want, just repeat this pattern in every scheme.

Automated SASS color scheme Grunt task

Finally its time to setup your Grunt tasks. I assume you know how to compile SASS/SCSS via grunt, so the only thing to do is to add a sass-task for every scheme in you grunt-file:


sass: {
    dev: {
        src: 'scss/style.scss',
        dest: 'style.css'
    },
    'color-scheme-1': {
        src: 'scss/schemes/color-scheme-1.scss',
        dest: 'css/color-scheme-1.css'
    },
    'color-scheme-2': {
        src: 'scss/schemes/color-scheme-2.scss',
        dest: 'css/color-scheme-2.css'
    }
},

Now run

grunt sass:color-scheme-1

and you get a color-scheme-1.css file in your css-directory. If you include this file instead of your default style.css, you will get your layout in the schemes colors. Auto generate all schemes with

grunt sass