建立高效能移動 web 站點

oschina發表於2013-08-15

  如果你的網站3秒鐘沒有響應,人們就會失去興趣了。為了滿足響應快這個願望,需要一個不同的方法在手機上進行分析,設計和測試。

  這篇文章將會對Johan Johansson在2013年4月提出" 怎樣讓你的網站在手機上也很快"的這種理念進行擴充套件。我們將提出論證方法來確認人們在手機上與網站的互動方式和以前是不一樣的,特別是設計也是基於此理念的。我們的目標不僅僅是提高網站效能,而且也要增加客戶收入的。

  我們將關注手機兩個特性,這兩個特性短期內也不會有變化:電池容量小,螢幕小。

  電量小

  手機的通訊要用無線電,但手機的電池很小,所以要非常謹慎的用電以防止把電用光。這樣,如果無線電不用的時候就會迅速關掉,這樣就增加了網頁出現的時間。2G和3G無線技術需要2秒鐘來建立HTTP連結。如果我接受“使用者會在3秒後失去興趣”的觀點的話,那我們的網站只有1秒來響應了。想想這“黃金般的一秒”吧。

  最大化利用這“黃金一秒

  小螢幕

  在物理世界中,廣告牌和雜誌的內容都是根據媒介的大小和觀看距離來定製的。在數字世界中,一個典型的中檔智慧手機擁有幾乎6平方英寸大小的螢幕。15英寸的MacBook Pro電腦螢幕擁有超過100平方英寸的大小。這樣,我們不僅可以通過減少傳送到手機端的內容優化網站效能,而且可以優化業務流程來提高網站所有者的投資回報。

  本文的程式碼示例是由.NET提供。我已經在companion article文章中展示了用PHP, Java, C 和Python達到同樣的效果。我在這篇文章的結尾會解釋為什麼選用.NET。  

  最大化利用 “黃金一秒”

  網站設計者和開發者們常常想當然的認為使用者應該用高頻寬Wi-Fi和固網來連線。響應式網站設計(RWD)強制在不同裝置上(不論其效能好壞)顯示相同的內容、導航和業務流程,限制了創新。

  確保我們能夠容易的進行效能測量,進行使用者行為監控的基於不同裝置特性的解決方案以及低頻寬裝置網頁訪問優化都需要最大限度的利用這“黃金一秒”。

  模擬現實網路

  現實移動頻寬模擬測試是一個必不可少的移動Web效能測試。很多100美元以下的廉價無線路由都提供了限制頻寬功能,測試僅僅只涉及到了區域網內的客戶端的上行和下行頻寬限制功能。如果路由不支援這個功能話,那麼試試用 DD-WRT(DD-WRT是一個開源升級韌體,可以替代目前主流路由的預設作業系統)來限制頻寬。

  我用DD-WRT升級了Linksys E3000路由。路由升級的過程非常簡單,DD-WRT官網上提供了完整的說明。

  安裝好DD-WRT後去到QoS選單,啟用頻寬限制。設定上行和下行頻寬的值,我習慣將下行頻寬設定為256kbps,上行頻寬設定為28kbps來模擬行動網路的平均頻寬。

Bandwidth Monitoring.
在“Quality of Service”選項中限定頻寬

  現在無論是以Wi-Fi或網線連線到路由器的裝置的頻寬都被人為的限制了。我們可以監視頻寬實際的使用情況。

Bandwidth Monitoring.

用DD-WRT監視頻寬使用

  雖然這種測試方法並沒有包括隨機的掉線、可變頻寬條件和由訊號強弱引起的延遲等情況,但是比起你在快速、低延遲頻寬下做的其他測試效果要好。在網站開發初期,這是一個在開發過程中對Web效能進行非正式測試的簡單的方法,能夠確保你在正式測試過程中不出現任何討厭的問題。

  你不能管理所不能測量的事

  管理顧問 Peter Drucker 曾經說過一句名言:“如果你無法測量某件事,你就無法管理它。”

You can't manage what you can't measure.

