diff --git a/tailbone/static/js/debounce.js b/tailbone/static/js/debounce.js new file mode 100644 index 00000000..8fea0eda --- /dev/null +++ b/tailbone/static/js/debounce.js @@ -0,0 +1,36 @@ + +// this code was politely stolen from +// https://vanillajstoolkit.com/helpers/debounce/ + +// its purpose is to help with Buefy autocomplete performance +// https://buefy.org/documentation/autocomplete/ + +/** + * Debounce functions for better performance + * (c) 2021 Chris Ferdinandi, MIT License, https://gomakethings.com + * @param {Function} fn The function to debounce + */ +function debounce (fn) { + + // Setup a timer + let timeout; + + // Return a function to run debounced + return function () { + + // Setup the arguments + let context = this; + let args = arguments; + + // If there's a timer, cancel it + if (timeout) { + window.cancelAnimationFrame(timeout); + } + + // Setup the new requestAnimationFrame() + timeout = window.requestAnimationFrame(function () { + fn.apply(context, args); + }); + + }; +} diff --git a/tailbone/static/js/tailbone.buefy.autocomplete.js b/tailbone/static/js/tailbone.buefy.autocomplete.js index eb36fa74..9b28f6b3 100644 --- a/tailbone/static/js/tailbone.buefy.autocomplete.js +++ b/tailbone/static/js/tailbone.buefy.autocomplete.js @@ -98,7 +98,7 @@ const TailboneAutocomplete = { // TODO: buefy example uses `debounce()` here and perhaps we should too? // https://buefy.org/documentation/autocomplete - getAsyncData: function (entry) { + getAsyncData: debounce(function (entry) { if (entry.length < 3) { this.data = [] return @@ -112,10 +112,10 @@ const TailboneAutocomplete = { this.data = [] throw error }) - .finally(() => { - this.isFetching = false - }) - }, + .finally(() => { + this.isFetching = false + }) + }), }, } diff --git a/tailbone/templates/themes/falafel/base.mako b/tailbone/templates/themes/falafel/base.mako index 24b533d1..bf8f5ee7 100644 --- a/tailbone/templates/themes/falafel/base.mako +++ b/tailbone/templates/themes/falafel/base.mako @@ -77,6 +77,9 @@ ## some commonly-useful logic for detecting (non-)numeric input ${h.javascript_link(request.static_url('tailbone:static/js/numeric.js') + '?ver={}'.format(tailbone.__version__))} + ## debounce, for better autocomplete performance + ${h.javascript_link(request.static_url('tailbone:static/js/debounce.js') + '?ver={}'.format(tailbone.__version__))} + ## Tailbone / Buefy stuff ${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.datepicker.js') + '?ver={}'.format(tailbone.__version__))} ${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.numericinput.js') + '?ver={}'.format(tailbone.__version__))}