让您的 web 应用程序飞起来

本文向您介绍如何通过在您的 CSS 和 JavaScript 文件中 — 两种易于优化的常见资源,使用社区中提供的工具即可完成优化 — 优化空间使用来实现更高的性能。然而,在继续之前,有一点是很重要的,压缩 CSS 和 JavaScript 文件只是为了让您的 web 应用程序 “轻巧” 的诸多操作其中的两个技术。关于优化其他资源(比如,HTML 和图像)的 技术,参阅 参考资料 获取更多信息。

为了从本文中获得最大收益,您需要安装下列工具:

  • 一个文本编辑器
  • Java™ Runtime Environment 1.4 或者更新版本(见 参考资料

问题:空白内容

当开发人员使用 CSS 或 JavaScript 文件工作时,空白内容通常是一件好事。空白内容包括缩进文件所使用的字符,增强可读性的间距、以及为了在文章的不同部分添加一个可视间隔而插入的额外空行。空白内容使文件易于阅读和维护。考虑 清单 2 中的 CSS 文件,其中有适当数量的空白内容(和注释),有助于开发人员理解 CSS 代码的意图。

从这一点上来说,将文件变得更小作为问题的一个长期解决方案是不可行的,因为文件很有可能在将来会被修改。如果将空白内容和注册全部删除,CSS 和 JavaScript 代码就很难阅读。

问题是逐渐增加的空白导致文件不断增大。每个空白行、缩进和括号之间的空格至少占用一个额外字符,这对于 CSS 或 JavaScript 代码的正确解析来说实际上并不需要。首先,一两个空白没有什么大不了的,但是小数量乘以一个很大倍数时就变成很大的数量了。

考虑这样一个文件,其中额外空白总计 5KB。如果您的网站每天的点击率是 1000,每天节省 5KB 每个月就可以节约大约 146 MB((5K * 1000 * 30) / 1024 作为粗略估计)。就这而言,该文件的点击量还是相对保守的估计,实际空白成本可能还会增加。

此外,下载您文件的用户必须等待文件的下载。尽管许多用户在他们第一次访问您的网站后可能就有缓存的 CSS 或 JavaScrip 文件,性能仍然会对他们的第一次访问造成负面影响。如果您可以减少您 CSS 和 JavaScript 文件,即使每次 1 KB,您都可以减少数千字节的浏览器必须加载的数据。

回页首

解决方案:压缩

要解决问题并从小资源获益,一个显而易见的解决方案是从您的 CSS 和 JavaScript 文件删除额外元素,比如注释和空白。但是,由于在开发过程中从您的文件删除注释和空白不 可行,一个较好的解决方案是 “分级” 您的网站资源、优化它们、然后将其发布。

编写一个删除空白字符的定制脚本最初听起来是一个可行的解决方案,但是在 CSS 和 JavaScript 文件中本身都有很重要的空白。因此任何删除空白和压缩文件的工具必须是足够智能,可以区别哪些语言中哪些空白是重要的。

幸运的是,在社区中已经可以找到这种工具了,它们已经经过资源(比如 CSS 和 JavaScrip 文件)压缩测试了。其中一个工具就是 YUI Compressor,一个来自 Yahoo!® Developer Network 的可用工具(链接见 参考资料)。

YUI Compressor

YUI 压缩器是一个使用 Java 编写的程序,拥有 Berkeley Software Distribution 许可证。YUI Compressor 可以缩小(压缩)您的 CSS 和 JavaScript 代码,这样您无需自己编写工具就可以享受小资源带来的益处了。

下载 YUI Compressor,然后提取文件,放置到一个容易访问的位置。归档文件包括完整源代码和一个用于构建 YUI Compressor 的 Apache Ant 脚本(build.xml)。然而,如果您不想构建该文件,您可以在 build 目录中找到 yuicompressor-{version}.jar(见 图 1)。
图 1. 归档文件目录
归档文件目录,显示构建用的文件夹、doc、lib 和 src。yuicompressor.jar 在 build 目录下。

YUI Compressor 的 JAR 文件是自带的,您可以将该文件复制到别的项目,通过输入以下命令来执行:

java -jar yuicompressor-2.4.2.jar --help

 

除了下载该文件,还有一种方法,使用 清单 1 中的 XML 文件来将 YUI Compressor 添加到您的 Apache Maven pom.xml 或 Apache IVY 文件。
清单 1. 添加 YUI Compressor 到 Maven 或 IVY

				
<dependency>
    <groupId>com.yahoo.platform.yui</groupId>
    <artifactId>yuicompressor</artifactId>
    <version>2.3.6</version>
</dependency>

 

将 -h 传递参数到 yuicompressor.jar 文件,显示 YUI Compressor 的基本用法信息。

回页首

压缩 CSS

清单 2 是一个为便于开发人员维护而优化的 CSS 示例,它包含注释,且被用空白格式化了。
清单 2. 为维护而优化的 CSS 文件

				
/* The main body for the page. */
body 
{ 
    font-family : Tahoma,Geneva,sans-serif;
    background-color : #e2e2e2;
    margin : 0 0 0 0;
    padding : 0 0 0 0;
}

/* The header and header elements */
#header, #content, #footer 
{
    padding 0;
    margin 0;
    width : 100%;
    min-width : 600px;
}

#header a 
{
    text-decoration : none;
    border : none;
}

#header 
{
    background : #fff url('images/lb-h.jpg') repeat-x top;
    height : 115px;
}

#header img.logo 
{
    position : absolute;
    border : none;
    margin-top : 10px;
    margin-left : 50px;
    z-index : 1000;
}

/* Top banner... */
#banner 
{
    margin : 0;
    padding : 0;
    background-color : #fff;
    border-bottom : 1px solid #bebebe;
    height : 265px;
    text-align : center;
}

/* This is the main content */
#content 
{
    background : #fff url('images/lb-g.jpg') repeat-x top;
    min-height : 450px;
    display : inline-block;
    clear : both;
}

#footer 
{
    border-top : 3px solid #bebebe;
    clear : both;
    min-height : 100px;
    font-size : smaller;
}

#followicons 
{
    margin-left : 50px;
}

 

要压缩一个 CSS 文件,运行以下命令:

java -jar yuicompressor-2.4.2.jar -o sample.min.css sample.css

 

文件被压缩之后,输出看起来如 清单 3 所示。清单是为了便于阅读进行了格式化的,但是 YUI Compressor 输出没有换行:您看到的都是在一行。
清单 3. 压缩后的 CSS 文件

				
body{font-family:Tahoma,Geneva,sans-serif;background-color:#e2e2e2;margin:0;padding:0;}
#header,#content,#footer{padding 0;margin 0;width:100%;min-width:600px;}#header a{
text-decoration:none;border:none;}#header{background:#fff url('images/lb-h.jpg') repeat-x 
top;height:115px;}#header img.logo{position:absolute;border:none;margin-top:10px;
margin-left:50px;z-index:1000;}#banner{margin:0;padding:0;background-color:#fff;
border-bottom:1px solid #bebebe;height:265px;text-align:center;}#content{background:#fff 
url('images/lb-g.jpg') repeat-x top;min-height:450px;display:inline-block;clear:both;}
#footer{border-top:3px solid #bebebe;clear:both;min-height:100px;font-size:smaller;}
#followicons{margin-left:50px;}

 

