提高Laravel应用性能方法详解


Posted in PHP onJune 24, 2019

使用Laravel做开发是高效而愉悦的体验。
通常,当你准备部署应用的时候,你可能会意识到应用也许会在真实环境下表现不佳。

需要明白的是,没有银弹。通过努力去对应用的每个细节完成所有的优化,速度可能会变慢,但使用下面这些技巧会让你感到恰到好处。

缓存配置文件

laravel 的配置项分布在数十个配置文件中,在每次的请求中都将每个文件 including 进来很消耗性能。为了将所有的配置文件都合并为一个,可以使用:

php artisan config:cache

记住修改了配置文件后不会影响已有的配置文件缓存。为了刷新缓存,可以再次上述的命令。如果你想完全清除缓存,执行:

php artisan config:clear

路由缓存

在laravel中,路由也需要昂贵的开销。用以下命令缓存 routes.php 文件:

php artisan route:cache

请注意,它不适用于闭包。 如果你正在使用闭包,这是一个很好的机会将它们移动到控制器中,因为 artisan 命令在尝试编译绑定到闭包的路径而不是正确的控制器方法时会抛出异常。
与配置缓存相同,对 routes.php 的任何更改都不会有任何影响。 要刷新缓存,请在每次更改路径文件时运行上面的命令。 要完全清理干净路由缓存,请运行以下命令:

php artisan route:clear

类映射加载优化

在一个中型项目中,存在数百个 PHP 源文件是很正常的事情,由于良好的编程习惯,我们会把代码做一些分离,每一个 php 文件都有自己的职责。当然,这并非没有缺点,Laravel 必须为每一次请求都加载这数百个文件,这是一件很消耗性能的事情。

因此,一个比较好的办法是声明哪些文件是用户每一次请求(如:服务提供者,中间件等)都需要载入的 ,然后将这些需要每次加载的文件写入同一个文件中,减少 include 文件的数量。

这类似于 javascript 将文件合并为一个没有区别 (webpack, gulp),会减少游览器会服务器的请求。

如果需要添加其他的源文件,可以在 config / compile.php 的files key中声明。

当你把需要为每个请求都加载的文件设置好之后,它们就会写入同一个文件中,减少加载文件的性能消耗

php artisan optimize --force

优化 composer 的自动加载

这不仅适用于 laravel,而且适用于任何使用 composer 的应用程序。

我将首先解释 PSR-4 自动加载器的工作原理,然后向您展示应该运行什么命令来优化它。如果您对了解 composer 如何工作不感兴趣,我建议您直接跳到关于控制台命令的段落处。

当您向 compsoser 请求 App\Controllers\AuthController 类时,它首先在类映射中搜索直接关联。classmap 是一个由类和文件组成的 1 到 1 关联的数组。当然,由于您没有手动将 Login 类及其相关文件添加到类映射中,composer 将继续在命名空间中搜索。

因为 App 是一个 PSR-4 命名空间,默认情况下是与 Laravel 一起提供的,并且与 app/ 文件夹相关联,所以 composer 将尝试使用基本的字符串操作过程将 PSR-4 类名转换为文件名。最后,它猜测 App\Controllers\AuthController 必须位于 AuthController.php 文件中,它位于 Controllers/ 文件夹中,恰巧的是,该文件夹正好位于名称空间文件夹中,即 app/。

所有这些艰苦的工作只是为了得到 App\Controllers\AuthController 类存在于 app/Controllers/AuthController.php 文件中。为了让 composer 扫描整个应用程序并创建类和文件的直接 1 对 1 关联,运行以下命令:

composer dumpautoload -o

请记住,如果您已经运行了 php artisan optimize --force,那么您就不必再运行这个函数了。因为优化命令已经告诉 composer 创建一个优化的自动加载器。

JIT 编译器(即时编译器)

PHP 并不是天然就被计算机理解的。你不能把它编译为字节码然后让计算机运行。PHP 必须要经过一个中介,像是 Zend 引擎,它会解释 PHP 文件并执行相应的 C 例程。如你所想,它的速度很慢。每次你的服务器执行一个 PHP 文件,都必须把它转换成 tokens —— 这个过程由 AST 解析器完成并解释。不幸的是,解析器必须每次都编译 PHP 文件,即使它每次都得到相同的结果。

为了让你的应用速度更快,你需要一个 编译一次,终生运行 的方法,而这就是一个 JIT 编译器所做的事情。

对于 Laravel 所推荐使用的 JIT 编译器是 HHVM,由 Facebook 创立并广泛使用。Wikipedia、Etsy 和其他上千项目也在使用它。

使用更快的缓存和会话驱动

将 session 保存在文件中是种足够快速而又优雅的方法,自 PHP 开始的时代就在这样做了。但是如果你追求性能,那么文件系统就是你需要注意的一件事,因为它很慢。一种更好的做法是将 cache 和 session 存储在内存中,因为它提供了一种高效读写数据的方式。幸运的是,laravel 支持一些基于内存的 cache 和 session 驱动。

我的建议是使用 memcached 作为 cache 和 session 的驱动,但你可以选择任何你喜欢的,只要它是基于内存工作的。

要更改 session 驱动,需要检查以下文件中「driver」项:

app/config/session.php

要更改 cache 驱动,需要检查以下文件中「driver」项:

app/config/cache.php

不要低估通过优化查询语句带来的查询速度的提升
就像你看到的,大部分优化都是在不同的层面使用缓存。但当面临数据库优化时,你不应该依赖缓存。缓存应是优化查询的最后手段。

缓存查询结果

MySQL 不会替你做这件事,也不如你自己做的好。当然了你肯定不会把应用中每个查询的结果都做缓存,看看数据统计,在应用程序中那些高频率的查询语句,它们真的有必要被频繁地执行?每 15 分钟运行一次然后把相同的结果提供给用户不是更好吗?

在查询构造器中移除了 removing方法是件好事(它曾经是个很好的功能,但不够好 - 人们似乎高估了它的作用)。然后你可以更多地使用 Cache::remember 方法,就像这样:

$posts = Cache::remember('index.posts', 30, function()

{

return Post::with('comments', 'tags', 'author', 'seo')->whereHidden(0)->get();

});
PHP 相关文章推荐
上传多个文件的PHP脚本
Nov 26 PHP
Windows7下PHP开发环境安装配置图文方法
May 20 PHP
php中关于codeigniter的xmlrpc的类在进行数据交换时的类型问题
Jul 03 PHP
php类中private属性继承问题分析
Nov 01 PHP
10个php函数实用却不常见
Oct 13 PHP
PHP错误处理函数
Apr 03 PHP
PHP的全局错误处理详解
Apr 25 PHP
php提交过来的数据生成为txt文件
Apr 28 PHP
PHP入门教程之面向对象基本概念实例分析
Sep 11 PHP
php 使用html5实现多文件上传实例
Oct 24 PHP
PHP经典实用正则表达式小结
May 04 PHP
Laravel框架实现定时Task Scheduling例子
Oct 22 PHP
PHP二维索引数组的遍历实例分析【2种方式】
Jun 24 #PHP
PHP中的self关键字详解
Jun 23 #PHP
php面向对象程序设计入门教程
Jun 22 #PHP
PHP字符串中抽取子串操作实例分析
Jun 22 #PHP
微信公众号之主动给用户发送消息功能
Jun 22 #PHP
Yii 使用intervention/image拓展实现图像处理功能
Jun 22 #PHP
PHP实现给定一列字符,生成指定长度的所有可能组合示例
Jun 22 #PHP
You might like
ob_start(),ob_start('ob_gzhandler')使用
2006/12/25 PHP
thinkPHP模板中for循环与switch语句用法示例
2016/11/30 PHP
PHP程序员简单的开展服务治理架构操作详解(一)
2020/05/14 PHP
读jQuery之十四 (触发事件核心方法)
2011/08/23 Javascript
event.currentTarget与event.target的区别介绍
2012/12/31 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
2013/01/23 Javascript
js改变鼠标的形状和样式的方法
2014/03/31 Javascript
Highcharts使用简例及异步动态读取数据
2015/12/30 Javascript
JavaScript中eval函数的问题
2016/01/31 Javascript
JavaScript获取图片像素颜色并转换为box-shadow显示
2016/03/11 Javascript
总结jQuery插件开发中的一些要点
2016/05/16 Javascript
深入理解javascript函数参数与闭包
2016/12/12 Javascript
微信小程序实战之自定义toast(6)
2017/04/18 Javascript
Canvas放置反弹效果随机图形(实例)
2017/08/17 Javascript
vue组件发布到npm简单步骤
2017/11/30 Javascript
取消Bootstrap的dropdown-menu点击默认关闭事件方法
2018/08/10 Javascript
Bootstrap-table自定义可编辑每页显示记录数
2018/09/07 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
2020/07/22 Javascript
基于JQuery和DWR实现异步数据传递
2020/10/16 jQuery
Python聚类算法之凝聚层次聚类实例分析
2015/11/20 Python
python中的迭代和可迭代对象代码示例
2017/12/27 Python
python opencv将图片转为灰度图的方法示例
2019/07/31 Python
python GUI库图形界面开发之PyQt5多线程中信号与槽的详细使用方法与实例
2020/03/08 Python
python requests包的request()函数中的参数-params和data的区别介绍
2020/05/05 Python
使用已经得到的keras模型识别自己手写的数字方式
2020/06/29 Python
个人能力自我鉴赏
2014/01/25 职场文书
部门年终奖分配方案
2014/05/07 职场文书
大学生党员个人对照检查材料范文
2014/09/25 职场文书
学校班子个人对照检查材料思想汇报
2014/09/27 职场文书
2014年中学生检讨书大全
2014/10/09 职场文书
市场部岗位职责
2015/02/12 职场文书
好人好事新闻稿
2015/07/17 职场文书
2016大学生暑期三下乡心得体会
2016/01/23 职场文书
七年级英语教学反思
2016/02/15 职场文书
高中生物教学反思
2016/02/20 职场文书
如何利用 CSS Overview 面板重构优化你的网站
2021/10/24 HTML / CSS