https://www.yiiframework.com/doc/guide/2.0/zh-cn/tutorial-performance-tuning

性能优化

有许多因素影响你的 Web 应用程序的性能。有些是环境, 有些是你的代码,而其他一些与 Yii 本身有关。 在本节中,我们将列举这些因素并解释如何通过调整这些因素来提高应用程序的性能。

优化你的 PHP 环境

一个好的 PHP 环境是非常重要的。为了得到最大的性能,

  • 使用最新稳定版本的 PHP。 PHP 的主要版本可能带来显著的性能提升。
  • 启用字节码缓存 Opcache(PHP 5.5或更高版本) 或 APC (PHP 5.4或更早版本)。字节码缓存省去了每次解析和加载 PHP 脚本所带来的开销。
  • Tune realpath() cache.

禁用调试模式

对于运行在生产环境中的应用程序,你应该禁用调试模式。 Yii 中使用名为 YII_DEBUG 的常量来定义调试模式是否应被激活。 若启用了调试模式,Yii 将需要额外的时间来产生和记录调试信息。

你可以将下面的代码行放在 入口脚本 的开头来禁用调试模式:

defined('YII_DEBUG') or define('YII_DEBUG', false);

提示: YII_DEBUG 的默认值是 false 。所以如果你确信你不在你应用程序代码中别的地方更改其默认值, 你可以简单地删除上述行来禁用调试模式。

使用缓存技术

你可以使用各种缓存技术来提高应用程序的性能。例如,如果你的应用程序允许用户以 Markdown 格式输入文字, 你可以考虑缓存解析后的 Markdown 内容,避免每个请求都重复解析相同的 Markdown 文本。 请参阅 缓存 一节, 了解 Yii 提供的缓存支持。

开启 Schema 缓存

Schema 缓存是一个特殊的缓存功能, 每当你使用活动记录时应该要开启这个缓存功能。如你所知, 活动记录能智能检测数据库对象的集合(例如列名、列类型、约束)而不需要手动地描述它们。 活动记录是通过执行额外的 SQL 查询来获得该信息。 通过启用 Schema 缓存,检索到的数据库对象的集合将被保存在缓存中并在将来的请求中重用。

要开启 Schema 缓存,需要配置一个 cache 应用组件来储存 Schema 信息, 并在 配置 中设置 yii\db\Connection::$enableSchemaCache 为 true :

return [
// ...
'components' => [
// ...
'cache' => [
'class' => 'yii\caching\FileCache',
],
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=mydatabase',
'username' => 'root',
'password' => '',
'enableSchemaCache' => true, // Duration of schema cache.
'schemaCacheDuration' => 3600, // Name of the cache component used to store schema information
'schemaCache' => 'cache',
],
],
];

合并和压缩资源文件

一个复杂的网页往往包括许多 CSS 和 JavaScript 资源文件。 为减少 HTTP 请求的数量和这些资源总下载的大小,应考虑将它们合并成一个单一的文件并压缩。 这可大大提高页面加载时间,且减少了服务器负载。 想了解更多细节,请参阅前端资源部分。

优化会话存储

默认会话数据被存储在文件中。 这是好的对处于发展项目或小型项目。 但是,当涉及要处理大量并发请求时, 最好使用其他的会话存储方式,比如数据库。 Yii 支持各种会话存储。 你可以通过在配置中配置 session 组件来使用这些存储, 如下代码:

return [
// ...
'components' => [
'session' => [
'class' => 'yii\web\DbSession', // Set the following if you want to use DB component other than
// default 'db'.
// 'db' => 'mydb', // To override default session table, set the following
// 'sessionTable' => 'my_session',
],
],
];

以上配置是使用数据库来存储会话数据。默认情况下, 它会使用 db 应用组件连接数据库并将会话数据存储在 session 表。 因此,你必须创建如下的 session 表,

CREATE TABLE session (
id CHAR(40) NOT NULL PRIMARY KEY,
expire INTEGER,
data BLOB
)

