2012年2月23日 星期四

[ASP.NET]用Microsoft Ajax Minifier幫你的Javascript瘦身

前兩天在Plurk上看到91哥在談這個工具,一時興起之下就稍為玩了一下,發現還蠻有趣的,以下介紹給大家參考看看。
從Web 2.0興起後,使用者對於網頁互動的需求愈來愈大,不僅要求使用界面美觀,也希望操作功能的友善度上能與過去的Winform程式看齊,而為了達到更良好的操作效果,程式設計師不得不在網頁設計上加入許多的新元素(又或者說廣泛使用一些過去比較少用的技術),其中AJAX就是一個很熱門且廣為人知的技術架構,而眾家軟體大廠也陸續推出對應的AJAX Framework來協助我們進行開發,但AJAX除了帶更良好的人機操作外,也帶來了大量的Javascript,隨著我們使用的AJAX功能愈來愈多,網頁需要reference的Javascript file數目也愈來愈多,體積也愈來愈大,而這些改變都將反應在使用者進行網頁下載與Javascript執行時的效率。
若你使用了ASP.NET AJAX,基本的Javascript體積約200-300KB,若你使用了AjaxPro,則基本的Javascript約為80KB,Javascript雖然都會cache,但對使用者來說,第一次操作時的體驗多少都會受到影響。
因為網頁流量太大,Javascript太肥等問題,實際上微軟這邊都有提供了一些還不錯的方案,將以下三項做搭配,就可以獲得很不錯的效果:
    • IIS網頁壓縮:將IIS靜態檔案(html、CSS、JS…)、動態檔案(asp、aspx…)進行壓縮,可大大減少網頁流量,壓縮比設到最高時,大約可以將流量壓到剩30%左右。
    • DOLOTO指令碼分析:負責分析執行的script,只下載必要的script內容到client,並隨著client端的需要動態到server上去取得必要的部分,可減少不必要的流量。
    • AJAX Minifier:Javascript瘦身工具,可以將Javascript去除不必要的字元,包含空白、換行、符號與區域變數的名稱等,可直接的讓我們的JS file變成一個全新的runtime版本。
本篇主要針對AJAX Minifier來做說明。

AJAX Minifier

這個工具是隨著Microsoft Ajax Library Preview 6一起被release出來的,可以到這個地方下載:http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34488
clip_image002
下載完並安裝後我們可以在程式集中看到Microsoft Ajax Minifier,第一次使用建議你看一下Microsoft Ajax Minifier Documentation
clip_image004
安裝上十分的簡單,不過使用時可就要稍微留意了,這個工具目前仍算陽春,只提供了Command-line模式的操作,還沒有GUI的使用介面,這也是前頭我建議各位先看看Documentation的原因所在了,下方我們會簡單帶一下如何透過Command-line與MSBuild來使用這項好工具。

Introduction

不管使用任何工具,如果有Documentation,請務必觀看,在Introduction中我們可以看到這個工具的處理分成四個等級:
    • Level 1:去除空白(whitespaces)與註解(comments)
    • Level 2:去除不需要的分號(semicolons)與大括號(curly-braces),以下簡稱Normal-Crunching
    • Level 3:變更區域變數名稱,將名稱變更為簡單的名稱,以下簡稱Hyper-Crunching
    • Level 4:去除不會執行到的script內容

以上四個等級,Level 1~3可直接選擇Level 3來使用,但若要使用Level 4的話,建議你確認一下該段script是否真的不會執行到,以免衍生其他問題。

Command-line模式

首先我們開啟Microsoft Ajax Minifier Command Prompt
clip_image014
根據文件說明,我們有以下幾個較常用的指令可以使用:
    • -O:指定Minify後的檔案檔名,預設產出的等級為Level 2的結果(Normal-Crunching)。
    • -H:進行Javascript的瘦身,預設產出等級為Level 3的結果(Hyper-Crunching)。
    • -A:將分析過程的內容顯示在Command-line畫面上
