优化网站设计(一):减小请求数

前言

网站设计的优化是一个很大的话题,有一些通用的原则,也有针对不一样开发平台的一些建议。这方面的研究一直没有中止过,我在不一样的场合也分享过这样的话题。javascript

做为通用的原则,雅虎的工程师团队曾经给出过35个最佳实践。这个列表请参考css

Best Practices for Speeding Up Your Web Site  http://developer.yahoo.com/performance/rules.html 

同时,他们还发布了一个相应的测试工具Yslow http://developer.yahoo.com/yslow/html

我强烈推荐全部的网站开发人员都应该学习这些最佳实践,并结合本身的实际项目状况进行应用。java

接下来的一段时间,我将结合ASP.NET这个开发平台,针对这些原则,经过一个系列文章的形式,作些讲解和演绎,以帮助你们更好地理解这些原则,而且更好地使用他们。jquery

 

准备工做

为了跟随我进行后续的学习,你须要准备以下的开发环境和工具web

  1. Google Chrome 或者firefox ,而且安装 Yslow这个扩展组件.请注意,这个组件是雅虎提供的,但目前没有针对IE的版本。
    1. https://chrome.google.com/webstore/detail/yslow/ninejjcohidippngpapiilnmkgllmakh
    2. https://addons.mozilla.org/en-US/firefox/addon/yslow/
    3. 你应该对这些浏览器的开发人员工具备所了解,你能够经过按下F12键调出这个工具。
  2. Visaul Studio 2010 SP1 或更高版本,推荐使用Visual Studio 2012
    1. http://www.microsoft.com/visualstudio/eng/downloads 
  3. 你须要对ASP.NET的开发基本流程和核心技术有至关的了解,本系列文章很难对基础知识作普及。

 

本文要讨论的话题

这一篇文章讨论的是第一个原则:应该尽量加减小请求数。这个原则的说明请参考  http://developer.yahoo.com/performance/rules.html#num_httpchrome

咱们的网页在加载的时候,为了提供更加丰富的内容和效果,除了页面自己这个请求以外,老是须要加载其余一些资源的,例如咱们常见的Javascript文件,css文件,图片,甚至还会有一些Flash组件等等。这本无可厚非,但若是过多的外部请求,会很直接地下降页面加载的速度。api

咱们来看一个例子吧。例如咱们常常访问的博客园的首页浏览器

image

这个网页的加载须要多少次请求呢?(若是不考虑缓存的话)缓存

image

咱们看到,请求数为55个。咱们进一步经过Yslow来分析,能够获得综合的报表

imageimageimage

应该说博客园的设计已经比较注意不少细节了。他们获得了B级的评分。咱们再来看看其余一些主要的门户的表现吧(从左至右,依次是新浪,搜狐,腾讯,淘宝),他们都只获得D级的评分。

【备注】这些评分只是做为一个参考,不作任何的结论和推论。

imageimageimageimage

 

如何减小请求数?

咱们能够经过以下的几个方法来减小请求数:

  1. 合并外部资源文件(如javascript,css,图片文件)
    1. 图片的合并,是将多个图片合并为一个图片,而后采用css的一些设置(background-image,background-position) 来使用它们。这个很简单实用(可是效果也是显著的)。本文将不作演示。
    2. javascript和css文件的合并,这个可能你们不太常常注意到。本文的后续部分将对此进行演示。
  2. 使用Inline images 这种方式这个方式可能依赖于浏览器的实现,目前并非全部的浏览器都支持。因此本文也不作演示。

 

合并javascript文件和css文件

对于这两种文件的合并而言,咱们固然能够手工去作(copy,paste),把一个文件的内容粘贴在另一个文件内容的底部便可。但这种方式有几个缺点:

  1. 破坏了原有文件的结构
  2. 不一样页面须要的文件组合多是不同的,这种状况下会须要产生多个不一样的文件,并且须要比较当心地维护它们
  3. 若是文件的内容发生变化,就须要从新再来一次

 

因此,我并非很推荐用这种手工合并的方法,事实上,咱们有更好的工具来实现, 而且在ASP.NET的一些框架(例如ASP.NET MVC)里面已经有了内置的实现。

咱们先来看一个例子,下面是一个典型的ASP.NET MVC项目

image

我找了其中的一个用户注册页面,在IE中进行查看

image

咱们看到默认状况下,完成这个页面其实要执行8个请求。但通过简单的处理(添加一行代码)以后,咱们能够看到以下的效果

image