平均螢幕尺寸隨時間的推移的增長情況

  持續根據裝置特性(比如無線支援或螢幕大小)對使用者檢視的內容進行監控,或多或少將會有助於你識別手機上流行的內容和服務。也許你將看不到任何區別,但是除非你測量過,否則無法確定。

  例子:“現在我要吃”站點

  一個全球化的快餐特許經營店需要建立針對移動終端的大螢幕網際網路站點的優化版本。在建立第一個針對移動終端優化的網際網路站點之前,執行分析以確定大螢幕網際網路站點的哪些項是小螢幕裝置的使用者可以訪問的。主選單、特賣品和分店查詢是最受歡迎的,因此建立針對移動裝置優化的網際網路站點就集中在這些方面。

  工作不能停留在此。接著的分析顯示出分店查詢是最受歡迎的。因此再次修改移動裝置的主頁以關注分店查詢。繼續的監視顯示出多少訪問者選擇其他選項,然後依此不斷改善地這個網際網路站點,以確保用最簡單可行的方法實現最受歡迎的欄目。

  好的日誌

  Google Analytics 提供了一些關於裝置模型的資訊,但它缺乏我們需要基於螢幕尺寸和輸入方法作出明智決定的細節。幸運的是,一個全面的裝置檢測庫(DDR)可以將此資訊新增到現有日誌檔案中。下面的程式碼片段可以新增到 .NET網站中,參考51degrees.mobi(可通過   NuGet  ) 獲取螢幕的物理尺寸和輸出到一個簡單的CSV檔案中。

// Write a log file containing the current time, and the screen
// size of the requesting device in inches.
File.AppendAllText(
    Path.Combine(
        AppDomain.CurrentDomain.BaseDirectory, String.Format(
            "App_Data\\Simple_Log_{0:yyyyMMdd}.csv",
            DateTime.UtcNow)),
    String.Format("{0:s},{1},{2},{3}\r\n",
        DateTime.UtcNow,
        Request.Path,
        Request.Browser["ScreenInchesWidth"],
        Request.Browser["ScreenInchesHeight"]));

第一行是處理請求的日期和時間。第二行是請求的頁面。最後兩行是裝置螢幕的寬度和高度。抓取足夠多的資料和平均螢幕的尺寸大小繪製出了下面的圖表:

Screen sizes per month.

  比較裝置螢幕的平均大小超過20個月 

  分析可以縮小到具體的頁面。有關裝置的特性,作業系統和瀏覽器也可以被新增到列中。

  類似的程式碼可以使用PHP、Java、Python和其他環境語言。

  已有的日誌檔案

  有時,已有的Web頁面不能按照上面的方式修改。在這樣的情況下,DDR可以用來執行含有使用者代理的日誌日文的離線分析了。下面的.NET程式碼是一個實用的命令列程式,它解析空格分隔的日誌檔案,然後計算出日誌所表示的請求以平方英尺為單位的平均螢幕尺寸。第一個引數是日誌檔案的位置,第二個引數是日誌檔案裡使用者代理所在列的索引。

