I was experiencing this same problem with an HTML5 game I'm developing. Sometimes the touchend would seem to fire immediately, and other times there would be a delay of several seconds before it fired.
I stumbled upon this post reminding me of the setTimeout 0 trick for pushing a block of javascript onto the queue for later processing. I was doing a bit of "heavy-lifting" (some DOM manipulation) inside the touchend event handler, and this appeared to disrupt its firing.
I wrapped the code inside my touchend handler with a setTimeout, and that eliminated the delay:
$(document).on('touchend', function (e) {
setTimeout(function(){
//do stuff here...
}, 0);
});