你也可以通过使用缓存来存储会话数据 yii\web\CacheSession 。 理论上讲,你可以使用只要支持数据缓存。 但是请注意,某些缓存的存储当达到存储限制会清除缓存数据。出于这个原因,你应主要在不存在存储限制时才使用这些缓存存储。 如果你的服务器支持 Redis,强烈建议你通过使用 yii\redis\Session 来作为会话存储。

如果您的服务器上有 Redis, 强烈建议您使用 yii\redis\Session 作为会话存储。

优化数据库

执行数据库查询并从数据库中取出数据往往是一个 Web 应用程序主要的性能瓶颈。 尽管使用数据缓存技术可以缓解性能下降,但它并不完全解决这个问题。 当数据库包含大量的数据且缓存数据是无效的, 获取最新的数据可能是最耗性能的假如在没有适当地设计数据库和查询条件。

一般来说,提高数据库查询的性能是创建索引。例如,如果你需要找一个用户表的“用户名”, 你应该为“用户名”创建一个索引。 注意,尽管索引可以使选择查询的速度快得多,但它会减慢插入、更新和删除的查询。

对于复杂的数据库查询,建议你创建数据库视图来保存查询分析和准备的时间。

最后,在“SELECT”中使用“LIMIT”查询。 这可以避免从数据库中取出大量数据。

使用普通数组

尽管活动记录对象使用起来非常方便, 但当你需要从数据库中检索大量数据时它的效率不如使用普通的数组。 在这种情况下,你可以考虑在使用活动记录查询数据时调用 asArray(), 使检索到的数据被表示为数组而不是笨重的活动记录对象。例如,

class PostController extends Controller
{
public function actionIndex()
{
$posts = Post::find()->limit(100)->asArray()->all(); return $this->render('index', ['posts' => $posts]);
}
}

在上述代码中,$posts 将被表中的行填充形成数组。每一行是一个普通的数组。要访问 第 i 行的 title 列,你可以使用表达式 $post[$i]['title']

你也可以使用 DAO 以数组的方式来构建查询和检索数据。

优化 Composer 自动加载

因为 Composer 自动加载用于加载大多数第三方类文件, 应考虑对其进行优化,通过执行以下命令:

composer dumpautoload -o

另外,您可以考虑使用 authoritative class maps 和 APCu 缓存。 请注意,这两种选择可能适用于您的特定情况,也可能不适合您。

处理离线数据

当一个请求涉及到一些资源密集操作, 你应该想办法在无需用户等待他们完成脱机模式时来执行这些操作。

有两种方法可以离线数据处理:推和拉。

在拉中,只要有请求涉及到一些复杂的操作,你创建一个任务,并将其保存在永久存储,例如数据库。然后, 使用一个单独的进程(如 cron 作业)拉任务,并进行处理。 这种方法很容易实现,但它也有一些缺点。 例如,该任务过程中需要定期地从任务存储拉。如果拉频率太低,这些任务可以延迟处理; 但是如果频率过高,将引起的高开销。

在推中,你可以使用消息队列(如 RabbitMQ ,ActiveMQ , Amazon SQS 等)来管理任务。 每当一个新的任务放在队列中,它会启动或者通知任务处理过程去触发任务处理。

性能分析

你应该配置你的代码来找出性能缺陷,并相应地采取适当措施。 以下分析工具可能是有用的:

准备扩展应用程序

当没有任何帮助时,您可以尝试使您的应用程序可扩展。Configuring a Yii2 Application for an Autoscaling Stack 中提供了一个很好的介绍。有关进一步阅读,请参阅 Web apps performance and scaling.