using System;
using FiftyOne.Foundation.Mobile.Detection.Binary;
using System.IO;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            // The number of devices read from the log file.
            int count = 0;

            // The column in the input file the user agent is held in.
            int column = int.Parse(args[1]);

            // Screen dimension variables.
            double total = 0, width, height, squareInches;

            // Create a provider to determine the device capabilities.
            var provider = Reader.Create("51Degrees.mobi.dat");

            // Read each line of the log file provided in argument  0.
            // Assume the value at column 8 is the UserAgent string.
            using (var reader = File.OpenText(args[0]))
            {
                while(reader.EndOfStream == false)
                {
                    var values = reader.ReadLine().Split(new[] { ' ' });
                    if (values.Length >= column)
                    {
                        // Get the device information based on the UserAgent.
                        var device = provider.GetDeviceInfo(
                            values[column - 1].Replace("+", " "));
                        if (device != null)
                        {
                            // Determine the screen dimensions in inches.
                            double.TryParse(
                                device.GetFirstPropertyValue("ScreenInchesWidth"),
                                out width);
                            double.TryParse(
                                device.GetFirstPropertyValue("ScreenInchesHeight"),
                                out height);
                            squareInches = width * height;
                            // If valid values are available (not a desktop/laptop)
                            // then add the values to the results.
                            if (squareInches > 0)
                            {
                                total += squareInches;
                                count++;
                            }
                        }
                    }
                }
            }

            Console.WriteLine(
                "Average screen size '{0:#.00}' square inches from '{1}' devices", 
                total / count,
                count);
            Console.ReadKey();
        }
    }
}

  分析日誌檔案很不準確,因為除了使用者代理外的其他HTTP頭都影響著檢測結果。對Opera Mini和Opera 移動瀏覽器來說尤其是這樣的。在這兩個瀏覽器裡,第二個HTTP頭,也就是名字為Device-Stock-UA的頭常常用來提供標準使用者代理裡沒有的有關物理硬體的資訊。

  為什麼監控?

  監控使得我們能夠將不受歡迎的內容從主頁中刪除,以此提升更重要的內容或相關的內容的效能。刪除的內容應該仍可以通過二級頁面訪問到——只是不放在首頁,不然的話它們會消耗寶貴的頻寬並降低效能體驗。

  那麼,我們怎樣來建立一個獨立的效能優化的移動網站呢?

  分而治之

  我能理解為什麼RWD(響應web設計)從使用者介面設計的角度來說很有意義。對於6平方英寸螢幕和10平方英寸螢幕,以及僅僅是需要進行改動的佈局來說,在內容,導航以及業務流程需求方面可以完全一致,這實在是太棒了。

Device screen sizes.

平均裝置螢幕尺寸。

  但是,在上述條件不為真或者對效能要求嚴格的時候有一個獨立的移動網站 具有特別的意義。

  獨立的移動網站常常表現出一種不良的使用者體驗。通過給網站懲罰賦以較低的搜尋引擎等級,Google現在投射出一縷曙光 到這些普通的問題上。問題包括了將每個桌面頁傳送到單獨的移動主頁,重定向到應用下載頁,阻止使用者訪問大屏的網站,對所有帶特定作業系統的裝置以相同的方式處理。

  這些糟糕的實現讓人對這些概念有一個壞的印象。這裡是一些簡單又正確的做法。

  下面的 .NETweb.config片段將把來自智慧手機的第一個請求,重定向到網站上“Smartphone”部分指定的等價頁面。 重要的是,查詢字串與頁面名字在重定向的過程中一直保持著。

<redirect firstRequestOnly="true" 
	mobileHomePageUrl="~/Mobile/Default.aspx"
	timeout="20"
	devicesFile="~/App_Data/Devices.dat"
	mobilePagesRegex="/(Mobile|Smartphone)/" >
	<locations>
		<!--Send smartphones to an equivalent version of the original page, preserving the page name and query string.-->
		<location name="smartphone" url="~/Smartphone/{0}" matchExpression="(?<=^\w+://.+/).+">
			<add property="IsSmartphone" matchExpression="true"/>
		</location>
	</locations>
