zoukankan      html  css  js  c++  java
  • 【转】 动态页面静态化

    在站点流量很大的时候,为了提高系统性能,减短系统响应时间,我们很多时候考虑把站点做成静态的,用后台的发布系统发布出来。静态页面在性能上具有不少优势,但是,相对动态页面灵活性不够,扩展性不好,以后维护起来也比较麻烦。下面,就我的经验谈谈怎样生成这些静态站点。
      生成静态页面一般来说都是做好静态页面的模板,然后从数据源读取数据,生成html代码块替换模板中的标签,然后生成静态文件。比如文章页面模板部分如下:
      

    <table border="1" style="BORDER-COLLAPSE: collapse" width="100%" cellpadding="2" cellspacing="2">
    <tr>
    <td>
    <href="(#ArticleUrl#)">(#Title#)</a>
    <br>作者(#Author#) 时间2006-3-24 13:38:00
    </td>
    </tr>
    <tr>
    <td>
    摘要:(#Description#)
    </td>
    </tr>
    <tr>
    <td>
    (#Content#)
    </td>
    </tr>
    </table>
      我们可以用如下的方法读取该模板的内容
     
    /// <summary>
    /// 读取文件内容
    /// </summary>
    /// <param name="strFilePath">文件路径</param>
    /// <returns>文件内容字符串</returns>
    /// <param name="strEncodingName">编码名称(GB2312,UTF-8等)</param>
    public string ReadFile(string strFilePath, string strEncodingName)
    {
    string strFile = string.Empty;
    StreamReader sr 
    = new StreamReader(strFilePath, System.Text.UnicodeEncoding.GetEncoding(strEncodingName));
    try

    strFile 
    = sr.ReadToEnd();
    }
    catch(Exception e)
    {
    }
    finally
    {
    sr.Close();
    }
    return strFile;
    }

      假设返回的字符串是strTemplate,从数据库中读取的文章标题为strTitle,作者为strAuthro,发布时间为strPostTime,描述为strDescription,内容为strContent,我们就可以用string的Replace方法把标签替换为实际要显示的内容了
    strArticle = strTemplate.Replace("(#Title#)", strTitle);
    strArticle 
    = strArticle.Replace("(#Author#)", strAuthor);
        ……………………………………
      这样,strArticle就是要显示页面的html代码了,再用如下的方法写入文件
    /// <summary>
    /// 写Html文件
    /// </summary>
    /// <param name="strHtml">写入的字符串</param>
    /// <param name="strDestinationFilePath">目的文件路径</param>
    /// <param name="strEncodingName">编码名称(GB2312,UTF-8等)</param>
    public void WriteFile(string strHtml, string strDestinationFilePath, string strEncodingName)
    {
    StreamWriter sw 
    = new StreamWriter(strDestinationFilePath, false, System.Text.UnicodeEncoding.GetEncoding(strEncodingName));
    try
    {
    sw.Write(strHtml);
    sw.Flush();
    }
    catch(Exception e)
    {
    strErrorMessage 
    = e.Message.ToString();
    }
    finally
    {
    sw.Close();
    }
    }

      这里要注意的是Replace方法有时候替换会失效,比如<a href="http://(#UserID#).it.com.cn">one</a>这里的(#UserID#)不能用Replace方法替换,可以这样来替换strArticle = Regex.Replace(Article, "\\(#UserID#\\)", strUserID);
      现在,生成静态文件的方法我们会了,再来看看一些个性化技巧,如何给用户提供不同风格的各种页面。
      现在一般是通过div+css的方法给每个用户提供不同风格的页面。也就是说每个用户页面的html代码结构是一样的,只是外部css不一样,这样在写页面的时候,我们可以把基本的html代码硬编码到我们的程序中,减少了复杂度。css可以很好的控制页面布局,实现起来很方便。这种方法中,所有风格的同一页面模板只有一个,一个风格对应一个css文件。这样,可以满足一般的需求了,很多的blog都是采用这种方法来实现,比如blogcn,douban。
      但是,这种方法也有个缺陷,因为html代码是硬编码到后台代码中,所有风格的同一页面模板只有一个,所以页面的个性化也受到了一定限制。比如我想让一个风格的文章列表用表格形式,另一个采用其他方式,就无法实现了,因为我们已经把具体内容写在后台代码中了,只是引用的css文件不同。只要我们稍加改进,就完全可以随心所欲定制页面了,我的方法如下:
      每个风格一套模板,一个css。比如文章页面的另一个风格模板如下:
    <div>
    <href="(#ArticleUrl#)">(#Title#)</a>
    <br>作者(#Author#) 时间2006-3-24 13:38:00
    <hr>
    摘要:(#Description#)
    <br>(#Content#)
    <div>
      同样,我们也可以用上面替代的方法生成页面,只是每次要根据用户所选择的模板来选择不同的模板文件,而不是所有的用户选择同一个。看到这里,你可能会问,那要是列表怎么办?以前是把列表的html代码直接写在后台代码中,现在呢?遇到这样的情况,我们可以做下面这样的模板。
    <table>
    <!-- ArticlesList Start -->
    <!-- Article (#ArticleID#) Start -->
    <tr>
    <td height="20"></td>
    </tr>
    <tr>
    <td>
    <table border="1" style="BORDER-COLLAPSE: collapse" width="100%" cellpadding="2" cellspacing="2" ID="Table2">
    <tr>
    <td>
    <href="(#ArticleUrl#)">(#Title#)</a>
    </td>
    </tr>
    <tr>
    <td>
    摘要:(#Description#)
    </td>
    </tr>
    <tr>
    <td>
    发表于(#ReleaseTime#)
    &nbsp;|&nbsp;评论((#CommentCount#))&nbsp;|&nbsp;访问((#VisitCount#))
    </td>
    </tr>
    </table>
    </td>
    </tr>
    <!-- Article (#ArticleID#) End -->
    <!-- ArticlesList End -->
    </table>
      上面的模板中<!-- Article (#ArticleID#) Start -->和<!-- Article (#ArticleID#) End -->之间的内容就是文章列表中一个文章的代码,我们只需要用正则表达式把这部分找出来,替换标签就得到了一个列表中一个文章的html代码,把所有文章的代码连起来就得到了文章列表的代码,再让得到的代码替换模板中<!-- ArticlesList Start -->和<!-- ArticlesList End -->的内容就得到了最终要写入页面的代码。虽然比以前div+css的方式多了些步骤,但是,这样确实有效可行。大家也许会发现,上面的模板也为某些更新页面而不需要读数据库提供了基础,比如我要从文章列表中删除ID为100的文章,我们只要删除<!-- Article 100 Start -->和<!-- Article 100 End -->之间的内容就可以了,根本不需要再读数据库。但是,这样也会带来隐患,假如某次文件操作失败,那就永远是失败,不能跟数据库的内容同步,当然你可以通过提供其他功能来解决这个问题。
      既然是为了性能,我们把页面发布成静态,那我们不如再进一步,看看怎样提高写静态页面的性能。
      1.提取所有页面的公共部分,放外部文件进行引用。
      比如所有页面的导航部分是相同的,这些部分经常要根据用户的操作进行更新,如果把它完全写在每个页面中,更新起来代价是很大的,必须重写每个页面。我们可以把这些内容外挂到js中,更新这些内容的时候,更新相应的js文件就可以了,一次更新,整站更新。这里,要注意的是要对js的特殊字符要进行转义,比如;'"等特殊字符要在前面加上/进行转义。
      2.局部更新,而不是整体更新
      我们可以用<!-- ArticlesList Start -->和<!-- ArticlesList End -->这样的标记把文章列表标记出来,更新文章页面的时候,我们只需要生成文章列表html代码,代替原页面(非模板)这两个标记之间的内容就可以了。这样,能大量减少读数据库的次数,性能自然也提高不少。在不同内容越多的页面,性能优势越明显。
      3.使用分层树结构存放文件
      这个其实是对读取性能的优化了。我们不要把大量的文件都生成在同一个根目录下,这样服务器遍历文件就会影响性能。我们可以使用分层树结构来生成文件,比如按年/月/日的形式组织文件目录。
      综合有目的性的使用以上方法可以提高发布系统的性能,也能使用户界面最大限度地个性化。有时,我们可以采用静态和动态结合的方法提高系统性能,比如文章列表第一页生成静态,后面的采用动态方式。总之,对访问频率越高的页面生成静态越有优势,更新频率越高的页面动态方式越有优势,所以我们要均衡两者,有的放矢的选择
  • 相关阅读:
    Sample XPS Documents Download
    触发器中的inserted表和deleted表
    Using freewheel.labs.autodesk.com to auto generate preview images of DWF files on your web site
    解除SQL对组件"Ad Hoc Distributed Queries"的"STATEMENT'OpenRowset OpenDatasource"的访问
    读写xps
    XPS文件,在Windows XP下的打开查看阅读和打印方法。
    Learning to Reference Inserted and Deleted Tables
    Get value from updated, inserted and deleted
    Reinstall Microsoft Helper Viewer
    如何查找文件的IFilter
  • 原文地址:https://www.cnblogs.com/xlfj521/p/1020794.html
Copyright © 2011-2022 走看看