除了简单地删除空白和注释之外,YUI Compressor 还对您的 CSS 执行大量其他优化来使文件更小。那么,为了使文件更小究竟对 CSS 代码做了什么呢?

  • 删除空白。任何不必要的空白,像缩进、空行,以及元素和括号之间的空格都被删除了。如果,CSS 的空白对于正常运行是必需的,那么会被保留下来(见 清单 4)。

    清单 4. 删除多余的空白

    						
    						/* Before */
    #header a 
    {
        text-decoration : none;
        border : none;
    }
    
    /* After */
    #header a{text-decoration:none;border:none;}
  • 删除注释。如果在您的 CSS 文件中必须包含注释,比如,公司的版权通告,您可以在注释中输入一个感叹号(!),通知 YUI Compressor 保留它(见 清单 5)。

    清单 5. 除必要注释外,全部删除

    						
    						/* Before */
    /* This is the main content */
    #content 
    {
        background : #fff url('images/lb-g.jpg') repeat-x top;
        min-height : 450px;
        display : inline-block;
        clear : both;
    }
    
    /* After */
    #content{background:#fff url('images/lb-g.jpg') repeat-x top;min-height:450px;
    display:inline-block;clear:both;}
  • 删除空声明。YUI Compressor 从 CSS 中删除空声明,除非它们对于正常运行是必需的(见 清单 6)。

    清单 6. 删除空声明

    						
    						/* Before */
    #followicons 
    {
        margin-left : 50px;
    }
    
    #followicons a
    {
    }
    
    /* After */
    #followicons{margin-left:50px;}
  • 执行其他优化。这些优化包括减少十进制数的前置零,缩短 0 值和 16 进制值(见 清单 7)。

    清单 7. 执行其他优化

    						
    						/* Before */
    body 
    { 
        font-family : Tahoma,Geneva,sans-serif;
        background-color : #ffee22;
        margin : 0 0 0 0;
        padding : 0 0 0 0;
    }
    /* After */
    body{font-family:Tahoma,Geneva,sans-serif;background-color:#fe2;margin:0;padding:0;}

累积起来,YUI Compressor 对 CSS 代码进行的这些优化使您的文件小了不少呢!

回页首

压缩 JavaScript 代码

您可以使用 YUI Compressor 来压缩 JavaScript 代码。清单 8 显示了一个包含注释和额外格式的文件。
清单 8. 一个便于维护而格式化的 JavaScript 文件

				
/*
 * Creates a cookie on the system with the given name,
 * value, and for the given number of days.
 */
function createCookie(name, value, days) {

    if (days != null) 
    {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        var expires = "; expires=" + date.toGMTString();
    }
    else 
    {
        var expires = "";
    }

    document.cookie = name + "=" + value + expires + "; path=/";

}

 

要在 JavaScript 文件上运行 YUI Compressor,执行以下命令:

java -jar yuicompressor-2.4.2.jar -o functions.min.js functions.js

 

YUI Compressor 对文件进行优化之后,看起来像 清单 9 这样。
清单 9. 压缩的 JavaScript 文件

				
function createCookie(c,d,e){if(e!=null){var b=new Date();b.setTime(b.getTime()+(e*24*60*
60*1000));var a="; expires="+b.toGMTString()}else{var a=""}document.cookie=c+"="+d+a+
"; path=/"};

 

YUI Compressor 添加到 Mozilla Rhino(见 参考资料)项目,并使用项目中代码标记 JavaScript 文件。Rhino 是一个执行 JavaScript 代码的 Java 实现,被设计用于在 Java 应用程序中提供扩展点,通过启动这些扩展点来执行 JavaScript 代码。

由于文件是使用支持 JavaScript 执行的库来进行标记的,那么它们将会被安全的编译成 JavaScript 代码,用与编写方式相同的方法来执行。其他搜索 — 替换工具用来缩小代码,比如这些使用规则表达式的工具,如果所用的规则表达式不是足够精细,那么将会出现误差。

以下优化是在 JavaScript 文件中执行的:

  • 删除空白。从 JavaScript 代码中删除所有不重要的空白,包括新行。
  • 删除注释。从 JavaScript 文件中删除所有注释,除了这些 C 风格的注释,以 /*! 序列开始的。如果公司版权或者其他信息必须保留在文件中,务必使用该序列包含您的注释内容。
  • 重命名 Method-scoped 变量。除非您使用 YUI Compressor 命令的 --nomunge 选项,否则 YUI Compressor 将自动缩短 JavaScript 文件中的变量名。(将变量声明单独留在函数外,假设它们可能会用于其他地方)。由于 JavaScript 语言中的变量名仅需至少一个字符 ,就能为您的 JavaScript 文件节省相当多字符。替换变量稍微混淆 JavaScript 代码,但是由于您不需要修改代码版本,应该问题不大。
  • 删除分号。像压缩 CSS 一样,一些不重要的分号(;)将被从 JavaScript 代码中删除。
  • 其他选择。--line-break 选项对于分离文件可能是重要的,因此这一行不能太长。(优化时 YUI Compressor 会删除换行符。)

回页首

看看优势

要想查看压缩的优势,您可以使用不同的工具,其中两个是构建在浏览器中,这使得使用它们比使用分析工具方便得多:Google® Chrome Web 浏览器的开发人员工具和 Mozilla® Firefox 的 Firebug 插件。这两个工具都向您展示了下载的附加资源以及文件大小和下载它们浏览器所用的时间。

图 2 是一个 Chrome 开发人员工具分析一个页面的示例。(要访问这些工具,在您的浏览器中单击 Tools > Developer Tools。)
图 2. Chrome 浏览器附带的开发人员工具 
被分析的页面截图

图 3 展示了 Firefox 中的 Firebug 插件分析同一页面 。
图 3. Firebug 插件
使用 Firebug 插件分析页面的截图

如果您使用一个自动工具(下一节将会介绍),您就可轻松地获取一个使用旧文件的 URL 和另一个包含压缩文件的 URL(例如,http://localhost/orig 和 http://localhsot/minified)。您可以使用这些工具来对您的 web 应用程序进行基本的分析,就会知道压缩您的 CSS 和 JavaScript 文件会有多大的不同。刚开始差异可能很小,但做一些数学运算,就能明白执行优化比起置之不理,长期效果是多么的明显。

回页首

自动化和集成

要想自动完成压缩,将它作为一个步骤添加到文件分段和执行测试之间。清单 10 中的 Ant 文件证实了如何使用 Ant 自动完成操作。
清单 10. 使用 Ant 自动压缩

				
<?xml version="1.0" encoding="utf-8" ?>
<project name="my-web-site" default="usage" basedir=".">

    <property name="source.dir" value="${basedir}/application" />
    <property name="staging.dir" value="${basedir}/staging" />

    <macrodef name="yuicompress">
        <attribute name="filename" />
        <sequential>
            <java jar="${basedir}/tools/yuicompressor-2.4.2.jar" fork="true">
                <arg value="${source.dir}/styles/@{filename}" />
                <arg value="--type" />
                <arg value="css" />
                <arg value="-o" />
                <arg value="${staging.dir}/styles/@{filename}" />
            </java>
        </sequential>
    </macrodef>

    <target name="prepare-deploy">
        <echo level="info" message="Preparing files for deployment..." />

        <!-- minify the CSS -->
        <yuicompress filename="main.css"/>
    </target>

    <!-- The rest of the build script... -->

</project>

 

您也可以使用一个 shell 脚本,Windows PowerShell™ 脚本,或者批处理文件来自动完成这一操作。

一旦文件被正确分段,您就可以根据分段代码运行您的测试了,如果可以的话。如果您没有通过单元测试验证您定义的 JavaScript 代码,您就应该考虑它。参阅 参考资料 ,获取介绍 web 应用程序 UI 测试的信息链接。

您也可将 YUI Compressor 和 IDE 整合,比如 Eclipse,这样构建行为可以自动为您生成一个压缩文件。直接集成 Eclipse 最大的缺点就是任何添加到 Eclipse 的单个构建器只可以优化一个文件,除非构建器调用一个脚本(比如,清单 10 中的 Ant 脚本)来压缩多个文件。

要为您的项目将 YUI Compressor 添加到 Eclipse 中,在 Eclipse 中选择项目,然后单击 Project > Properties 来向项目中添加一个新构建器。从那里开始执行以下步骤:

  1. 从属性列表中选择 Builders,然后单击 New 来添加一个新构建器(见 图 4)。

    图 4. 将 YUI Compressor 作为一个构建器添加到 Eclipse 
    显示为项目添加构建器的屏幕截图。

  2. 选择 Program,然后单击 OK(见 图 5)。

    图 5. 添加一个构建器运行程序
    选择一个额外工具类型来创建的屏幕截图。选择的是 Ant Builder、Grails Tools 和 Program。

  3. 输入 Compress 作为发布配置的名称。
  4. 输入您 Java 文件夹的路径(例如,/usr/bin/java)。
  5. 通过单击 Variables 和添加 ${project_loc},使用项目位置作为工作目录。
  6. 为命令添加参数,包括 yuicompressor-{version}.jar 文件名。在 图 6 所示的示例中,JAR 文件被包含在项目的工具目录下。

    图 6. 添加工具参数
    'Edit launch configuration properties'屏幕的屏幕截图,显示 'Main' 选项卡。这有 Location、Working directory 和 Arguments 的文本字段.

  7. 单击 Refresh 选项卡,然后选择 Refresh resources upon completion。您只需要刷新包含源代码的项目即可。

如果您构建了一个 Ant 脚本来执行压缩,那么您可以向您的项目中添加一个构建器来以同样的形式调用 Ant 脚本。参阅 参考资料,获取整合 Ant 构建器和您的 Eclipse 环境的示例链接。

回页首

结束语

YUI Compressor 是一个可以用来优化您的 CSS 和 JavaScript 源文件的工具,使它们变得更小。小的原文件为您带来了许多好处,节省了带宽、为您的访问提供更快的加载时间。尽管对于一个文件节约似乎微不足道,但是如果大量使用,累计起来相当可观。

如果添加到分段步骤中,YUI Compressor 将可以在不影响文件开发和维护的情况下优化您的 CSS 和 JavaScript 文件。压缩 CSS 和 JavaScript 文件只是优化资源,使您的 web 应用程序更轻巧的整体工作中的两个技术。

获得产品和技术

Debug 总结

本来只是把网站程序从一台虚拟空间转移到一台linux服务器,但是越搞越复杂,仅在此写上我的感悟。

我首先是单独安装apache 和mysql服务器然后再一一配置,但是这样做出现了一个问题,一些扩展你要在Linux平台再进行编译,相当麻烦,于是我选用了lampp组件,

好处是省的你一一编译了,但是出现了一下几个问题:

1.要配置开机自动启动(解决办法见上一篇日志)

2.MYSQL命令行好像无效,(./解决)

3.一些命令比较特别

这是安装服务器的问题

在安装程序时遇到了一下问题:
1.ZIP RAR解压需要安装其它软件,采用其它压缩方式要换非windows系统

2.还有就是权限问题 最好都设置为777 不然一些包含文件的语句会导致错误

3.不同平台的服务器环境略有差别,有的PHP程序开始简写是<? 而有的不支持,所以最好在编写程序时考虑到这一点一律用<?php

经验:

1.编写程序最好有说明文档,不能想到哪该到哪,一些常用组件要学会封装,避免沉余代码。

2.要考虑多平台的可移植性,多浏览器兼容性。

3.最好要有一键化安装程序,不能让安装过程一定要由专业人士来做,这是很重要的一点。

4.代码文件的命名,目录的命名要符合规范,我所安装的这个程序主页是default.php 这是很坑爹的,作为PHP程序,我第一次见有人把这设为索引文件,还有就是这个程序存在两个文件目录一个是js 一个是script 这也是很不规范的。

5.文件的包含我很赞同,但是把常用组件封装成类更好,然后类单独放在一个文件中,提高效率

 

密码为什么明文存放

 

很早就写过一篇blog,说到过,你的密码应当一次一密,至少某些密码泄露时不至于波及太广。结果这次CSDN不幸中枪。我不去讨论多少人急急忙忙修改密码,多少人数据泄露,单说说为什么很多时候密码是明文存放的。

就我有记忆以来,我写应用就从来没有明文存放过密码。最起先是md5方式存放。md5可以让你找到hash值,有的时候也会被用于穷举。但是无论如何,md5密码本身比明文安全很多。后来改成了challenge-response验证模式,也是用md5做的hash后进行c-r的。再后来,md5的碰撞冲突的论文出来,后面用的多数都是sha256了。从头到脚,我就没做过密码明文存放,并且,我认为这是正常程序员最起码的修养。(当然,明文存放的代码不是没有,不过那是调试模式) 但是现在我所知,很多系统的身份验证都是密码明文存放的,为什么?其实我不大理解。不过有时候问起,有些人和我说了几个我觉得不是搪塞的理由,现在抄录如下,告大家知。

1.明文密码没法应付检查。大家知道互联网审查,有时往往会一个电话过来,要XX用户的密码。如果你没法给出,上头就认为你不配合,事情各种难搞。作为审查机构的老板,当然没必要知道明文密码的危害。他们只知道,我要密码,为什么不行。所以,悲崔的程序员们就往往会得到一条死命令,保存明文密码。

2.压根不知道明文密码有什么问题。中国的互联网有太多的没基础的新人,从石头的缝隙中顽强的生长出来。这不是坏事,坏事的是这些人往往会在一些基础问题上出现奇怪的毛病。例如有些程序员,写程序很快,但是居然从来不知道密码明文存放会导致什么问题。更神奇的是,这些人中,有一家银行…

3.自信暴棚的混帐。有些人的自信总比别人强,而且强在莫名其妙的地方。例如:我的服务器肯定是没问题的,所以我的密码一定要明文存放。如果不,就是质疑我的技术。

实话说,这种人真是少数中的少数。

4.遗留系统。很多系统设计的时候因为某个其他理由,使用了明文密码。等后来这个理由不存在了,密码系统升级成了一个困难。因为密码系统太重要了,所以在没有太大利益的情况下,总是倾向于不修改系统。但是有什么足够利益来推动系统修改呢?用户安全问题在发现前不是一个问题——好比这次的CSDN,不是被暴出来的话就根本不会被当作一个问题。系统的管理者,每个人都没有足够的动力去修改系统。

5.世界的阴暗角落。有的时候,程序员/老板明文存放的理由,是为了方便盗窃用户其他网站资料。例如我所知的某钓鱼案例,你注册网站,就提供很多免费服务,网站看起来也很靠谱——除了后来突然爆出这家网站其实暗地中用你的生日/密码猜解信用卡/银行卡密码,大家才突然发现,这家网站其实根本没有在美国注册,而是一个听都没听说过的国家。

而且很多网站提供从其他网站导入之类的功能,更加的危险。以前经常爆出twitter密码被窃取,主要就是因为OAuth开放以前,twitter上的第三方应用需要提供原生密码,导致很多小应用的目的其实就是收集密码…

6.为了给用户提供方便。这个理由和上一个很类似,不过不是为了某些险恶的目的。而是客户经常要求——为什么我不能做XX事,为什么我不能blahblah。好吧,为了让你能,我们就必须保存明文密码。

明文密码的保存原因很多,不过结论都是一样的。在任何网站/服务上,你绝对不能使用同一个密码,零级密码除外。尤其请注意,不要在两家银行使用同样的银行卡密码/网银密码,原因不说。

从未来进化的角度说,密码的未来进化趋势是核心授权体系。就是你要向某个网站验证身份,只需要向身份验证商验证,剩下自动完成。现在的openid就是一种解决方案。密码都没了,还谈什么泄露呢?同时,实体交互和授权的精细划分也是一个趋势。某个网站访问别的网站的数据的时候,会形成一个访问令牌。这个令牌对需要访问的内容详细写明,并且需要用户授权。OAuth就是这个趋势的代表。另外一个趋势是利用某个足够安全的设备作为以上两者的终端载体。目前这个设备用的是手机,可是——手机不是一个足够安全的设备。也许这会是下一个XX门的隐患吧。

浅析PHP模板引擎之二

上篇文章我简要的介绍下模板引擎的运行机理,但是过于简单不太实用,下面我继续扩展这一问题,并使它成为轻量型引擎。

首先我们建立三个目录 ./templates ./templates_c    ./lib 这三个目录分别放模板文件、经过编译后生成的文件、引擎代码文件

下面放上运行原理图:

下面写上各个部分代码:

1.模板引擎template.class.php代码:

< ?php  class template{  private $template_c;  private $data=array();  public function __set($name,$value){  if(!array_key_exists($name,$this->data)){
$this->data[$name]=$value;
}else{
$this->data[$name]=$value;
}

}
public function display($templatename){
$this->template_c=file_get_contents('./templates/'.$templatename);
foreach($this->data as $name => $value){

$this->template_c=str_replace('{'.$name.'}',$value,$this->template_c);

}
echo $this->template_c;

}

}

模板test.tpl代码:

我的名字是 {name}
 手机号 {telephone}
 性别{sex}
 口头禅是{say}

index.php代码:

< ?php  Header('Content-type:text/html;charset=utf-8'); require_once  "./lib/template.class.php"; $template= new template; $template->name="lvxinwei";
$template->telephone=15151827622;
$template->sex="男";
$template->say="我勒个去";
$template->display('test.tpl');

显示效果:
我的名字是 harold
手机号 151518276xx
性别男
口头禅是我勒个去
在第三节,我会继续扩展该问题,使之能进行智能化的页面缓存;