接下來我們簡單的進行使用吧,首先我找了一個hash.js的檔案,其原始內容為大致如下,有完整的註解與Function定義,這對開發人員很有用,但是對runtime的使用者來說並沒有意義:
clip_image016
接著開始來試驗一下吧,先進行以下兩個指令Normal-CrunchingHyper-Crunching
Normal-Crunchingajaxmin C:\inetpub\wwwroot\WebSite2\hash.js o C:\inetpub\wwwroot\WebSite2\ hash _mini_O.js
將hash.js檔透過-O(Normal-Crunching)的指令轉成hash_mini_O.js檔:
clip_image018
按下Enter後顯示Crunching file hash.js’…Done.
clip_image020
以下則是轉完後的結果,檔案大小從5K-->2K,字元數從3891-->1699
clip_image022
Hyper-Crunchingajaxmin a -h C:\inetpub\wwwroot\WebSite2\hash.js o C:\inetpub\wwwroot\WebSite2\ hash _mini_A.js
clip_image024
按下Enter後它會將分析的結果印在Command-line的畫面上,這是因為我們使用了-a的指令:
clip_image026
以下是產出的檔案,乍看之下似乎差別不大,但這一份因為我們使用了-h(Hyper-Crunching)的指令,所以會發現一些區域變數被改名成比較簡單的命名,例如:var exists-->var a,所以這份檔案的大小雖然還是2K,但是其位元數為1531,比之前的1669更少:
clip_image028
由於這個js檔比較小,所以整個效果並沒有讓人感到特別驚人(5K-->2K),所以下面我們直接拿jQuery的js檔來試驗吧:
clip_image030
jquery1.3.1版,大小為115K,經過-O的指令後變為69K,經過-H的指令後變為53K,效果之好真的非常正點。

MSBuild模式

講完Command-line模式後我們繼續來說明MSBuild模式吧,透過Command-line模式多少還是會讓人感到有些綁手綁腳的,最好可以在佈署時就自動幫我們做掉就最好囉。
當我們裝好Minifier後,在這Program Files/MSBuild/Microsoft/MicrosoftAjax的路徑下可以找到一個AjaxMin.tasks檔案,這是一個MSBuild專用的task檔案,在我們專案建置時會呼叫這個task來進行Minifier的呼叫:
clip_image032
開啟我們的Web專案檔(*.csproj、*.vbproj),並在</Project>的結尾符號前加上這一段:
1<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
2<Target Name="AfterBuild">
3  <ItemGroup>
4    <JS Include="**\*.js" Exclude="**\*.min.js;Scripts\*.js" />
5  </ItemGroup>
6  <AjaxMin SourceFiles="@(JS)" SourceExtensionPattern="\.js$" TargetExtension=".min.js" />
7</Target>
clip_image034
以上的設定是告知專案編譯時要呼叫ajaxmin.tasks,主要進行的工作是找出目錄下所有的*.js檔,進行完Minify後將名稱命名為*.min.js,做完以上設定後我們再開啟我們的專案,這時候可能會出現以下的畫面,請選擇『以一般方式載入專案』,並按下確定:
clip_image036
接著我們在專案中隨便加入幾個js檔,如下:
clip_image038
接著請依照一般的使用模式,按下建置,這時候到我們專案的目錄下就可以看到以下的結果囉,不過這些檔案並不會自動幫你加入到專案中,這個設計也不錯,因為畢竟這兩份js一份是在design time,另一份是run time使用,不直接被加入專案是合理的:
clip_image040

 

結語

這個工具的使用大致如以上所述,希望對各位有幫助。

連結資料庫的語法&連結 ACCESS 資料庫時常見的錯誤

用ASP連結資料庫有很多種方法。由於不同類型的資料庫,所以我們需要用各自的連結語法來產生對資料庫的連接。

在自己的電腦,我們可以使用DSN(Data Source Name)來連接,方法是在控制台設定ODBC 連線,再在ASP用該DSN作開啟即可。但在一些免費空間,我們則須用DSN-less的方式連接資料庫,我們要在ASP中列出驅動程式名稱及資料庫位置。

通常指出資料庫位置是需要使用絕對路徑的,但我們並不知道我們的資料夾的位置究竟在哪裏,所以我們會用Server.MapPath("資料庫名稱")來取得絕對路徑。

因應各種資料庫,我列出以下資料庫的連接語法如下:
註:不可分行(除非使用 & _ 連結兩行字串才可分行)。在這裏分行是為了方便閱讀。
  [ ] 內的東西若設了密碼才需要用到,沒設密碼則必須刪除。使用連線字串時請刪除「[」和「]」。 
(資料來源:http://www.class2u.com/book/ultradev4/connection.htm)
-------------------------------------------------------------------------------------------
Microsoft Access
1.Driver={Microsoft Access Driver (*.mdb)};Dbq=資料庫;[Uid=使用者名稱;Pwd=密碼;]
2.Provider=Microsoft.Jet.OLEDB.4.0;Data Source=資料庫;[User Id=使用者名稱;Password=密碼;]

Oracle
1. Driver={Microsoft ODBC for oracle};Server=資料庫;[Uid=使用者名稱;Pwd=密碼;]
2. Provider=OraOLEDB.Oracle;Data Source=資料庫;[User Id=使用者名稱;Password=密碼;]

dBase
Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=資料庫;

Microsoft Text Driver
1. Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=資料庫;Extensions=asc,csv,tab,txt;
 Persist Security Info=False;
2. Provider=Microsoft.Jet.OLEDB.4.0;Data Source=資料庫;
 Extended Properties='text;FMT=Delimited'

Microsoft SQL Server
1. Driver={SQL Server};Server=伺服器;Database=資料庫;
 [Uid=使用者名稱(預設帳戶為sa);Pwd=密碼;]
2. Provider=SQLOLEDB;Data Source=伺服器;Initial Catalog=資料庫;
 [User Id=使用者名稱(預設帳戶為sa);Password=密碼;]

MySQL
driver={mysql};database=資料庫;option=16386;[uid=使用者名稱;pwd=密碼;]

Visual Foxpro
Driver={Microsoft Visual FoxPro Driver};SourceType=DBC;
 SourceDB=資料庫;Exclusive=No;

建立連線時,我們必須先建立連線元件,並因應該資料庫類型以上述連線方式連接資料庫。
假設資料庫路徑為在網頁底下的 abc.mdb (Access資料庫),使用者名稱為 abc 、密碼為 test ,你可以這樣作:

<%
Set objDBConn=Server.Createobject("ADODB.connection") '建立連線元件
objDBConn.open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
Server.MapPath("abc.mdb") & _
";User Id=abc;Password=test;"
'用連結字串開啟OLE DB的Access資料庫。注意,若您的資料庫沒設使用者名稱及密碼,則不需User Id及Password屬性。
'此時資料庫已經開啟,我們可以執行SQL指令或是建立資料集元件,請參閱其他相關文章。
'當執行完SQL指令或其他相關操作,我們可以叫那元件「回家睡覺」了。
objDBConn.Close
Set objDBConn=Nothing
'關閉資料庫元件連接,釋放系統資源,「回家睡覺」去
%>



連結 ACCESS 資料庫時常見的錯誤

--------------------------------------------------------------------------------

當物件關閉時不允許操作
ADODB.Connection (0x800A0E78)
當物件關閉時,不允許操作。
/guestbook/save.asp, line 100


當您尚未 rs.open 開啟資料庫時,即欲執行讀取資料庫的指令;或資料庫已經關閉,您卻重覆下達 rs.close 
關閉資料庫指令;也可能是指令 rs.close 放置不當,導致資料庫提前被關閉,後續程式無法執行。 

--------------------------------------------------------------------------------

無法指出的錯誤
Provider (0x80004005)
無法指出的錯誤
/db/file.asp, line 8


發生這個錯誤訊息的實際原因是相當複雜的,在此僅針對虛擬主機用戶最常見的因素提供說明。倘若您的程
式原先能夠正常執行,卻突然之間出現以上訊息、導致整套程式無法正常運作時,絕大部份都是由於您的程
式碼所產生的問題。例如:當您的程式開啟資料庫之後,卻沒有按照規定程序下達「關閉」與「釋放資源」
的指令,就可能出現這個錯誤訊息。所謂「關閉」與「釋放資源」的指令有:
  rs.close (關閉指令;左列英文字敘述僅供參考之用,切勿照抄)
  set rs=nothing (釋放資源指令;左列英文字敘述僅供參考之用,切勿照抄)
當您的程式沒有按照規定程序下達「關閉」與「釋放資源」的指令,還可能會因此引發更多的錯誤訊息。 

--------------------------------------------------------------------------------

無法開啟 '(未知的)' 資料庫。
它可能不是一個您的應用程式所能認得的資料庫,或是檔案可能已經損壞。
Microsoft JET Database Engine 錯誤 '80004005' 
無法開啟 '(未知的)' 資料庫。它可能不是一個您的應用程式所能認得的資料庫,或是檔案可能已經損壞。
/db/file.asp, line 8


發生這個錯誤訊息的實際原因是相當複雜的,在此僅針對虛擬主機用戶最常見的因素提供說明。倘若您的程
式原先能夠正常執行,卻突然之間出現以上訊息、導致整套程式無法正常運作時,絕大部份都是由於您的程
式碼所產生的問題。例如:當您的程式開啟資料庫之後,卻沒有按照規定程序下達「關閉」與「釋放資源」
的指令,就可能出現這個錯誤訊息。所謂「關閉」與「釋放資源」的指令有:
  rs.close (關閉指令;左列英文字敘述僅供參考之用,切勿照抄)
  set rs=nothing (釋放資源指令;左列英文字敘述僅供參考之用,切勿照抄)
當您的程式沒有按照規定程序下達「關閉」與「釋放資源」的指令,還可能會因此引發更多的錯誤訊息。 

--------------------------------------------------------------------------------

此處需要物件
Microsoft VBScript 執行階段錯誤 (0x800A01A8)
此處需要物件: 'rs'
/GuestBook/loveadam.asp, line 168


一般而言,是您開啟資料庫所使用的宣告方式與找尋資料的類型不一致或尚未定義所導致的。例如您若使
用 Set rs2 = GetMdbRecordset( "loveadam.mdb", SQL ) 定義,但稍候卻使用到 IF not rs.eof THEN ..... 或者是
想從資料庫帶出某些欄位的資料 session("User") = rs("User") ,但由於 'rs' 尚未正確定義或者呼叫程序有錯
誤時,就會出現這一個錯誤訊息。 

--------------------------------------------------------------------------------

類型不相符
Provider 錯誤 '80020005'
類型不相符。 
/news/save.asp, 列100


當程式本身執行「類型錯誤的蒐尋」或「資料庫欄位類型與實際儲存資料無法相容」時,即會出現此一
錯誤訊息。以下僅針對資料庫類型方面的錯誤,進行解說:
當您的 Ms-Access 資料庫某欄位的預設 "資料類型" 與存檔資料發生衝突時,即會出現錯誤 。 例如,資
料庫中的 NUMBER 欄位,若預設祇能儲存阿拉伯數字,但您卻試圖將中文字資料存入 NUMBER 欄位。
倘若欲在 NUMBER 這個欄位儲存中文字或其他資料,您可運用 Microsoft Access 程式開啟整個資料庫,
將 NUMBER 欄位原本預設的 "資料類型" 修改為「文字」類型或「備註」類型即可。 

--------------------------------------------------------------------------------

無法開啟登錄鍵
[Microsoft][ODBC Microsoft Access Driver]一般錯誤 無法開啟登錄鍵 'Temporary (volatile) Jet DSN for
process 0x898 Thread 0x914 DBC 0x209e024 Jet'


嚴格說起來,會出現這個錯誤訊息的情況有頗多的因素。一般最常見的是程式呼叫資料庫的路徑設定有
錯誤,例如虛擬目錄或實體目錄的路徑在語法使用上有錯誤。除此之外,當程式試圖要從資料庫讀取或
寫入一筆資料,但資料庫並不存在指定的欄位定義值時,或者資料庫設有密碼,因為密碼錯誤而無法順
利開啟資料庫的時後,都會出現無法開啟登錄鍵的錯誤訊息。若您是使用自己的主機架設網站,則需確
認資料庫與資料庫所在資料匣,一般訪客使用者是否擁有讀取與寫入資料的權利。 

--------------------------------------------------------------------------------

無法更新資料庫
Microsoft OLE DB Provider for ODBC Drivers (0x80004005)
[Microsoft][ODBC Microsoft Access Driver] 無法更新。資料庫或物件是唯讀的。


請檢查資料庫這一個檔案,是否本身已被設定為唯讀屬性(將滑鼠置於資料庫再按下右鍵選「內容」,
將可以設定資料庫的屬性與讀寫的權限)。此外,也有可能是您之前的程式碼撰寫的並不完整,將資料
庫開啟使用但最後沒有下達關閉指令,導致其他程式無法再讀取及寫入資料,這時您必須先將開啟的資
料庫予以關閉,才能正常執行後續的程式碼。若您是使用自己的主機架設網站,則需確認資料庫與資料
庫所在資料匣,一般訪客使用者是否擁有讀取與寫入資料的權利。 

--------------------------------------------------------------------------------

找不到包含檔
Active Server Pages 錯誤 'ASP 0126' 
找不到包含檔


程式碼設計者,為了節省撰寫程式碼的時間,將呼叫資料庫的語法藉由副程式進行,但因為系統找不到
副程式檔案或找不到其他指定要求載入的附加檔案,故出現這一個錯誤訊息。比較常見的錯誤情況是,
使用者搞不清楚網站根目錄和子目錄的互動關係,例如在子目錄下面執行程式,但副程式卻擺放在網站
根目錄或其他子目錄下面,而程式碼卻沒有返回上一層或進入正確的子目錄尋找。當然,也有可能是您
因為一時疏忽,沒有將程式整套完整的上傳所導致的。 

--------------------------------------------------------------------------------

找不到檔案
Microsoft JET Database Engine (0x80004005) Could not find file 'C:\Inetpub\wwwroot\loveadam.mdb'.


正如同系統回應給您的訊息一般,伺服器在ASP程式所指定的路徑下面,找不到指定的檔案或資料庫。

--------------------------------------------------------------------------------

找不到檔案
Microsoft JET Database Engine 錯誤 '80004005' 
'C:\Inetpub\wwwroot\loveadam.mdb' 不是一個有效的路徑。請確定路徑名稱是拼對的,而且檔案位於您
所連接的伺服器上。 


正如同系統回應給您的訊息一般,伺服器在ASP程式所指定的路徑下面,找不到指定的檔案或資料庫。
倘若您是租用本網虛擬主機網站代管服務的用戶,請查閱啟用通知信件(信中有記載您的網站實際存放
的目錄位置)。

--------------------------------------------------------------------------------

資料表被鎖定
Database Engine error '80004005' Table 'tblTable' is exclusively locked by user 'Admin' on machine
'MyMachine'.


當您使用自己的主機架設網站,在執行程式的之前,您也開啟資料庫進行設計與修改,導致程式對於資
料庫沒有執行的權限。這一個錯誤情況,通常不會在虛擬主機上面發生。 

--------------------------------------------------------------------------------

參數太少
Microsoft OLE DB Provider for ODBC Drivers 錯誤 '80040e10' 
[Microsoft][ODBC Microsoft Access Driver] 參數太少,預期個數 1。


這一類型的錯誤,通常都是程式中SQL所下達的指令有錯誤,或是指定的欄位名稱與資料庫的實際資料
表的欄位名稱不符合。除此之外,也有可能是SQL下達指令運用到的變數值,您尚未給予定義。 

--------------------------------------------------------------------------------

BOF 或 EOF 的錯誤
ADODB.Recordset 錯誤 '800a0bcd'
可能是 BOF 或 EOF 的值為 True,或目前的記錄已被刪除。應用程式所要求的操作需要目前的記錄。


當使用者執行程式時,若在資料庫找不到符合的資料,或是資料筆數為零的時候,都可能會出現這個錯
誤訊息。一個有經驗的程式設計人員,為了避免這個錯誤情況的發生,通常會將程式碼撰寫的更理想,
例如當程式查無符合資料時,出現適當的訊息告知使用者或訪客。例如在SQL蒐尋指令後加入:
<%
IF RS.EOF THEN
Response.Write "非常抱歉,目前沒有任何符合的資料。"
Response.End
END IF
%> 

--------------------------------------------------------------------------------

運作必須使用更新查詢
Microsoft OLE DB Provider for ODBC Drivers (0x80004005)
[Microsoft][ODBC Microsoft Access Driver] 運作必須使用更新查詢


會造成這一類型的錯誤原因有很多, 例如在SQL程式語法中的指令無法讓伺服器理解,或者是一些運算
方式及符號(例如引號、括號)標示位置不當或缺少符號標示,都可能會出現這一類型的錯誤訊息。倘
若您是使用自己的主機架設網站,則需確認資料庫與資料庫所在資料匣,一般訪客使用者是否擁有讀取
與寫入資料的權利。