優化網站設計(一):減小請求數

前言

網站設計的優化是一個很大的話題,有一些通用的原則,也有針對不一樣開發平臺的一些建議。這方面的研究一直沒有中止過,我在不一樣的場合也分享過這樣的話題。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的作法)

相關文章
相關標籤/搜索