Когда использовать nocall на моем Tal: условии?
Я знаю, что для производительности это хорошая практика, чтобы использовать nocall
на <tal:condition>
во избежание вызова объекта. Был бы признателен (ссылки на) немного фона, поскольку это звучит немного расплывчато для меня:-)
Итак, когда вы используете Nocall? Может быть больно поставить его на все мои условия?
Спасибо!
4 ответа
Я склонен использовать вместо этого tal:condition="python: variable". Таким образом, я всегда могу писать нормальные правильные выражения Python, не опасаясь магического поведения из выражений пути по умолчанию.
Выражения пути будут делать несколько вещей, например, вызывать переменную в выражении, если она вызывается. Часто вы имеете дело с инструментами или элементами контента в TAL, которые все могут быть вызваны.
Наиболее распространенная ошибка - использовать tal:condition="content_object". Объект содержимого может исходить из ряда API, например, вызов любого поля ссылки возвращает объекты содержимого. Поиск по каталогу вернет "мозги", но в списках вам часто нужно получить доступ к дополнительным их атрибутам, поэтому у вас есть tal:define="obj brain/getObject".
Вызов объекта содержимого приводит к отображению объекта так, как если бы браузер запросил его. Так как рендеринг страниц обычно занимает от 500 мс до 2 секунд, вы делаете рендеринг страницы медленнее на это время. Если вы сделаете это в цикле из более чем 25 элементов, я ожидаю, что визуализация страницы займет 30 секунд или более.
nocall
позволяет получить "обработчик" для атрибута или метода объекта. Если вы хотите знать, имеет ли объект этот атрибут или метод, вы должны использовать:
<div tal:condition="nocall:context/method|nothing">
...
</div>
|nothing
работает аналогично except
блок в коде Python: если context/method
не удается (не определено), возврат nothing
, (Это может быть не совсем реальное объяснение, но работает так).
Еще одна причина использовать nocall
чтобы получить обработчик метода, который, как вы знаете, определен, и вы будете использовать позже:
<div tal:define="method nocall:context/method">
<span tal:content="python:method(3)" />
<span tal:content="python:method('hello')" />
<span tal:content="python:method('whatever')" />
</div>
Я предполагаю, что вы только добавите nocall:
к условиям, которые уже тестируют на элементах, которые не могут быть вызваны в первую очередь, и которые, возможно, избегают встроенной функции Python callable
Тест может дать вам повышение производительности.
Короткий ответ на этот вопрос - нет, это не поможет вам. На моем ноутбуке Macbook Pro работает callable(True)
1000 раз в такте 119 нс на цикл, против 71 нс на цикл для равнины True
заявление. Так что для простых объектов Python callable
тест занимает всего 48 нс. Добавление nocall:
для оператора TALES, с другой стороны, требует дополнительной обработки, которая почти наверняка превысит 48 нс заголовка callable
тест вы только что спасли.
Таким образом, добавляя nocall:
ради повышения производительности будет иметь неприятные последствия. Вы бы лучше реализовали правильное кэширование (смотрите plone.app.caching в сочетании с Varnish), или посмотрите, может ли Chameleon работать для вашего варианта использования.
Не ставьте это на все ваши условия. Это может повредить! Особенно люди, которые должны следовать вашему коду:-)