directory search
阅读前篇 简介 Yii 是什么 从 Yii 1.1 升级 入门 安装 Yii 运行应用 第一次问候 使用Forms 数据库应用 使用 Gii 生成代码 进阶 应用结构 概述 入口脚本 应用(Applications) 应用组件(Application Components) 控制器(Controllers) 模型(Models) 视图(views) 模块(Modules) 过滤器(Filters) 小部件(Widgets) 前端资源(Assets) 扩展(Extensions) 请求处理 运行概述 启动引导(Bootstrapping) 路由和创建URL 请求(Requests) 响应(Responses) Sessions 和 Cookies 错误处理(Handling Errors) 日志(Logging) 关键概念 组件(Component) 属性(Property) 事件(Events) 行为(Behaviors) 配置(Configurations) 别名(Aliases) 类自动加载(Autoloading) 服务定位器(Service Locator) 依赖注入容器(Dependency Injection Container) 配合数据库工作 数据库访问 (Data Access Objects) 查询生成器(Query Builder) 活动记录(Active Record) 数据库迁移(Migrations) Sphinx Redis MongoDB Elasticsearch 接收用户数据 创建表单(Creating Forms) 输入验证(Validating Input) 文件上传(Uploading Files) 收集列表输入(Collecting Tabular Input) 多模型的复合表单(Getting Data for Multiple Models) 显示数据 格式化输出数据(Data Formatting) 分页(Pagination) 排序(Sorting) 数据提供器(Data Providers) 数据小部件(Data Widgets) 客户端脚本使用(Working with Client Scripts) 主题(Theming) 安全 认证(Authentication) 授权(Authorization) 处理密码(Working with Passwords) 客户端认证(Auth Clients) 最佳安全实践(Best Practices) 缓存 概述 数据缓存 片段缓存 页面缓存 HTTP 缓存 RESTfull Web服务 快速入门(Quick Start) 资源(Resources) 控制器(Controllers) 路由(Routing) 格式化响应(Response Formatting) 授权认证(Authentication) 速率限制(Rate Limiting) 版本(Versioning) 错误处理(Error Handling) 开发工具 调试工具栏和调试器 使用Gii生成代码 生成API文档 测试 概述(Overview) 配置测试环境(Testing environment setup) 单元测试(Unit Tests) 功能测试(Function Tests) 验收测试(Acceptance Tests) 测试夹具(Fixtures) 高级专题 高级应用模板 创建自定义应用程序结构 控制台命令 核心验证器(Core Validators) 国际化 收发邮件 性能优化 共享主机环境 模板引擎 集成第三方代码 小部件 Bootstrap 小部件 Jquery UI 助手类 概述 Array 助手(ArrayHelper) Html 助手(Html) Url 助手(Url)
characters

性能优化

性能优化

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

优化你的 PHP 环境

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

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

禁用调试模式

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

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

defined('YII_DEBUG')ordefine('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表,

CREATETABLEsession(idCHAR(40)NOTNULLPRIMARYKEY,expireINTEGER,dataBLOB)

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

优化数据库

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

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

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

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

使用普通数组

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

classPostControllerextendsController{publicfunctionactionIndex(){$posts= Post::find()->limit(100)->asArray()->all();return$this->render('index', ['posts'=>$posts]); } }

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

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

优化 Composer 自动加载

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

composerdumpautoload -o

处理离线数据

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

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

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

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

性能分析

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

  • Yii debug toolbar and debugger
  • XDebug profiler
  • XHProf
Previous article: Next article: