I run Django 1.11.20. I have just (finally) made the jump from Python 2.7 to 3.7.
I've noticed that since upgrading to Python 3, the very first page load after clearing the cache is very slow. So far I only have my Python 3 environment on my development machine, so I'm experiencing this when using ./manage.py runserver
and the FileBasedCache
backend. I don't know if I will experience the same thing on a production stack (nginx, uwsgi, redis, etc).
I'm using Django Debug Toolbar, which gives me some hints as to what the problem isn't, but I'm not sure where I should look to see what the problem is.
The times given by the debug toolbar run loading a simple page with an empty cache in the Python 2.7 environment on my development machine are:
The times given by the debug toolbar run loading the same page with an empty cache in the Python 3.7 environment on my development machine are:
(I'm using the file based caching on this development machine, so when I say "with an empty cache" I just mean that I rm -r cache
before loading the URL in my browser.)
So the SQL and Cache times got slightly faster with the upgrade, but the CPU time doubled. When I open the "Time" panel in the debug toolbar I see that the "timing attribute" that increased is "request".
This same thing happens on every page (including pages that are just HTML generated by TemplateView
, so they're not doing anything tricky), but only when it is first loaded from an empty cache. After that very first response, all pages are back to about the same response time as in the Python 2 environment. So it is something to do with the initial request.
I'm not sure where to look to try to figure out what Django is doing only on the very first request. Any pointers? Or is there something obvious that I can expect to be slower in the jump from Python 2.7 to 3.7?
I was finally able to trace this problem back to the Django Debug Toolbar itself, which was bumped from 1.11 to 2.0 during my Python 3 upgrade. Specifically, the toolbar's SQL panel was causing the slowdown. I have a context processor which executes a query if a cached object does not exist. The query itself is fast, but for some reason Django Debug Toolbar 2.0 is extremely slow generating the stacktrace for it. I have not figured out what changed between 1.11 and 2.0 to cause this terrible performance loss, but now that I know where the problem lies I can work around it.