Кэширование сайтов на Flask. Расширение Flask-Caching
Кэширование позволяет сохранить результат выполнения функции (или скрипта) и при следующем ее вызове не выполнять ее снова, а возвращать ранее сохраненный результат. Такой механизм избавляет сервер от лишних вычислений. Обычно кэшируют на какое-то время. Однако в случае статического сайта на Flask для view-функций это можно делать "навсегда", то есть до перезапуска программного веб-сервера (при перезапуске сервера данные кэша теряются). Кэширование подходит не для всех функций.
Чтобы использовать кэширование во flask-приложении, следует дополнительно установить расширение Flask-Cashing:
$ pip install Flask-Caching
В приложении сначала задают конфигурацию кэширования, применить ее к экземпляру Flask
, потом создать экземпляр Cache
, через который происходит управление кэшем:
from flask_caching import Cache config = { "DEBUG": True, # some Flask specific configs "CACHE_TYPE": "SimpleCache", # Flask-Caching related configs "CACHE_DEFAULT_TIMEOUT": 300 } app = Flask(__name__) # tell Flask to use the above defined config app.config.from_mapping(config) cache = Cache(app)
Другие способы установки кэша см. на сайте расширения Flask-Caching.
Время кэширования задается в секундах. Если требуется кэшировать без ограничения по времени (бесконечное хранение), то используется значение 0 (в коде выше вместо 300 следует написать 0). Когда ведется разработка приложения, и кэширование надо отключить, то можно указать время в 1 секунду.
Чтобы результат выполнения view-функции кэшировался, после декоратора роутера и перед ее заголовком надо указать декоратор кэширования:
@app.route('/') @cache.cached() def index(): return render_template('index.html')
Если в настройках было задано время кэша по-умолчанию, и оно подходит для данной функции, то в скобках декоратора можно не указывать время. Иначе, это делается через параметр timeout
. Например, @cache.cached(timeout=50)
.
Если кэшируется обычная функция (не представление страниц), то следует присваивать уникальное значение параметру key_prefix
. По нему будет извлекаться результат выполнения функции из кэша (для view-функций роль ключей играют адреса). Его основная задача - предотвратить конфликты между различными функциями, которые используют кэширование.
@cache.cached(key_prefix='ads') def ads(): return ...
Не все функции можно кэшировать. Так в примере ниже предполагается, что функция вызывается из html-шаблона и выполняет подсветку соответствующего ей пункта меню. Если ее закэшировать, то на всех страницах сайта будет подсвечен один и тот же пункт.
def nav(menu, file_name): return Markup(menu.replace( f'<li><a href="{file_name}">', f'<li autoscroll class="selected"><a href="{file_name}">'))
С другой стороны, можно кэшировать и фрагменты кода Jinja2 в шаблонах. Однако это также подходит не для всех случаев.
{% cache 0 %} {{ highlighter('htmlD', ' ... ') }} {% endcache %}
Для очистки кэша используется метод clear
экземпляра Cache
. Например, можно создать view-функцию, ведущую на определенную страницу, в теле функции вызвать clear()
. При переходе по адресу страницы, кэш будет очищаться.
@app.route('/clear') def cache_clear(): cache.clear() abort(404)