在使用异步框架时,最重要的问题就是保持异步。这一点十分影响我们对于框架组件的选择,如不能用requests只能用aiohttp,不能用pymysql要用aiomysql。那这里就有一个问题了,对于模板引擎jinja2我们是否需要替换?下面我用aiohttp-jinja2来说明一下。

aiohttp-jinja2和jinja2

通常在异步框架中处处是异步,因此会认为aiohttp-jinja2是jinja2的异步修改版本,如同aiomysql和aiopg一般。但事实并非如此,查看源码会发现,aiohttp-jinja2仅仅在模板路由方面适配了一下aiohttp,此外仅仅加了一层包装,使其可以作为协程装饰器。

为什么不将jinja2改为异步版本呢?在寻找答案的过程中有了一个意外发现,jinja2从2.9版本开始添加了异步支持,这一点在官方文档也已经指出,我们完全可以直接使用jinja2作为异步模板而不需要任何修改。但在aiohttp-jinja2的源码中并没有开启异步功能,这又是为什么?

异步jinja2

因为事实并非这么美好,aiohttp-jinja2的开发者们在发现jinja2支持异步功能时,第一时间就进行了讨论和测试,结果是令人失望的,引用samuelcolvin测试数据:

Requests/sec:
    enable_async=False                    594.52
    enable_async=True                     219.19

可以发现jinja2开启异步模式后,在aiohttp框架中的性能反而下降了,不足在同步模式下的50%。这里的性能下降在官方文档就已经说明,只不过没想到下降了这么多。在jinja2没有做出重大修改之前,为了异步而开启jinja2的异步模式可以说是得不偿失的。

总结

协程是为了解决异步io问题,以前一直纠结jinja2这类的模板程序是计算阻塞型还是io阻塞型,现在看来应该是计算阻塞型。jinja2本身已经够快,以后直接使用即可,不用过多担心异步阻塞,当然aiohttp-jinja2作为包装过的jinja2,更适合配合aiohttp框架使用。