</redirect>

  在大多數情形,當重定向到替代頁面時,如果願意的話使用者應當可以返回原始的頁面;或許他們對網站的大螢幕版本更熟悉呢。firstRequestOnly屬性保證了只有來自裝置的第一次請求才被重定向。devicesFile屬性是用來對不支援cookies的裝置進行跟蹤。timeout屬性控制了在多長時間內該裝置被記憶(為了重定向的目的)。

  重定向系統還必須知道哪個頁面是針對哪種裝置設計的。mobilePagesRegex屬性被應用到請求URLs。如果存在匹配,頁面將不適用重定向。這阻止了無窮重定向的情況。

  locations元素允許配置定義不同的地址,以及相關的規則。這個例子將Smartphone目錄插入到原始的URL。查詢字串和其他的URL資訊在重定向過程中一直保持。所有影響到請求上下文的資訊必須被傳送,以便使用者獲得他們期望的內容。

  這個簡單的方法使得一個搜尋引擎友好的,相容Google的,移動手機優化的網站,在傳送的過程中有良好的使用者體驗和優異的效能。這個過程的基礎是DDR,它快速的,一致的,精確的提供了裝置的資訊。對於改變了移動手機瀏覽器設定到桌面模式的使用者,重定向將不會發生。

  警惕雲

  雲服務是給網站迅速增加特性的流行方法。但是它們跨越Internet的請求對效能帶來損耗。如果忽略處理時間,我們觀察到由Amazon Web Service提供的雲服務的資料傳輸有平均200毫秒的延時

  200毫秒是一個黃金秒的20%。因此,仔細考慮一下你使用的雲服務在哪裡,確保它們是非同步呼叫的,以便在等待響應的過程中其他處理能繼續下去。它們應該避免關鍵路徑上的活動,例如判別請求裝置的資訊。

  壓縮內容

  緊隨視訊、影象之後,CSS和HTML佔據了大量的Web流量。我們需要優化所有這一切的方法。視訊本身就是就可以寫一篇文章,所以要等以後再說。

  影象

  流行的解決方案是同一張影象提供三個版本,而且當瀏覽器渲染頁面的時候,使用JavaScript或者CSS選擇最適合請求裝置的那張圖象。這是一個好的開始,不過管理同一影象的不同版本卻是很痛苦的;影象從來都不是完美優化的,而且這種方法給有限CPU和電池電量的移動裝置增加了進行影象大小調整的負擔。

  有一個更好的處理方法是使用影象優化器。可以通過Viusal Studio的整合開發環境把52Degrees.mobi的影象優化器增加到ASP.NET站點。下面的配置將自動增加到web.config裡。

<handlers>
	<add name="Image" verb="GET" path="P.axd" type="FiftyOne.Framework.Image.ImageHandler, FiftyOne.Framework" />
</handlers>

  上面的處理器告訴網際網路資訊服務(IIS)影象處理器應該處理資源P.axd的任何GET請求。

  一旦web.config裡啟用這項,下面的ASP.NET程式碼將使用影象優化器從三種可能的資源-也就是分別為240,480和640畫素寬的影象中確定一個影象。

<mob:Image runat="server" ID="ImageBanner" CalculateSizeMode="ClientWidth" Style="clear: both; width: 100%">
	<mob:AltImage ImageUrl="~/Images/Landscape240.png" />
	<mob:AltImage ImageUrl="~/Images/Landscape480.png" />
	<mob:AltImage ImageUrl="~/Images/Landscape640.png" />
</mob:Image>

  當初始化顯示影象的時候,伺服器將傳送一個白色的1x1畫素的GIF顯示在影象所在位置。下面就是生成的HTML:

<img id="B" src="P.axd?i=E.gif&i=1"/> 

  一旦頁面裝載完成,JavaScript用來算出最終顯示影象所需要的真正的尺寸,然後向伺服器請求一個大小明確的影象。經過JavaScript處理後,上面的HTML轉換為:

<img id="B" src="P.axd?i=1&w=500"/> 

  web.config中引用的影象處理器把i查詢字串關聯到影象源,因此伺服器上最適合的影象將用作調整的最初影象。w查詢字串引數指定了所請求影象的寬度。因此不需要提供多個影象;一個單獨的影象幾乎就可以了。 這種方法易於實現,而且結果是大小明確的影象。這樣做不但減少了頻寬,而且還減少了行動電話CPU的執行週期和電量。

  HTML

  整個牛津大辭典包括171476個單詞。如果一個電腦用獨有的二進位制數字代表一個單詞,而不是一個字母表的字母,大概需要用18位元(向上舍入大概3位元組)。這表明壓縮演算法是十分有效的。

  然而,HTML不是很有效,因為它充滿了用字元代表的元素、IDs,類,styles和Javascript,沒有考慮到是否是人可讀的。壓縮可以減少這些,但還是要有開銷的。這就是為什麼流行的庫都有人們讀不懂的壓縮版本。

  在伺服器傳送給瀏覽器之前,一些與標記相關的單詞還可以最小化,而且不會丟失任何這些單詞的意義。看一個上面所示的影象的例子,ASP.NET裡標準的HTML的影象元素的ID屬性是ImageBanner。

