`
woody_420420
  • 浏览: 42068 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

慎用typo(theme_support)的换肤机制

阅读更多
  • 前言

  本文提到的typo版本是目前最新的5.0.3.98.1,theme_support版本是1.3.0。在typo中,我们看到了很好很花哨的换肤机制,而theme_support则是从typo中抽取出来的一个plugin,以供其他程序进行换肤操作。
  先简单介绍下typo换肤的使用。typogarden提供了typo十分丰富的皮肤,我们只需要下载喜欢的皮肤,解压,放在typo程序根目录的theme目录下即可,大致的结构图如下所示:

  然后,就可以在admin界面选择自己的皮肤。的确十分方便。但是,使用这种机制,会存在一个严重的性能问题,下面将详细分析问题的原理及其我目前所知的解决方案。

  • Typo的换肤原理

  通常,我们会将程序的图片,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  星期四

分享到:
评论
12 楼 tiaohai 2009-04-16  
tiaohai 写道
正在思考这方面的问题,改了一个theme后,竟然出现500错误,反复看了后台log,可能就是这个机制惹的祸害,还在测试中。

测试完毕,在后台修改blogs表恢复themes设置后正常!找得我好辛苦 
11 楼 tiaohai 2009-04-16  
正在思考这方面的问题,改了一个theme后,竟然出现500错误,反复看了后台log,可能就是这个机制惹的祸害,还在测试中。
10 楼 yza0088 2009-02-17  
不错,学习了,但好像typo-5.2仍然没有改变啊
看来typo团队没有看楼主的帖子
9 楼 冉翔 2008-07-18  
woody_420420 写道
liusong,我没搞懂你什么意思~能详细点么?


二大爷说话就素这个样子,你搞啊搞啊滴就明白鸟。
8 楼 woody_420420 2008-07-18  
是的。typo这个机制其实还是不错的。关键问题就是css,images,js引用问题。
不过你说的“stylesheet_link_tag_with_theme”也不错,我们可以自己写一个,然后在每一个皮肤的layout中使用,就不用每次都"../../public/..."了。
enjoy ubuntu~~:)
7 楼 liusong1111 2008-07-18  
woody_420420 told me:
Each theme has an individual layout file, and it operates views_path to switch between them.
so, no need to rewrite/enhance stylesheet_include_tag helper.

di, could you introduce views_path for us?

sorry, can't input Chinese.
6 楼 woody_420420 2008-07-18  
liusong,我没搞懂你什么意思~能详细点么?
5 楼 liusong1111 2008-07-18  
crazy!

<%= stylesheet_link_tag 'style.css', :theme =>:auto %>
 
or
<%= stylesheet_link_tag_with_theme 'style.css' %>  

enhance stylesheet_link_tag helper.

are they enough?
4 楼 jinjiankang 2008-07-18  
请教楼主:文中关于性能测试,你使用的是什么工具。烦请回复到:jinjiankang1980@gmail.com 谢谢。我没有找到你的email。不喜欢用javaeye系统自带的邮件系统。
3 楼 qichunren 2008-07-18  
好像目前对于rails中的换肤,我所看到的只有theme_support插件,我用了它,感觉比没有是慢一些,不爽.

不过我想对于网站换肤,如果只有想改一下网站总体色调什么的,那么只需要引用不同的css样式文件即可啊,没有必要搞得这么麻烦.
2 楼 woody_420420 2008-07-18  
没办法,人笨,只能把别人觉得简单的东西详细记录下来。
不过,你要把图片去掉,似乎也不怎么“大”,是不是应该放“贴图区”去阿?呵呵
1 楼 系统程序 2008-07-18  
晕,很简单的一点点东西竟然让你写出这么大一篇来

相关推荐

    外包常用建站系统:typo3_4.16_stable-all

    红遍德国的建站系统,欧美外包常用的,typo3_4.16_stable-all.rar

    typo3_CMS_v9.5.0

    Typo3内容管理系统,是基于PHP4/PHP5+MYsql的内容管理系统(框架)(CMS/CMF),兼容PHP4和PHP5.数据库系统除Mysql之外,也能运行于Oracle, MS-SQL, ODBC, LDAP 等其它数据库系统,支持Typo3的服务器系统:Apache或者IIS...

    [CMS程序]Typo3 4.2.5_typo3_src-4.2.5.zip

    【Typo3 CMS系统概述】 Typo3是一款开源的内容管理系统(CMS),以其强大的功能和高度的可扩展性闻名。在4.2.5版本中,Typo3提供了丰富的功能,适用于构建复杂的网站和企业级应用。这个版本是该系统发展历史上的一...

    [CMS程序]Typo3 4.2.5_typo3_src-4.2.5.rar

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...

    typo3_image_proxy:借助img-proxy作为外部服务调整TYPO3图像的大小

    TYPO3扩展typo3_image_proxy typo3_image_proxy是TYPO3 CMS的扩展。 它将您上传的图片发送到托管或容器化的ImgProxy服务以调整图像大小。1特点在TYPO3中上传时调整图片大小2用法2.1安装使用Composer安装推荐的扩展...

    [CMS程序]Typo3 dummy 4.110 (集成后台简体中文语言包)(PHP4+)_typo3_src4.zip

    **Typo3 CMS系统介绍** Typo3是一款开源的内容管理系统(CMS),专为构建复杂的、企业级的网站而设计。它的灵活性和可扩展性使其在众多CMS中脱颖而出,尤其适合大型组织和机构使用。该系统提供了强大的内容编辑、...

    Typo3 4.2.5_typo3_src-4.2.5_CMS程序开发模板(使用说明+源代码+html).zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...

    基于CMS实现的Typo3 4.2.5_typo3_src-4.2.5(使用说明+源代码+html+毕业设计).zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...

    PyPI 官网下载 | typo_pypi-0.1.4.tar.gz

    4. **Python库**:这确认了`typo_pypi`是一个用Python编写的库,可以被其他Python项目导入和使用,提供了特定功能,比如与Zookeeper的接口或者分布式系统的管理工具。 根据提供的压缩包子文件名称列表"typo_pypi-...

    基于CMS实现的Typo3 v4.05 简体中文版_typo3_4(使用说明+源代码+html).zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...

    [CMS程序]Typo3 dummy 4.110 (集成后台简体中文语言包)(PHP4+)_typo3_src4.rar

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。...【项目质量】:所有源码都经过严格测试,可以直接...

    sphinx_typo3_theme:docs.typo3.org的Sphinx主题

    docs.typo3.org的Sphinx TYPO3主题 Sphinx TYPO3主题包含构建提供该主题的Sphinx扩展所需的所有文件。 维护者:Martin Bless &lt; &gt; 由TYPO3文档团队提供。 免费软件:MIT许可证 作者:请参阅AUTHORS.rst 仓库...

    em_tvplus_theme_demo:TYPO3TemplaVoilà的演示主题! 加v8 +

    em_tvplus_theme_demoTYPO3TemplaVoilà的演示主题! 加v8 + 演示截至2020年12月19日的模板状态,该状态显示: 子页面作为菜单页面的第一个媒体元素作为徽标页面标题为h1-tag fluid_styled_content内容元素pages_...

    typo3 tt_news插件动画演示

    标题中的“typo3 tt_news插件动画演示”指出,我们即将探讨的是关于TYPO3内容管理系统中的一个插件——tt_news的使用,并且这个讲解将以动画的形式呈现,帮助用户更直观地理解操作流程。 TYPO3是一款开源的企业级...

    typo3_encore:在TYPO3中使用Webpack Encore

    TYPO3与Webpack Encore集成! 通过此扩展,您可以通过阅读entrypoints.json文件并帮助您呈现所需的所有动态script和link标签来使用的splitEntryChunks()功能。 composer require ssch/typo3-encore如何使用首先按照...

    jarvisoj_typo

    jarvisoj_typo,arm架构下的pwn题。

Global site tag (gtag.js) - Google Analytics