優化網站設計(十二):刪除重復腳本


前言

網站設計的優化是一個很大的話題,有一些通用的原則,也有針對不同開發平台的一些建議。這方面的研究一直沒有停止過,我在不同的場合也分享過這樣的話題。

作為通用的原則,雅虎的工程師團隊曾經給出過35個最佳實踐。這個列表請參考  Best Practices for Speeding Up Your Web Site http://developer.yahoo.com/performance/rules.html,同時,他們還發布了一個相應的測試工具Yslow http://developer.yahoo.com/yslow/

我強烈推薦所有的網站開發人員都應該學習這些最佳實踐,並結合自己的實際項目情況進行應用。 接下來的一段時間,我將結合ASP.NET這個開發平台,針對這些原則,通過一個系列文章的形式,做些講解和演繹,以幫助大家更好地理解這些原則,並且更好地使用他們。

准備工作

為了跟隨我進行后續的學習,你需要准備如下的開發環境和工具

  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的開發基本流程和核心技術有相當的了解,本系列文章很難對基礎知識做普及。

本文要討論的話題

這一篇我和大家討論的是第十二條原則:Remove Duplicate Scripts (刪除重復腳本)。

這條原則的意思是說,不要在一個頁面中,重復引用同一個腳本文件。乍一看起來,似乎沒有單獨拿出來談的必要:誰會這么做呢?你會嗎?我會嗎?

當然,你最好沒有這么做,而且希望你沒有這么做並不完全是出於一個好的習慣,而是因為你真的了解了重復引用同一個腳本文件所帶來的問題。

重復引用一個腳本可能存在的問題

我們可以用一個簡單的例子來看看,如果你在一個頁面中重復引用同一個腳本文件,可能存在的問題:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>

</head>
<body>
    <form id="form1" runat="server">
        <div>

            <script>
                var count = 0;
            </script>

 <script src="JavaScript1.js"></script> <script src="JavaScript1.js"></script>

            <script>
                document.write("<h1>訪問計數:" + count + "</h1>");
            </script>

        </div>
    </form>
</body>
</html>

頁面中,我們首先定義了一個全局的變量(count),然后重復引用了同一個腳本文件(javascript1.js),這個腳本文件內的腳本其實很簡單

count++;

這個頁面如果運行起來的話,大家可以想象一下count最后的值會是多少呢?對javascript比較熟悉的朋友一定猜出來了,由於有兩次腳本引用,所以,count的最終值應該是2。如下圖所示

image

所以后果是顯而易見的:我們可能認為,如果是同一個文件,引用多次的話,瀏覽器會不會聰明地只下載一次,並且也只執行一次呢?

從上圖中,我們幾乎可以覺得這就是對的,因為看起來並沒有兩個腳本請求,不是嗎?

這是一個假象!通過上面的實例,你應該會知道,實際上腳本文件肯定被下載過兩次,而且執行過兩次,否則為什么count會等於2呢?

如果你重復引用10次,那么毫無意外的,count會等於10。

好吧,我憑什么會犯這么低級的錯誤呢?你是這樣想到嗎?

This isn't as unusual as you might think. A review of the ten top U.S. web sites shows that two of them contain a duplicated script. Two main factors increase the odds of a script being duplicated in a single web page: team size and number of scripts

經研究發現,即便是美國排名前10位的網站,都可以犯這個錯。你有什么理由說你就一定不會呢?是的,有時候可能不是你一個人的錯,在一些較大的團隊和較大的項目,尤其是有大量腳本的時候,可能就要特別小心地對這些腳本進行管理了。

 

刪除重復腳本及最佳實踐

其實要刪除重復腳本,最重要的是要對腳本進行有效的管理,並且在編寫頁面的時候,仔細地進行引用。在ASP.NET中,善於利用一些框架,可以最大可能性地避免這個問題。

ASP.NET 從2.0開始引入了母版頁(master page)的技術,利用這個技術,我們可以將一些公用的腳本引用定義在母版頁中,而在內容頁中引入的腳本相對就少了很多了,既然很少,那么重復添加的概率就大大減小了。

