When to use nocall on my hoist: condition?

I know that for performance it is recommended that you use nocall on <tal:condition> to avoid calling the object. Understand (links to) a bit of background, as that sounds a bit vague to me :-)

So when do you use nocall? Can it harm all my conditions?

Thanks!

+6
performance zpt template-tal zope plone
source share
4 answers

I prefer to use tal: condition = "python: variable". That way, I can always write normal correct Python expressions without fear of the magic behavior from the default path expressions.

Path expressions will do several things, for example, invoke a variable in an expression if called. Often you are dealing with tools or content elements in the TAL that are all callable.

The most common mistake is to use tal: condition = "content_object". A content object can come from several APIs, for example, content objects will be returned to call a reference field. A directory search will return brains, but in lists that you often need to access additional attributes, so you have tal: define = "obj brain / getObject".

A call to a content object causes the object to render as if the browser requested it. Since rendering pages usually take anywhere from 500ms to 2 seconds, you render your page slower by this amount of time. If you do this in a loop of more than 25 elements, I would expect the page to take 30 seconds or more to render.

+12
source share

nocall allows you to get the "handler" of an attribute or method of an object. If you want to find out if an object has this attribute or method, you should use:

 <div tal:condition="nocall:context/method|nothing"> ... </div> 

|nothing works like an except block in python code: if context/method does not work (there is undefined), return nothing . (This may not be just a real explanation, but it works like that).

Another reason for using nocall is to get a method handler, which, as you know, is defined, and you will use it later:

 <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> 
+5
source share

I assume that you would add only nocall: to conditions that have already been tested on elements that are not called in the first place, and that possibly avoiding the python builtin callable test can improve performance.

The short answer to this question is no, it will not help you. On my laptop, the Macbook Pro launched a callable(True) clock cycle at 119 ns per cycle, versus 71 ns per cycle for the simple True statement. So, for simple python objects, the callable test callable takes 48 ns. On the other hand, adding the nocall: operator to TALES requires additional processing, which will almost certainly exceed the 48ns overhead from the callable test you just saved.

Thus, adding nocall: to improve performance will have unpleasant consequences. You are better off implementing the right caching (see plone.app.caching in combination with varnish), or see if Chameleon can work for your use case.

+1
source share

Do not put it on all your terms. It could hurt! Especially people who should follow your code :-)

0
source share

All Articles