并且若是你细心看的话,在这个页面中请求的javascript文件彷佛看起来通过了特殊的处理(路径比较特殊)。那么,这是如何实现的呢?

原来,在MVC项目中,默认会有一个所谓的BundleConfig的类,它提供了一个方法RegisterBundles,以下所示

using System.Web;
using System.Web.Optimization;

namespace MvcApplication1
{
    public class BundleConfig
    {
        // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                        "~/Scripts/jquery-ui-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.unobtrusive*",
                        "~/Scripts/jquery.validate*"));

            // Use the development version of Modernizr to develop with and learn from. Then, when you're
            // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));

            bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));

            bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
                        "~/Content/themes/base/jquery.ui.core.css",
                        "~/Content/themes/base/jquery.ui.resizable.css",
                        "~/Content/themes/base/jquery.ui.selectable.css",
                        "~/Content/themes/base/jquery.ui.accordion.css",
                        "~/Content/themes/base/jquery.ui.autocomplete.css",
                        "~/Content/themes/base/jquery.ui.button.css",
                        "~/Content/themes/base/jquery.ui.dialog.css",
                        "~/Content/themes/base/jquery.ui.slider.css",
                        "~/Content/themes/base/jquery.ui.tabs.css",
                        "~/Content/themes/base/jquery.ui.datepicker.css",
                        "~/Content/themes/base/jquery.ui.progressbar.css",
                        "~/Content/themes/base/jquery.ui.theme.css"));

        }
    }
}

 

这个方法会在Global.asax文件中调用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace MvcApplication1
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            //BundleTable.EnableOptimizations = false;//启用这一行,则使用Bundle的机制进行文件打包
            AuthConfig.RegisterAuth();
        }
    }
}

 

在具体的页面中,若是须要用到上述的脚本组合,则可使用下面这样的语法来调用

@Scripts.Render("~/bundles/jqueryval")

 

这就是全部的秘密。

那么,这个技术是否是只能使用在MVC中,在咱们另一种开发框架(ASP.NET Web Forms)中是否也可使用呢?

答案是:能够的。并且这个技术,确实是最先就是用在ASP.NET Web Forms里面,只不过,由于这方面的文档较少,因此可能你们用的很少而已。下面是我做为演示用的一个简单的ASP.NET Web Forms的项目:

image

咱们看到,在页面中,咱们添加了三个脚本引用,这样的话,天然在打开页面的时候,须要单独请求这三个脚本文件。

image

咱们是否能够将这三个文件合并成一个请求呢?请跟随我来进行以下的操做

首先,添加一个组件,这是微软官方发布的System.Web.Optimization,顾名思义,这就是为了优化网络开发用的

image

按照通常的惯例,咱们在项目中添加一个文件,来进行Bundle的注册

using System.Web.Optimization;

namespace WebApplication1
{
    public class BundleConfig
    {
        public static void RegisterBundle(BundleCollection config)
        {
            config.Add(new ScriptBundle("~/default").Include("~/scripts/jquery-2.0.0.min.js", "~/scripts/knockout-2.2.1.js", "~/default.js"));
        }
    }
}

 

而后,咱们修改Global.asax文件,添加以下的代码

using System;
using System.Web.Optimization;

namespace WebApplication1
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {
            BundleConfig.RegisterBundle(BundleTable.Bundles);
            BundleTable.EnableOptimizations = true;
        }

    }
}

最后,咱们在页面上也作相应的修改,以下所示(请注意粗体部分)

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<%@ Import Namespace="System.Web.Optimization" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <%= Scripts.Render("~/default") %>
</head>
<body>
    <form id="form1" runat="server">
        <div>
        </div>
    </form>
</body>
</html>

很不错,咱们如今能够查看一下页面运行起来的效果

image

很明显,原先的三个请求,如今变成了一个请求。须要注意的是,若是咱们去计算文件大小,这个合并以后的文件,体积会比以前三个文件体积总和略小一些。因此你能够理解为这里存在必定的压缩,但这个压缩比是不大的(尤为是原有的javascript文件自己就通过了压缩的状况下)。关于javascript文件或者css文件的压缩,后续会有专门的文章介绍。

上面的例子,演示的是javascript文件的合并。其实,css文件的合并也是相似的作法,区别在于要使用StyleBundle : http://msdn.microsoft.com/en-us/library/system.web.optimization.stylebundle.aspx

 

总结

本文介绍了网站优化的第一个原则(尽可能减小请求数),我带领你们分析了为何须要考虑这个原则,以及具体如何实现(包括在MVC和Web Forms的作法)

相关文章
相关标签/搜索