Hi,
just found out what was taking my server threw hell… it’s the search form that send a post on every letter tipped !!!
please, please add lodash debounce on this
it’s nothing to do
check this
https://css-tricks.com/debouncing-throttling-explained-examples/
please !!!
added to the fact that call is done via POST makes it hell to cache it!
and it really deserves caching !!
so changing it to a GET so cdn can cache it would be marvelous!
thanks
-
This topic was modified 6 years by
cantoute.
It’s because our users seem to love the search function that I’m going to need this badly… happy to help if possible, because the debounce stuff really are 4 dummy lines to add and they really make a difference on usability and server load.
It’ll make search display much faster then calling on every keypress.
With 140k posts and over 50k daily users… it’s really to be hard on server
Thanks
Hi Calin,
I was very busy with migrating that 140k pages site, so I didn’t take the time to look into this until now.
So I just prettified the script_for_front.js and had a quick look and the fix seams real easy.
somewhere around line 350 I see this
a.jqueryObj.find(".tdb-head-search-form-input").keydown(function (b)
{
if (b.which && 39 === b.which || b.keyCode && 39 === b.keyCode || b.which && 37 === b.which || b.keyCode && 37 === b.keyCode) tdbSearch.set_input_focus(a);
else
{
if (b.which && 13 === b.which || b.keyCode && 13 === b.keyCode) return b =
a.jqueryObj.find(".tdb-aj-cur-element"), 0 < b.length ? window.location = b.find(".entry-title a").attr("href") : jQuery(this).parent().parent().submit(), !1;
if (b.which && 40 === b.which || b.keyCode && 40 === b.keyCode) return tdbSearch.move_prompt_down(a), !1;
if (b.which && 38 === b.which || b.keyCode && 38 === b.keyCode) return tdbSearch.move_prompt_up(a), !1;
(b.which && 8 === b.which || b.keyCode && 8 === b.keyCode) && 1 === jQuery(this).val().length && a.jqueryObj.find(".tdb-aj-search").empty();
tdbSearch.set_input_focus(a);
setTimeout(function ()
{
tdbSearch.do_ajax_call(a)
},
100);
return !0
}
});
looking just on the last few lines
replacing this
setTimeout(function ()
{
tdbSearch.do_ajax_call(a)
},
100);
by that
debounce(
setTimeout(function () {
tdbSearch.do_ajax_call(a)
}, 0),
250
);
first you would need this https://davidwalsh.name/javascript-debounce-function
actually coming from an old version of underscore (it works!)
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
this is the actual up to date function on https://github.com/jashkenas/underscore/blob/master/underscore.js
but perhaps underscore can be useful to have in such a project
I see here that _.debounce requires _.delay who needs restArguments
this could be the “light” way that does the trick too
_ = _ || {};
_.debounce = function(func, wait, immediate) {
var timeout, result;
var later = function(context, args) {
timeout = null;
if (args) result = func.apply(context, args);
};
var debounced = restArguments(function(args) {
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(later, wait);
if (callNow) result = func.apply(this, args);
} else {
timeout = _.delay(later, wait, this, args);
}
return result;
});
debounced.cancel = function() {
clearTimeout(timeout);
timeout = null;
};
return debounced;
};
_.delay = restArguments(function(func, wait, args) {
return setTimeout(function() {
return func.apply(null, args);
}, wait);
});
// Some functions take a variable number of arguments, or a few expected
// arguments at the beginning and then a variable number of values to operate
// on. This helper accumulates all remaining arguments past the function’s
// argument length (or an explicit startIndex), into an array that becomes
// the last argument. Similar to ES6’s "rest parameter".
var restArguments = function(func, startIndex) {
startIndex = startIndex == null ? func.length - 1 : +startIndex;
return function() {
var length = Math.max(arguments.length - startIndex, 0),
rest = Array(length),
index = 0;
for (; index < length; index++) {
rest[index] = arguments[index + startIndex];
}
switch (startIndex) {
case 0: return func.call(this, rest);
case 1: return func.call(this, arguments[0], rest);
case 2: return func.call(this, arguments[0], arguments[1], rest);
}
var args = Array(startIndex + 1);
for (index = 0; index < startIndex; index++) {
args[index] = arguments[index];
}
args[startIndex] = rest;
return func.apply(this, args);
};
};
Perhaps you all ready have underscore? but didn’t spot it in that js
… it’s got nice goodies and comes handy 🙂 (17.6 KB not so bad ?)
hope this comes helpful, have a nice day.
oups editing code here is dangerous ö
perhaps on this https://pastebin.com/k0PRwzzC it’s more readable… but not much more :-/ sorry
no deed for the setTimeout… me dummy… the debounce will async your call 🙂
debounce(
tdbSearch.do_ajax_call(a),
250
);
and the old debounce function or adding underscore
it gets messy to take bits of the more recent _ versions…
-
This reply was modified 6 years by
cantoute.
looks a bit better here… sorry for all the noise
I finally found a way to hack it in… to give the server a breath
jQuery(function() {
jQuery('.tdb-head-search-form-input').on('keydown', function(e) {
if (typeof debounce_do_ajax_call === "undefined") {
console.log('tdbSearch.do_ajax_call override');
tdbSearch.original_td_do_ajax_call = tdbSearch.do_ajax_call;
// as hacked out of context, needed to hook context or debounce would trigger on each call
debounce_do_ajax_call = debounce(tdbSearch.original_td_do_ajax_call, 1500)
tdbSearch.do_ajax_call = debounce_do_ajax_call
}
});
});
// https://davidwalsh.name/javascript-debounce-function
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
The webiste I did with your theme has gone from small trafic to become nº1 in tennis in europe… thanks to your work !!
But that means that for Roland Garros I could have to handle over 500k daily visitors (we are yet over 70k)
It’s not that big… I have other site running 2M (not wp tho)
As the site uses infinit scroll… caching even of 3s would help
I coud suggest a very simple change that could change the deal about caching (the site is behind varnish)
php side have all ajax $_POST changed to $_REQUEST
then I could fiddle to change all ajax POST to { method:’GET’, cache:false }
it adds a &_=134567 that can be removed from url in varnish and then hit a common cache
… no rush, just clues 🙂
-
This reply was modified 6 years by
cantoute.
and here i took things one step further but the result is almost copy paste for devs
Just you wouldn’t have to put debounce_ajax_call in ‘window’ context, I was forced to it because my context is .on(‘foncsin’) (out of tdAjaxSearch object)
so in this hack i just debounce the actual ajax request (and not the do_ajax_call) that is changed to ‘GET’ (and removing the setTimeout)
line 19 there is
tdAjaxSearch.process_ajax_response_mob(b)
if you change it to
tdAjaxSearch.process_ajax_response_mob(b, a) // a being here the search term
then in function process_ajax_response_mob() you have the term without having to read the response 🙂
I was just playing around to look for ways of making life easier in there.
hope it can help
-
This reply was modified 6 years by
cantoute.
being here I had an other issue with the megamenu offsetting itself halfway threw the page when post had a tweet
this was the fix
/* fix megamenu offset when post has a tweet */
(function($){
$(window).load(function() {
$(this).trigger('resize')
})
})(jQuery)