Laravel 8 性能优化自查清单
Laravel 开箱即用速度很快,但通过优化配置和应用程序代码,你可以使其更快。本指南列出了从快速优化到深度调优的各种性能优化技巧,这些技巧可以帮助你让你的 Laravel 应用成为客户想要的轻巧、简约的程序服务。
在 Enlightn 上有不少同学在帮助我们编写了本指南。如果你正在寻求 Laravel 的自动化性能或安全工具,不妨可以访问这个网站看看。
为什么要提高性能?
毫无疑问,相比加载速度慢的应用程序,我们更喜欢加载速度更快的应用程序。
根据谷歌的一项研究,加载时间超过3秒的网站,在移动端会有 53% 的用户流失(选择离开)。而移动网站的平均加载时间约为 15 秒。这就是性能的重要性!
你的应用每增加一秒的加载时间,你的客户转化率可能就会越低。谢天谢地,对于 Laravel 应用程序来说,这并不是一个很难解决的问题。
1. 使用内置性能能力快速获胜
Laravel 提供了一些内置的性能提升能力,可以适用于任何应用程序。
最关键的性能提升是 路由缓存 。你是否知道每次启动 Laravel 应用程序时,应用程序都会确定中间件,解析别名,解析路由组并为每个路由标识控制器操作和参数输入?
你可以使用 Artisan 命令 route:cache
来缓存所有必需的路由信息,从而绕过路由处理:
php artisan route:cache
这条命令可以给你带来 5 倍的性能提升!它会对你的应用程序性能产生重大影响。
除了路由缓存,Laravel 还提供以下内容:
配置缓存 在每次应用启动时跳过
.env
和config
文件的解析。视图缓存 预编译你的 Blade 模板视图。
事件缓存 缓存应用程序所有事件和监听器清单。
提示:你应该确保将上述缓存命令添加到部署脚本中,以便每次部署时都重新缓存路由,配置,视图和事件。否则,你对路由或配置文件所做的任何更改都不会在应用程序中更新。
2. 优化 Composer
Laravel 开发人员时常会犯的一个错误是在生产模式下安装所有依赖项。一些开发包(例如 Ignition)会在内存中记录你的查询、日志和转储,从而为你提供带有上下文的友好错误消息,简化调试过程。尽管这在开发中很有用,但可能会减慢生产环境中应用程序的速度。
在你的部署脚本中,使用 Composer 安装拓展包的同时请务必使用 -no-dev
选项:
composer install --prefer-dist --no-dev -o
此外,请确保如上所述在生产环境中使用 -o
选项。这可以让 Composer 可以通过生成「classmap」来优化自动加载器。
如果你的应用在运行时没有生成类,你可以选择使用 --classmap-authoritative
选项而不是 -o
选项进行进一步优化。请务必查看 Autoloader 的 Composer 文档 优化策略.
3. 选择正确的驱动程序
选择正确的缓存、队列和会话驱动程序将会对应用程序性能产生极大影响。
对于生产环境中的缓存,我们推荐 Redis、Memcached 或 DynamoDB 等内存缓存驱动程序。你可以考虑将本地文件系统缓存用于单服务器设置,尽管这将比缓存到内存的选项慢。
对于队列,我们推荐使用 Redis、SQS 或 Beanstalkd 驱动程序。数据库驱动程序不适用于生产环境,并且已知可能会存在死锁问题。
对于 session,我们推荐数据库、Redis、Memcached 或 DynamoDB 驱动程序。Cookie 驱动程序具有文件大小和安全限制,不建议用于生产环境。
4. 将耗时的任务通过队列处理
在典型的 Web 请求过程中,可能会有一些特定任务需要很长时间才能执行完成。Laravel 拥有一流的 队列系统,这可以让我们将耗时的任务转移到队列的任务中,从而让你的应用程序能够以极快的速度响应请求。
一般情况下,这类任务的常见示例包括解析和存储 CSV 文件、与第三方 API 交互、向用户发送通知、存在较长耗时的数据库查询和搜索索引更新。
5. 在文本格式文件上设置压缩头
压缩头会对应用程序性能产生重大影响。确保你在 Web 服务器上为文本格式文件(如 CSS、JS、XML 或 JSON)启用压缩头或 CDN。
图像格式已经有压缩算法的实现且大多数情况图像格式文件已经被压缩过,并且图像并不是文本格式文件(SVG格式除外,这是XML文档)。因此,图像格式不需要压缩。
你可以在 Web 服务器或 CDN 上设置 gzip 或 brotli(较旧的浏览器可能不支持 brotli),以获得较大的性能提升。
通常情况下,压缩可以将文件体积大小减少 80% 左右!
6. 在静态资源上设置缓存头
缓存可以提高应用程序的性能,特别是对于静态资源,如图像、CSS 和 JS 文件。建议在 Web 服务器或CDN 级别启用缓存控制头(如果适用的话)。如果你希望在 Larvel 应用程序而不是 WebServer上设置这些控制头,可以使用 Larvel 的 缓存控制中间件。
Cache 消息头字段可以确保浏览器不会在以后访问你的网站时重复请求静态资源。这可以提高你的用户体验,因为你的网站在随后的访问时可以加载更快。
确保你使用了缓存清理的功能,以便在更改 CSS 或 JS 代码时,浏览器不会继续使用旧的缓存内容。Laravel Mix 提供了开箱即用的缓存清理 功能。
7. 考虑使用 CDN 服务加速静态资源
内容交付网络(CDN)是一个基于地理分布式的服务器组,通过使用距离网站访客更近的服务器来提供服务。可以让访问用户体验到更快的加载时间。
除了更快的加载速度和更短的加载时间外,CDN 还具有其他优点,如减少 Web 服务器负载,DDOS 保护和静态资源服务的分析等。
一些流行的 CDN 包括 CloudFlare、AWS CloudFront 和 Azure CDN。大多数 CDN 都有一定的免费试用额度。请考虑使用 CDN 来提升静态资源的加载性能。
Laravel 在框架中提供了开箱即用的 CDN 支持组件 Mix 和助手函数 asset。
8. 最小化你的 JS 和 CSS 代码
最小化脚本将会从你的应用程序中去除对执行不必要的额外代码(如代码注释、空格、将变量重命名为名称较短的变量名以及其他优化)。这是一个在生产环境中减小 JS 和 CSS 文件大小常用且有效的手段。
Laravel Mix 为你的生产脚本提供了开箱即用的 最小化输出 功能
9. 合理使用缓存
Laravel 内置了 缓存 支持。缓存最适合用于读取繁重的工作负载。这些工作负载通常涉及耗时的数据检索或数据处理任务。
缓存的一些常见场景案例可能包括:
缓存静态页面:缓存静态页面是一件轻而易举的事. Laravel 的官网使用 页面缓存 的方式缓存每一个文档页面。
片段或部分缓存:有时候,相比缓存整个页面,缓存页面片段可能更有用。例如,你可能希望缓存包含用户名和用户头像的页眉。你可以一次性缓存页面页眉片段,而不需要每次都从数据库中获取数据。
查询缓存:如果你的应用程序频繁地查询数据库中很少更改的项,则查询缓存可能会很有用。例如,当你经营一家电商网站,你可能希望缓存商城主页上显示的项目,而不是在每次访问商城时从数据库中读取这些项目。
请记住,缓存对long tail
(很少请求的项目)没有用处。相反,对于任何频繁进行的数据检索(与数据更新相比),应谨慎使用它。
还必须确保每次缓存内容更改时都使缓存无效或刷新缓存。例如,如果您正在缓存配置文件头,则在用户更新其配置文件图片后刷新缓存。
10. 确定您的应用程序的性能瓶颈
如果您的某些页面加载时间较长或内存使用率较高,则可能需要确定性能瓶颈。Laravel 生态系统中有许多工具可以帮助您做到这一点,包括 Laravel Telescope、Laravel Debugbar 和 Clockwork 。
一些常见的性能瓶颈包括:
N+1个查询:如果您的代码为每个记录执行一个查询,将导致更多的网络往返和更多的查询。这可以在 Laravel 中使用 Equired loading.
Duplicate Queries]来解决:如果您的代码针对同一请求多次执行同一查询,则可能会减慢您的应用程序的运行速度。通常情况下,如果多个服务或类需要相同的数据集,则可以通过将数据计算或检索提取到单独的类来解决这些问题。
高内存使用率:为了减少应用程序的内存使用量,可以考虑使用 Lazy collections 和 Query chunking 来减少模型水化。若要存储文件,请签出 Automatic streaming 以减少内存使用。
慢查询:如果您的查询执行时间过长,则应考虑使用查询缓存和/或使用EXPLAIN语句来优化查询执行计划。
如果你无法使用上述调试工具确定应用程序中的性能瓶颈,则可以考虑使用 XDebug 或 Blackfire 等分析工具。
总结
性能优化是一个永恒的话题,但 Laravel 有几个内置组件,如 Mix、queues 和缓存,这使性能优化看起来很简单!我们希望你在提高应用程序性能方面学到一些新知识。