<mob:Image runat="server" ID="ImageBanner" CalculateSizeMode="ClientWidth" Style="clear: both; width: 100%">

  然而傳送給瀏覽器的程式碼只使用B。對一個單獨的元素來說。這樣的效能改進是微不足道的,然而,對一個含有數百個元素的複雜頁面來說,傳送這樣的頁面會更快,而且瀏覽器將能更快地處理這一切。

  Includes

  影象例子生成的HTML看起來比較奇怪:

<img id="B" src="P.axd?i=1&w=500"/> 

  這段ASP.NET程式碼沒有樣式而且也沒有為img元素設定CLASS屬性。那麼它的樣式是怎麼來的呢?

  伺服器端最小化過程中將會確定樣式資訊,並且為網頁建立一個CSS檔案,從而減小了HTML的大小。當HTML變化時,樣式已經被快取在瀏覽器中,不需要重新下載。CSS片段看起來就像這樣:

#B{clear:both;width:100%;} 

  如果許多元素共享同一個樣式,那麼就要給這個CSS增加ID屬性,這樣它們就可以共享相同的資訊。

  還可以通過使用伺服器端樣式元素實現在多個元素和頁面上共享樣式資訊。下面的程式碼擴充套件了前面影象例子,以此來說明共享樣式元素。

<mob:Style runat="server" ID="StyleBanner">
	<mob:Filter Style="clear: both; width: 100%"/>
</mob:Style>

<mob:Image runat="server" ID="ImageBanner" CalculateSizeMode="ClientWidth" StyleID="StyleBanner">

  根據裝置的能力,還可以對這個元素進行進一步擴充套件,使得可以應用其他樣式,並且可在多個頁面上優化樣式表。 這種技術總是確保只傳輸必須的CSS,因此在對同一個頁面的後續請求方面提高了效能,尤其是對HTML內容只有稍稍不同的頁面。

  為什麼選擇.NET?

  上面所示的影象優化和動態最小化HTML和CSS內容的技術和程式碼例子取決於頁面渲染之後且伺服器傳送給瀏覽器之前更改的內容。這樣的預處理技術在諸如ASP.NET的Web表格這樣的結構裡實現起來相當容易。

  然而在基於指令碼的比如PHP這樣的架構裡實現它們就非常複雜。正是由於這個原因,並且為了保持一致性,這篇文章中的例子都是在.NET上的。我們已經能夠把這種技術應用到其他語言上,例子程式碼可在朋友部落格裡看到。

  例子

  公共衛生基金會的企業實現了本文中提到的技術,並在第一週成功提高了23%的效能。

  其他比較注重效能的網站包括 24.com(媒體),ServiceTick(分析),LettingWeb(財產),AdSupply(廣告)和Kitsap Credit Union(金融)都使用了本文提到的部分或是全部的技術來優化他們的移動站點。

 總結

  為了真正地優化效能,我們需要考慮網站所有人的投資回報。監測裝置特徵的不同是根本起始點。

  然後我們才能部署諸如利用分散的移動網站來分離或改變內容焦點的解決方案。我們還能通過收緊縮小影象和HTML,移除jQuery,問詢何時單獨使用響應式網站設計(RWD),以及其它技術等使效能達到最高。當然,現有的技術也是至關重要的,例如配置快取路徑和壓縮內容。

  微調我們的開發環境,來模擬真實世界的情況,這樣也可以在整個開發過程中獲得對效能的更好的理解。

  現在就優化

  為了能讓你更多地考慮效能,我已經設定好了一個尋找世界上最重型的網站的競賽。尋找一個網頁,它在行動電話上執行得很糟糕,並將其提交給競賽。我們會比較頁面的分量,以及它是否是最重型的,你將因此而贏得1000美元。與此同時,實現本文以及其他Smashing Magazine中的牛文中提到的技術,以確保你的網站在被我們掂量其效能的時候不會出現在榜單之首!

  從未有過比這更能提高你的網站效能的機會了。

  原文地址:creating-high-performance-mobile-websites

相關文章