Since we starting using the massively convenient GAE Mini Profiler, we were surprised to discover that we spend a significant amount of time reading files from disk. Here’s a particulary extreme example:
This was contrary to my understanding that App Engine tries to cache almost any code-related file read. After investigating, I found that App Engine does try to cache templates – see the source of template.py. But it turns out this only works when you render a template directly with webapp.template.render
, and not when you use Django’s inclusion_tag
.
To verify this, I put together a basic page with some repeated template use and used opensnoop (and after discovering that tool, I need to learn more about DTrace) to observe changes to the filesystem. Here’s the result when using inclusion_tag
. You can see the template simple_student_info.html
was loaded over and over again:
$ sudo opensnoop -n Python UID PID COMM FD PATH 501 27864 Python 7 . 501 27864 Python 6 /Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/../../VERSION 501 27864 Python 6 /var/folders/TX/TXTcFXvEFKKsTqfua-9AGE+++TI/-Tmp-/request.7SyMKG.tmp 501 27864 Python 6 /var/folders/TX/TXTcFXvEFKKsTqfua-9AGE+++TI/-Tmp-/request.7SyMKG.tmp 501 27864 Python 7 /Users/dmnd/projects/khan/src/desmond/templatetest.html 501 27864 Python 7 /Users/dmnd/projects/khan/src/desmond/simple_student_info.html 501 27864 Python 7 /Users/dmnd/projects/khan/src/desmond/simple_student_info.html 501 27864 Python 7 /Users/dmnd/projects/khan/src/desmond/simple_student_info.html 501 27864 Python 7 /Users/dmnd/projects/khan/src/desmond/simple_student_info.html 501 27864 Python 7 /Users/dmnd/projects/khan/src/desmond/simple_student_info.html
When calling webapp.template.render
directly, the template is only read once:
$ sudo opensnoop -n Python UID PID COMM FD PATH 501 27864 Python 6 /Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/../../VERSION 501 27864 Python 6 /var/folders/TX/TXTcFXvEFKKsTqfua-9AGE+++TI/-Tmp-/request.j-MxJs.tmp 501 27864 Python 6 /var/folders/TX/TXTcFXvEFKKsTqfua-9AGE+++TI/-Tmp-/request.j-MxJs.tmp 501 27864 Python 7 . 501 27864 Python 7 /Users/dmnd/projects/khan/src/desmond/templatetest.html 501 27864 Python 7 . 501 27864 Python 7 /Users/dmnd/projects/khan/src/desmond/simple_student_info.html 501 27864 Python 7 . 501 27864 Python 7 . 501 27864 Python 7 . 501 27864 Python 7 .
As we’re already using inclusion_tag
all over the place, I added support for AppEngine’s template caching to it replacing all usages of django.template.Library
with my own subclass. You can use it by including this file in your project, and changing the top of your templatetags.py
files like so:
1 2 |
|
1 2 |
|
Caveats: we’re still using Django 0.96, so there’s a chance this only applies to that version of Django on AppEngine.