網站設計的優化是一個很大的話題,有一些通用的原則,也有針對不一樣開發平臺的一些建議。這方面的研究一直沒有中止過,我在不一樣的場合也分享過這樣的話題。javascript
做爲通用的原則,雅虎的工程師團隊曾經給出過35個最佳實踐。這個列表請參考css
同時,他們還發布了一個相應的測試工具Yslow http://developer.yahoo.com/yslow/html
我強烈推薦全部的網站開發人員都應該學習這些最佳實踐,並結合本身的實際項目狀況進行應用。java
接下來的一段時間,我將結合ASP.NET這個開發平臺,針對這些原則,經過一個系列文章的形式,作些講解和演繹,以幫助你們更好地理解這些原則,而且更好地使用他們。jquery
爲了跟隨我進行後續的學習,你須要準備以下的開發環境和工具web
這一篇文章討論的是第一個原則:應該儘量加減小請求數。這個原則的說明請參考 http://developer.yahoo.com/performance/rules.html#num_httpchrome
咱們的網頁在加載的時候,爲了提供更加豐富的內容和效果,除了頁面自己這個請求以外,老是須要加載其餘一些資源的,例如咱們常見的Javascript文件,css文件,圖片,甚至還會有一些Flash組件等等。這本無可厚非,但若是過多的外部請求,會很直接地下降頁面加載的速度。api
咱們來看一個例子吧。例如咱們常常訪問的博客園的首頁瀏覽器
這個網頁的加載須要多少次請求呢?(若是不考慮緩存的話)緩存
咱們看到,請求數爲55個。咱們進一步經過Yslow來分析,能夠獲得綜合的報表
應該說博客園的設計已經比較注意不少細節了。他們獲得了B級的評分。咱們再來看看其餘一些主要的門戶的表現吧(從左至右,依次是新浪,搜狐,騰訊,淘寶),他們都只獲得D級的評分。
【備註】這些評分只是做爲一個參考,不作任何的結論和推論。
咱們能夠經過以下的幾個方法來減小請求數:
對於這兩種文件的合併而言,咱們固然能夠手工去作(copy,paste),把一個文件的內容粘貼在另一個文件內容的底部便可。但這種方式有幾個缺點:
因此,我並非很推薦用這種手工合併的方法,事實上,咱們有更好的工具來實現, 而且在ASP.NET的一些框架(例如ASP.NET MVC)裏面已經有了內置的實現。
咱們先來看一個例子,下面是一個典型的ASP.NET MVC項目
我找了其中的一個用戶註冊頁面,在IE中進行查看
咱們看到默認狀況下,完成這個頁面其實要執行8個請求。但通過簡單的處理(添加一行代碼)以後,咱們能夠看到以下的效果
並且若是你細心看的話,在這個頁面中請求的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的項目:
咱們看到,在頁面中,咱們添加了三個腳本引用,這樣的話,天然在打開頁面的時候,須要單獨請求這三個腳本文件。
咱們是否能夠將這三個文件合併成一個請求呢?請跟隨我來進行以下的操做
首先,添加一個組件,這是微軟官方發佈的System.Web.Optimization,顧名思義,這就是爲了優化網絡開發用的
按照通常的慣例,咱們在項目中添加一個文件,來進行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>
很不錯,咱們如今能夠查看一下頁面運行起來的效果
很明顯,原先的三個請求,如今變成了一個請求。須要注意的是,若是咱們去計算文件大小,這個合併以後的文件,體積會比以前三個文件體積總和略小一些。因此你能夠理解爲這裏存在必定的壓縮,但這個壓縮比是不大的(尤爲是原有的javascript文件自己就通過了壓縮的狀況下)。關於javascript文件或者css文件的壓縮,後續會有專門的文章介紹。
上面的例子,演示的是javascript文件的合併。其實,css文件的合併也是相似的作法,區別在於要使用StyleBundle : http://msdn.microsoft.com/en-us/library/system.web.optimization.stylebundle.aspx
本文介紹了網站優化的第一個原則(儘可能減小請求數),我帶領你們分析了爲何須要考慮這個原則,以及具體如何實現(包括在MVC和Web Forms的作法)