下面有一個簡單范例(ASP.NET Web Forms)

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebApplication2.SiteMaster" %>

<!DOCTYPE html>
<html lang="en">
<head runat="server">
    <meta charset="utf-8" />
    <title><%: Page.Title %> - My ASP.NET Application</title>
    <asp:PlaceHolder runat="server">     
          <%: Scripts.Render("~/bundles/modernizr") %>
    </asp:PlaceHolder>  
    <webopt:BundleReference runat="server" Path="~/Content/css" /> 
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    <asp:ContentPlaceHolder runat="server" ID="HeadContent" />
</head>
<body>
    <form runat="server">
    <asp:ScriptManager runat="server">
        <Scripts>
            <%--To learn more about bundling scripts in ScriptManager see http://go.microsoft.com/fwlink/?LinkID=272931&clcid=0x409 --%>
            <%--Framework Scripts--%>
            
            <asp:ScriptReference Name="MsAjaxBundle" />
            <asp:ScriptReference Name="jquery" />
            <asp:ScriptReference Name="jquery.ui.combined" />
            <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" />
            <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" />
            <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" />
            <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" />
            <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" />
            <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" />
            <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" />
            <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" />
            <asp:ScriptReference Name="WebFormsBundle" />
            <%--Site Scripts--%>

        </Scripts>
    </asp:ScriptManager>
    <header>
        <div class="content-wrapper">
            <div class="float-left">
                <p class="site-title">
                    <a runat="server" href="~/">your logo here</a>
                </p>
            </div>
            <div class="float-right">
                <section id="login">
                    <asp:LoginView runat="server" ViewStateMode="Disabled">
                        <AnonymousTemplate>
                            <ul>
                                <li><a id="registerLink" runat="server" href="~/Account/Register">Register</a></li>
                                <li><a id="loginLink" runat="server" href="~/Account/Login">Log in</a></li>
                            </ul>
                        </AnonymousTemplate>
                        <LoggedInTemplate>
                            <p>
                                Hello, <a runat="server" class="username" href="~/Account/Manage" title="Manage your account">
                                    <asp:LoginName runat="server" CssClass="username" /></a>!
                                <asp:LoginStatus runat="server" LogoutAction="Redirect" LogoutText="Log off" LogoutPageUrl="~/" />
                            </p>
                        </LoggedInTemplate>
                    </asp:LoginView>
                </section>
                <nav>
                    <ul id="menu">
                        <li><a runat="server" href="~/">Home</a></li>
                        <li><a runat="server" href="~/About">About</a></li>
                        <li><a runat="server" href="~/Contact">Contact</a></li>
                    </ul>
                </nav>
            </div>
        </div>
    </header>
    <div id="body">
        <asp:ContentPlaceHolder runat="server" ID="FeaturedContent" />
        <section class="content-wrapper main-content clear-fix">
            <asp:ContentPlaceHolder runat="server" ID="MainContent" />
        </section>
    </div>
    <footer>
        <div class="content-wrapper">
            <div class="float-left">
                <p>&copy; <%: DateTime.Now.Year %> - My ASP.NET Application</p>
            </div>
        </div>
    </footer>
    </form>
</body>
</html>

下面還有一個ASP.NET MVC中的示例

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <header>
            <div class="content-wrapper">
                <div class="float-left">
                    <p class="site-title">@Html.ActionLink("your logo here", "Index", "Home")</p>
                </div>
                <div class="float-right">
                    <section id="login">
                        @Html.Partial("_LoginPartial")
                    </section>
                    <nav>
                        <ul id="menu">
                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                            <li>@Html.ActionLink("About", "About", "Home")</li>
                            <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                        </ul>
                    </nav>
                </div>
            </div>
        </header>
        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>
        <footer>
            <div class="content-wrapper">
                <div class="float-left">
                    <p>&copy; @DateTime.Now.Year - My ASP.NET MVC Application</p>
                </div>
            </div>
        </footer>

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)
    </body>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM