本文提到的typo版本是目前最新的5.0.3.98.1,theme_support版本是1.3.0。在typo中,我们看到了很好很花哨的换肤机制,而theme_support则是从typo中抽取出来的一个plugin,以供其他程序进行换肤操作。
先简单介绍下typo换肤的使用。typogarden提供了typo十分丰富的皮肤,我们只需要下载喜欢的皮肤,解压,放在typo程序根目录的theme目录下即可,大致的结构图如下所示:
然后,就可以在admin界面选择自己的皮肤。的确十分方便。但是,使用这种机制,会存在一个严重的性能问题,下面将详细分析问题的原理及其我目前所知的解决方案。
通常,我们会将程序的图片,css等与皮肤相关的文件放在网站的public目录下,在view中直接引用即可。但是从上图我们可以看到,typo将新皮肤的所有相关文件都存放在theme目录下的各个子目录下。那么typo是如何引用这些文件的呢?下面,我们随便打开某一个皮肤下面的layout文件,例如theme/typographic/layouts下面的default.html.erb文件,可以看到如下代码:
<%= stylesheet_link_tag '/stylesheets/theme/style.css', :media => 'all' %>
你仔细搜查一下程序,绝对发现不了/stylesheets/theme目录,乱引用?当然不是,我们可以在routes.rb中发现如下的route信息:
get.with_options(:controller => 'theme', :filename => /.*/, :conditions => {:method => :get}) do |theme|
theme.connect 'stylesheets/theme/:filename', :action => 'stylesheets'
theme.connect 'javascripts/theme/:filename', :action => 'javascript'
theme.connect 'images/theme/:filename', :action => 'images'
end
很经典的route配置,原来在typo中,所有对css,javascript,image的引用,不是通过直接引用public目录下的文件,而是通过一个传统的controller:ThemeController来完成的。至于ThemeContorller具体代码,这里不详细谈,因为不是本文的重点,无非就是根据当前选择的皮肤(在admin界面选择的),到相应的皮肤目录(比如:theme/typographic)下,将各个文件找到,然后通过send_file的方式发送到客户端浏览器。那执行完一次action后,controller到底应该执行怎么样的render操作呢?(通过上图,我们看到不同的view文件,在各自的theme子目录下)
在ApplicationController中,有如下代码:
class ApplicationController < ActionController::Base
......
def setup_themer
# Ick!
self.view_paths = ::ActionController::Base.view_paths.dup.unshift("#{RAILS_ROOT}/themes/#{this_blog.theme}/views")
end
end
大致讲下,setup_themer方法的作用是根据目前皮肤配置(this_blog.theme),将controller的view_paths设置为某一个皮肤的目录(比如:theme/typographic/views),这样,在执行render操作的时候,将使用皮肤目录下的view,layout等等(还记得前面提到的layout中引用css的方法么?重要!)。并且,将setup_themer方法设置为需要换肤的contorller的before_filter。于是,当我们执行程序的时候,就可以达到动态换肤的目的。
大致原理如是。。。
前面我讲了,这种机制会存在一个严重的性能问题,是怎么来的呢?在传统方式下,我们将css,images,js都放在public目录下,view进行引用的时候,在web服务器层面,就完成了文件的引用,发送操作。但是在typo这种机制下,每引用一个css,图片,js,web服务器会将请求route到rails,通过rails的ThemeController来处理请求,返回文件。这都还算小事,在一次request,response周期,这样一个额外操作往往占用不了多大的百分比。但是,我们知道ThemeController是rails中一个普通的Controller,它也继承自ApplicationController。通常,我们会将很多程序通用逻辑放在ApplicationController中来做,比如:验证用户合法性,处理本地化等等,而这些操作,大部分都是访问数据库。也就是说,我们通过ThemeController,仅仅想得到一个css或者图片文件,但是ApplicationController仍然会初始化,执行相应的操作(重复,无用的操作)。这就是性能问题的根源。口说无凭,下面的数据揭示了一切:
上面两个性能测试是我随机访问一次typo首页得到的,我们可以看到,对css,image,js的请求,耗费了数十毫秒的操作。为什么请求一个css会耗费如此多时间呢?从下面的图中,我们可以看到原因:
Oh~My god!我出来打个酱油而已,咋搞出个db访问占用了这么长的周期?原因就是我前面提到的,访问ThemeController的时候,ApplicationContorller偷偷摸摸的作祟着(执行了一些业务逻辑的操作,用户验证等)。具体执行的多余db操作如下图所示:
什么show tables,select blogs,select triggers之类操作啊~我请求一个css,何必呢?
性能问题的原因分析完毕!不要忘了,我举例的这些简单的皮肤中,只是简单的十几个css,js,images等。如果你真的使用这种机制在自己的程序中,我想,一个稍微复杂点的皮肤不止十个图片文件。加入我们要在皮肤中引用数十个此类文件,那么性能问题将是十分严重的。
目前,我找到三个解决方案处理这个性能问题。
1. 在ApplicationController中,执行某些业务逻辑的时候,判断一下controller,如果是ThemeController,则跳过。这样做的好处是不用变动typo中换肤方法的使用,仍然将皮肤放在theme目录下即可。但是,这样做似乎“侵入性”太强,仅仅为了一个皮肤,修改业务逻辑,实在有些得不偿失,因此,这种方案不是一个很好的方案。
2. 要想不影响已有的业务逻辑解决这个性能问题,我们则需要手动做一些修改。将某一个皮肤放到theme目录下以后,我们收到将css,image,js拷贝到public的相应目录下。比如:将theme/typographic/stylesheets下的所有css文件拷贝到public/stylesheets/typographic目录下,然后,手动将皮肤中所有对css的引用修改为引用public下面相应的目录,比如:我将前面提到的default.html.erb中对css的引用修改为如下所示:
<%= stylesheet_link_tag 'typographic/style.css', :media => 'all' %>
然后,将关于theme的roues信息全部删除,让web server为我们完成这个工作。这样,既能解决性能问题,还不影响业务逻辑。只不过,需要不少的手动工作(要将皮肤中所有关于css,js,images的引用修改到public目录下)。
3. 一劳永逸,按照第二种方法重写theme_support plugin。。。
这里,我按照第二种方法修改了typo的theme机制,主观上来讲,页面访问速度有不小的改进,不像原来,进度条象个蚂蚁一样一耸一耸的~最后,客观起见,还是来一张修改后的性能测试结果:
整个世界清静了不少~不是吗?:)
2008.7.17 23:30 星期四
分享到:
相关推荐
红遍德国的建站系统,欧美外包常用的,typo3_4.16_stable-all.rar
Typo3内容管理系统,是基于PHP4/PHP5+MYsql的内容管理系统(框架)(CMS/CMF),兼容PHP4和PHP5.数据库系统除Mysql之外,也能运行于Oracle, MS-SQL, ODBC, LDAP 等其它数据库系统,支持Typo3的服务器系统:Apache或者IIS...
【Typo3 CMS系统概述】 Typo3是一款开源的内容管理系统(CMS),以其强大的功能和高度的可扩展性闻名。在4.2.5版本中,Typo3提供了丰富的功能,适用于构建复杂的网站和企业级应用。这个版本是该系统发展历史上的一...
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...
TYPO3扩展typo3_image_proxy typo3_image_proxy是TYPO3 CMS的扩展。 它将您上传的图片发送到托管或容器化的ImgProxy服务以调整图像大小。1特点在TYPO3中上传时调整图片大小2用法2.1安装使用Composer安装推荐的扩展...
**Typo3 CMS系统介绍** Typo3是一款开源的内容管理系统(CMS),专为构建复杂的、企业级的网站而设计。它的灵活性和可扩展性使其在众多CMS中脱颖而出,尤其适合大型组织和机构使用。该系统提供了强大的内容编辑、...
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...
4. **Python库**:这确认了`typo_pypi`是一个用Python编写的库,可以被其他Python项目导入和使用,提供了特定功能,比如与Zookeeper的接口或者分布式系统的管理工具。 根据提供的压缩包子文件名称列表"typo_pypi-...
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...
docs.typo3.org的Sphinx TYPO3主题 Sphinx TYPO3主题包含构建提供该主题的Sphinx扩展所需的所有文件。 维护者:Martin Bless < > 由TYPO3文档团队提供。 免费软件:MIT许可证 作者:请参阅AUTHORS.rst 仓库...
em_tvplus_theme_demoTYPO3TemplaVoilà的演示主题! 加v8 + 演示截至2020年12月19日的模板状态,该状态显示: 子页面作为菜单页面的第一个媒体元素作为徽标页面标题为h1-tag fluid_styled_content内容元素pages_...
标题中的“typo3 tt_news插件动画演示”指出,我们即将探讨的是关于TYPO3内容管理系统中的一个插件——tt_news的使用,并且这个讲解将以动画的形式呈现,帮助用户更直观地理解操作流程。 TYPO3是一款开源的企业级...
TYPO3与Webpack Encore集成! 通过此扩展,您可以通过阅读entrypoints.json文件并帮助您呈现所需的所有动态script和link标签来使用的splitEntryChunks()功能。 composer require ssch/typo3-encore如何使用首先按照...
jarvisoj_typo,arm架构下的pwn题。