Django是一个非常棒的框架,相当重要的原因是它包含了快速创建web应用程序所需的一切。但是开发者不应该是唯一的受益者。这个应用程序对用户来说也应该更快。
官方文档中有一章是关于性能和优化的,其中提供了很好的建议。在本文中,我将在此基础上展示我过去用来减少页面加载时间的工具和方法。
测量 & 收集数据
性能基准测试和概要分析对于任何优化工作都是必不可少的。盲目地应用优化可能会增加代码库的复杂性,甚至可能使情况变得更糟。
我们需要性能数据来了解应该关注哪些部分,并验证任何更改是否达到了预期的效果.
django-debug-toolbar
django-debug-toolbar很容易使用,并且有一个很好的界面。它可以显示每个SQL查询花费了多少时间,并有一个快速按钮可以获得该查询的EXPLAIN输出和其他一些有趣的细节。template-profiler是一个额外的面板,用于添加有关模板呈现过程的分析数据。
不过,django-debug-toolbar也有一些缺点。由于它集成到站点中的方式,所以只有在DEBUG = True的开发环境中使用它是有意义的。它本身也会带来巨大的性能损失。
DTrace
DTrace就没有这些限制。它可以用于生产服务,并提供比项目的python部分更多的细节。您可以深入了解数据库、python解释器、web服务器和操作系统,以获得每个地方时间花费的完整信息。
这将发生在CLI中,而不是漂亮的浏览器UI中。DTrace脚本是用类AWK语法编写的。在dtracetools包中还有一些有用的脚本。当您使用Joyent pkgsrc repos时,您可以使用一下代码来安装它:
这个包中有用的脚本之一是dtrace-mysql_query_monitor.d,它将显示所有的MySQL查询:
您也可以对PostgreSQL做同样的事情:
输出将会像这样:
在dtracetools包中有一些非常有用的dtrace-py_*脚本,可以帮助你深入了解python过程本身。例如dtrace-py_cputime.d将显示一个函数的调用次数以及包含和不包含CPU的时间:
在本例中,我们看到在正则表达式相关的东西上花费了一些时间,可能与URL路由有关。
cProfile
标准的python库附带了cProfile,它将收集函数调用的精确时间。我们可以将它与django test client一起使用来进行自动化性能测试。
尽可能多地自动化性能数据收集步骤有助于快速迭代。在最近的一个项目中,我创建了一个专用的manage.py命令来分析最重要的URL。它看起来像这样:
我们不但可以打印统计数据,还可以使用pr.dump_stats(fn)将统计数据保存到磁盘。这允许我们使用flameprof进行进一步处理来创建火焰图。
%timeit
另一个来自标准库的方便实用程序是timeit。你会经常发现这样的例子:
这在对小型语句进行实验是很有用。
为了更进一步,我建议您安装IPython,它会将Django manage.py shell 转换成一个非常强大的开发环境。
除了tab-补全和其他上千个功能外,你还会拥有%timeit魔法。
优化
一旦你知道你的项目中哪些部分是最慢的,你就可以开始改进这些部分。通常大部分时间是花在数据库查询上,然后是模板呈现。
虽然每个项目可能需要不同的优化,但也有一些常见的模式。
预加载相关的对象
当您在模板中显示一个对象列表并访问一个相关对象的某个字段时,将触发一个额外的数据库查询。这些耗时很容易地叠加起来,并导致针对一个请求的大量查询。
当您知道您将需要哪些相关字段时,您就可以告诉Django以更有效的方式去获得这些字段。两个重要的方法是select_related()和prefetch_related()。
select_related()通过使用一个SQL JOIN prefetch_related()为每个查找创建一个查询。它们易于使用,几乎不需要对现有代码进行任何修改,并且可以带来巨大的改进。
索引
另一个容易应用的性能调整是确保您有正确的数据库索引。无论您何时使用一个字段进行filter,在某些情况下是进行order_by,您都应该考虑是否需要索引。创建索引与向模型字段添加db_index = True一样简单,然后创建并运行结果迁移。确保使用SQL EXPLAIN去验证改进。
缓存
缓存是一个很大的主题,有很多方法可以通过缓存来提高django的性能。根据环境和性能特征,使用缓存的位置、持续时间和层将不同。
django cache 框架是在各个层上利用Memcached的一种简单方法。@cached_property装饰器通常对胖模型方法很有帮助。
>>> 今日签到口令:8wgf <<<
预计算
有些计算对于一个HTTP请求的时间预算来说太长了。在这些情况下,我发现在后台进程中预先计算所需的数据是很有用的。这可以通过像Celery这样的任务队列来完成,也可以通过一个manage.py命令来降低复杂性,该命令可以作为一个服务或作为一个定时任务长期运行。
Django之外
除了这些常见的情况外,还有许多进一步优化web项目的方法。通过反规范化更改数据库模式可能会改进一些查询。其他技术将在很大程度上取决于项目的环境。
通常也有很多机会去优化堆栈和下面的东西。从浏览器中测量性能数据,在Django中花费的时间只会越来越少。有了这些新数据,你就可以开始处理DOM渲染、CSS和JS,减少图像请求大小或更好的网络路由。
查看更低级别的改进也能带来巨大的好处。即使是低级别的小改进也会导致性能的提高,这仅仅是因为这些部分运行得太频繁了。
最近的一个例子是,通过改变python解释器的编译方式,每个请求获得了约120ms的提升。我测试的cpython版本中已经启用了retpoline缓解。这是一个孤立的内部服务,而威胁模型是不需要这个服务的。因此,仅通过不使用-mindirect-branch=thunk-inline -mfunction-return=thunk-inline -mindirect-branch-register进行编译就可以极大地提高性能。
如果您的web项目需要进行一些性能优化,请随时联系我们!
英文原文:https://wiedi.frubar.net/blog/2019/11/18/django-performance/译者:Nothing
声明:本文部分素材转载自互联网,如有侵权立即删除 。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容