Yii2性能优化的更多相关文章

  1. Yii2 性能优化 来源yii2官方文档

    优化你的 PHP 环境 使用最新稳定版本的 PHP . PHP 的主要版本可能带来显著的性能提升. 启用字节码缓存 Opcache(PHP 5.5或更高版本) 或 APC (PHP 5.4或更早版本) ...

  2. 缓存技术之——Yii2性能优化之:缓存依赖

    Yii中的缓存依赖,简单来说就是将缓存和另外一个东西绑定在一起,如果另外一个东西发生变化,那么缓存也将发生变化.有点儿类似于JS中的触发事件(但是也不那么像),缓存的变动是依赖的东西所导致的. 依赖可 ...

  3. 01.SQLServer性能优化之----强大的文件组----分盘存储

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...

  4. 03.SQLServer性能优化之---存储优化系列

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 概  述:http://www.cnblogs.com/dunitian/p/60413 ...

  5. Web性能优化:What? Why? How?

    为什么要提升web性能? Web性能黄金准则:只有10%~20%的最终用户响应时间花在了下载html文档上,其余的80%~90%时间花在了下载页面组件上. web性能对于用户体验有及其重要的影响,根据 ...

  6. Web性能优化:图片优化

    程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...

  7. C#中那些[举手之劳]的性能优化

    隔了很久没写东西了,主要是最近比较忙,更主要的是最近比较懒...... 其实这篇很早就想写了 工作和生活中经常可以看到一些程序猿,写代码的时候只关注代码的逻辑性,而不考虑运行效率 其实这对大多数程序猿 ...

  8. JavaScript性能优化

    如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...

  9. 02.SQLServer性能优化之---牛逼的OSQL----大数据导入

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 上一篇:01.SQLServer性能优化之----强大的文件组----分盘存储 http ...

随机推荐

  1. PPP

    名称 chat–调制解调器的自动对话脚本 命令格式 chat [options] script 描述 Chat程序定义了一个计算机和调制解调器之间对话交流,其主要目的是用来在本地PPPD和远端PPPD ...

  2. Redis中的缓存雪崩与缓存穿透

    1.缓存雪崩 1.1什么是缓存雪崩? 如果我们的缓存挂掉了,这意味着我们的全部请求都跑去数据库了. 我们都知道Redis不可能把所有的数据都缓存起来(内存昂贵且有限),所以Redis需要对数据设置过期 ...

  3. USACO10FEB]慢下来Slowing down dfs序 线段树

    [USACO10FEB]慢下来Slowing down 题面 洛谷P2982 本来想写树剖来着 暴力数据结构直接模拟,每头牛回到自己的农场后,其子树下的所有牛回到农舍时,必定会经过此牛舍,即:每头牛回 ...

  4. Cogs 56. 质数取石子(博弈)

    质数取石子 ★★ 输入文件:stonegame.in 输出文件:stonegame.out 简单对比 时间限制:1 s 内存限制:128 MB 问题描述 DD 和 MM 正在玩取石子游戏.他们的游戏规 ...

  5. I9300 国行联通定制修复手记

    同事拿来个I9300给我修,说是打不了电话,试了一下,打电话的时候会提示“网络未注册”,于是果断找了个国行的4.1.2五件套刷砖.5分钟后,刷机成功,开机拨号,依旧是这个问题,怎么回事呢?上百度一查, ...

  6. 最长公共子序列 DP

    class Solution: def LCS(self,A,B): if not A or not B: #边界处理 return 0 dp = [[0 for _ in range(len(B)+ ...

  7. python中range语法

    规则:一般不取最后一位 start: 计数从 start 开始.默认是从 0 开始.例如range(5)等价于range(0, 5); stop: 计数到 stop 结束,但不包括 stop.例如:r ...

  8. Django基础(2)-如何安装特定版本的Django项目

    Django1.0版本和2.0版本的差异较大,这里jacky更常用的Django的1.9.8的版本,本小节jacky将给大家分享如何用Pycharm创建1.9.8版本的项目 (一)使用Pycharm配 ...

  9. comobox在datagrid里,当滚动scrollbar时,会导致comobox选中项被重置的解决办法

    VirtualizingStackPanel.IsVirtualizing="False"

  10. 重写mybatis的字符串类型处理器

    1.简介 无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型. St ...