Why Master Page, But Not Frameset?

跟同事討論新網站如何讓所有網頁都保持一致的Header/Menu/Footer,我的看法是回歸ASP.NET 2.0建議使用的Master Page、同事則覺得這樣比較笨重,不如保持用FrameSet切割出一塊Frame切換內容的傳統做法即可。想了想,到ASP.NET 2.0後,看到的幾乎都是用Mater Page解決,VS 2005 IDE甚至會在你使用FrameSet時發出警告;另外一方面,除了ASP.NET之外,印象中現在Internet中遊歷到的大小網站,除了一些上了年紀的簡單小網站,已經很難看到用Frame切割Header/Menu的做法。雖然腦中大致了解二者間的差異,但Frame式的設計似乎已快從地球上絕跡了,為什麼?

好奇地針對這個問題,Google了一下,以下是我的心得。

首先,要做出全站一致的Header/Footer,有幾種做法:

  • Copy & Paste大法! 把Header/Menu/Footer的Code複製到每一個網頁。
    (你瘋了嗎? 誰敢給我用這種方法設計網站,我一定用鍵盤打爆他的頭!!)
  • Frameset: 每次只更換Content Frame網頁,缺點是會有Cross-Frame Scripting的Issue,而且有可能Frame間更新狀態不同步。
  • 利用Server-Side Include: 可用在ASP,但每一頁都要配合排版位置插入。
  • 利用User Control: 可用在ASPX,但每一頁要配合排版位置擺放。
  • Master Page: 利用類似繼承的概念,內容頁不必過問Header/Footer的排版設計,但每次執行都要重新產生Footer/Header元素。

以上這些做法,在ASP.NET 2.0中,大概只剩下Master Page及Frameset兩種要抉擇。Master Page可以確保直接使用內容頁的URL也會看到完整的版面設計,用Frameset則可能瞧見沒有Header/Footer的裸體版內容頁,這在Search Engine點選查詢結果時最可能發生。但Master Page的每一頁都要重新載入、產生及傳輸Header/Footer也是不爭的事實,比Frameset有更多無謂的消耗。

找到一篇不錯的剖析,列舉了採用各架構的最佳實務:

Master Page

  • 不介意每次全頁更新
  • 需要彈性化的繼承式版型設計,且使用者不在意全頁更新
  • 希望每一頁都被獨立檢視時,都可以完整呈現

ICallbackEventHandler

  • 只想局部更新頁面的部分資料或圖片
  • 只想局部更新頁面上一些簡單的HTML元素(不含asp: Controls)

XML Data Islands

  • 在Client建立資料儲存,建少網頁點擊更新次數

FrameSet

  • 不希望全頁更新
  • 具有複雜的網頁元件,必須從Server端產生更新(不能只換Data)
  • 網頁上不同的區域需要用不同的頻率更新

不過,由這些分析,我還是無法理解大部分網站捨棄Frame的理由,看到不少人說"Frames Are Evil"(相信嗎? 居然有個"我恨Frames俱樂部"!),卻沒足夠的理由讓我完全信服。我所知道Frame的缺點包含四點:

  1. Cross-Frame Scripting比較曲折,但只要不是Cross-Site,並不難解決。
  2. Frame間可能發生更新不同步,例如: Header Frame的Logon User與Content Frame的不是同一人。
  3. Browser顯示的URL無法準確反應內容Frame的變動,譹Brower的標籤功能(IE我的最愛)頓成廢材。
  4. 當使用者使用Content Frame用的URL連上網站,看到的不是完整網站呈現版型。目前Search Engine記錄及Index的特性,這種狀況挺常發生的,但我不敢斷定這就是Frame漸漸被揚棄最主要的理由。

於是我又做了些挖掘,看看可否找出Frame有更多我不知道的黑暗面? 以下是我又挖到的一些補充:

  • Frame讓Browser的列印功能變得不直覺
  • Frame導致Browser的Refresh行為與使用者的預期有出入

不過,歸納了以上的種種剖析,我認為Frame有些缺點,但罪不至死,不需反應過度。在某些情境下,用Frame仍OK,如果:

  • 網站為內部使用,不在乎Search Engine Friendly
  • Header/Menu/Footer的演算及HTML很複雜,值得省下這個資源成本
  • User連線頻寬有限,需要儘可能減少資料傳輸量(Update 2007-11-19)

至於我,應該還是會回歸Master Page,理由是盡量用別人在用的方法做事,出問題時可以多些難兄難弟,也多點相關討論可以參考;萬一被Challenge時還可以說,"嘿! 別怪我,我是照著微軟建議的方式處理的",然後把頭埋到沙子裡繼續睡午覺,哈!!

歡迎推文分享:
Published 18 November 2007 06:30 PM 由 Jeffrey
Filed under: ,
Views: 47,173



意見

# KKK said on 18 November, 2007 08:33 AM

頗為有趣的剖析

題外話,小弟目前正跟一家腦袋XX的客戶打交道,在已經delay的狀況下,要求我們把Master Page全部換成Frame

理由是 : 要跟之前的OOO系統長得一樣

我也有想拿鍵盤打爆他們腦袋的衝動 XD

# Ken Lai said on 19 November, 2007 08:06 AM

frame也許還有一點是較少人考量的缺點---就是有很大的機會會對身心障礙者透過特殊機器來"瀏覽"(或"聽")網頁時有可能無法了解全貌。

其實這也是目前大多數網站的缺點,有的都限ie開啟了,又怎麼會考慮到身心障礙者?

# 小菜 said on 19 November, 2007 11:08 PM

我個人也投master page一票,不過我還有搭配AJAX的部份頁面更新,如果頁面中有些處理時複雜,我還會搭配lightbox來將整個畫面控制住或暫時將該Control Disable,以防止User這個時候多送出幾個submit。

# Ark said on 23 November, 2007 03:20 AM

其實Master Page也是可以和Frameset結合的

只是再設計上要多做一些處理

如果先前ASP設計習慣喜歡用form submit 做傳值的動作

將原本active=XXX 轉換到Button.PostBackURL

target =YYY 一樣可以包在Master Page內的form裡面

這樣就能在大架框Frame下弄得更花俏了

再說Include 這招

也是可以含在Content內用Response.WriteFile("(檔案名稱)")

不過這些多餘的動作~老闆會和你算成本嗎?

# 潼恩 said on 29 November, 2007 12:40 AM

  最近也在用ASP試著更新公司的網頁…

  因為公司的網頁實在是太慘了~囧a

  我在一開始也直覺式的想要使用目前大部分網站所顯示的樣子,頁面架構不變但內文會跟著變的模樣。雖然是有想過用Frame,但…

  一陣子沒碰程式了,因此摸索了許久,在今天才搞清楚我要用的功能在ASP.Net 2.0有,正是Master Page這功能…囧a

  我覺得,不用Frame最主要的原因大概是……

  看起來很遜(被毆飛)

  今後可能要請J大多多指教了~囧a

# 潼恩 said on 03 December, 2007 08:45 PM

請教~

  距離上次認真的寫程式已將近十年餘…,出社會後大多做的都非科系相關的工作。但因製公司網頁,因此試著以ASP.NET 2.0來製作。在嘗試了好幾次仍無法做出想要的效果,只好請J大指點迷津了~m(_ _)m

  底下若有誤植專有名稱,還請多多包涵、指點……畢竟在下已將近十年沒用那些程式的名稱了~(遠目)

  我希望能讓使用者按Menu的項目時,分別顯示各頁面的Title…

  網站使用MasterPage的功能,並在主頁架構上使用Menu控制項,在查詢網路上的功能後發現有MenuItemClick的事件可以使用。於是放了一個Lable,並把它的ID設為lblTile,用以動態顯示網頁標題。

  不過問題就來了~…

   Protected Sub Menu_MenuItemClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MenuEventArgs)

  由此行可得知事件可取得Sender及e變數

  因之前試過Button的OnClick事件後,所以首先我就以Sender.Title或ID或Text之類當成是我所須要的變數,但可惜並沒有此變數可用。

  sender底下的函數有Equals、GetHashCode、GetType、ReferenceEquals、ToString,依其傳回值似乎是ToString比較有可能接近我所需要的值,不過沒有title或text的選項可供選擇。接著又試了GetType,不過依然沒辦法做出我想要的效果…

  於是把念頭動到e變數上(老實說後面那麼一長串的變數型態讓我不是很清楚,但應該也覺得不是我所需要的東西,不過還是只能試試~-_-a),但也試不出需要的效果…

  如方便的話,煩請將回應寄至dawn@mail.twku.net…或者直接回應至此亦可~

# Jeffrey said on 04 December, 2007 06:33 AM

sender就是觸發事件的物件,你可以用Button b = sender as Button的做法轉型成原來的呼叫物件,這麼一說,你應該就知道怎麼玩了吧?

# 潼恩 said on 05 December, 2007 07:10 PM

還是不懂... (炸)

不要太小看十年沒用程式後,腦中程式邏輯生鏽的程度~(遠目)

sender是觸發事件的物件,而我是從Protected Sub Menu_MenuItemClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MenuEventArgs)的程式裡去使用它的…

所以這裡的Sender應該是Menu,還是Menu Item呢?

。_。a

想以 lblTile.text = sender.???的方式抓出來,不過Menu再怎麼用力點都沒有變化…囧rz

# mj said on 07 December, 2007 01:22 AM

sender應該是不能直接這樣用,要先給他型別,以c#的寫法是lblTitle.Text = ((menu的type)sender).屬性

先決條件是,你要確定sender是誰,也就是到底是誰觸發這個事件的,是menu還是menu item,才不會導致轉型失敗(轉型失敗要實際run的時候看到exception才會知道~~)。

至於...vb.net的寫法,別問我,我不會。vs2005也沒用過,公司開發專案還是停在vs2003,跟本沒有多餘的時間讓我踹2005阿阿阿阿(淚奔~~).....

# 潼恩 said on 09 December, 2007 09:01 AM

囧a

對不起,我在學校時是學VB的...

雖然是資管出身,但不會C#,對Java也不熟... 囧a

工作的部分,前兩、三年我是做機械繪圖,今年是做建築工程繪圖~ -_-a

再之前是服務業的雜項部分... (遠目)

所以我這MIS是學的蠻慘的,再加上有學到也差不多都還老師,還記得的部分也退流行了... (遠目)

就算想淚奔,也哭不太出來......(遠目xN)

Sender應該是Menu Item,因為副程式名稱是MenuItemClick(...)~

# Jerry said on 19 December, 2007 06:02 PM

網路看了一堆Frame vs Master的筆戰, 看到你這篇文章,  真是如獲至寶, 在教ASP.NET想把這篇文章推薦學生, 比較中肯, 一堆文章寫的太過偏激,  好像用了Frameset就是大惡不赦的壞事, 我是兩者兼用的, Master的用法需要養成好習慣, (寫網頁前要先有良好的規劃) 可是, 畢章很多舊有的使用者還是習慣框架頁的作法, 不過我也是懶人一族, 可能也會使用Master為主, 除非客戶就是要Frameset

# mj said on 23 December, 2007 02:33 AM

.....2003裡面有辦法不用fs但是可以做到mp的效果嗎?目前開發中使用的方式是用一個【偽‧User Contorl】簡單的去載入LiteralControls以解省系統資源。但是.....還是要使用c/p大法把header and footer放置到各頁面去。

到這裡,都還可以接受,畢竟只要貼一次就可以解決一個頁面了,但是....後來出現了需要因為不同的使用者,而有不同的menu需求,世界就開始崩壞了........目前還在尋找解籤的人.....

# Jeffrey said on 23 December, 2007 08:13 AM

如果是ASP.NET 1.1,我應該也會採用User Control來解決Header/Footer的問題。如果你覺得Copy & Paste太煩,又想挑戰一下進階的程式設計,那麼可以試試實作一個會自動加上Header/Footer的MyBasePage物件,之後所有ASPX不要繼承Page,而是改認MyBasePage做爸爸。不過,編輯時看不到未來呈現的效果,在IDE裡也可能引發一些副作用,這方法不算頂好。

VS 2005可以直接將ASP.NET 1.1專案升級上去,ASP.NET 2.0也可以直接引用1.1寫的DLL,只有在極少數的狀況下會出問題。也許可以考慮升級到2.0做開發,我就常會發出T.G.I VS 2005的感嘆,哈!

# lichai said on 05 February, 2008 08:58 PM

1.網頁上不同的區域需要用不同的頻率更新

2.各個區域在進行更新時,回Server端時有可能會卡住,但又不能影響其他區域運作。

試過用AJAX,只要有一個Updatepanel卡住,其他也跟著卡死。

請問用除了用frameset外,還有其他方試嗎?

# Master一票 said on 18 February, 2008 12:59 AM

使用frameset當頁面內容大於frame本身會出現scrollbar,使得網頁看起來很奇怪

至少MasterPage會自動延伸,不需要再頁面內容改變時又去變動frameset的配置

# Maxi said on 29 August, 2008 03:57 AM

想請教一下雙menu的nested master page你有沒有經驗

就是一個top menu去控制,click其中一個item了之後

會出對應的leftmenu,再click leftmenu其中一個item會出對應的

content.

而且leftmenu的轉換和content的轉換都要是ajax的

我是.net新手,想做這樣的效果,但真的搞不出來

可以教我一下嗎?

# Jeffrey said on 29 August, 2008 10:14 AM

to Maxi, 就你所說的情境,由於Menu的轉換與Content切換都是用AJAX在前端處理掉,如果是我來規劃,應該不會用Master Page,而是用jQuery搞定。

Master Page的設計主要是讓多個ASPX共享同樣的排版及共用元素,因此要不斷的切換ASPX才特別會突顯它的優勢。如你打算一切的切換都用AJAX,則很有可能從頭到尾都停在同一個ASPX,Content ASPX應該也不會套Master Page(既然在Content區,應不會再含一次Header/Footer),因此我覺得Master Page派上用場的地方不多。以上是我的淺見。

# Johnson said on 26 May, 2010 07:48 PM

投 FrameSet 一票!

最近用 Master Page 遇到一個問題:

我希望只有 Content 出現捲軸 並且 可以隨著使用者瀏覽器的視窗大小而動態改變 Content 大小 , Master Page + ContentPlaceHolder 似乎做不到 , 於是我寫了 Java Script 完成了該功能! 但是 , ContentPlaceHolder 沒有支援 MaintainScrollPositionOnPostback , 所以又要自己寫 Java Script了 ...

後來想想 , 用傳統的 FrameSet 就可以輕鬆的達到我要的功能 , 而且可以搭配 .aspx 的 MaintainScrollPositionOnPostback!

只是不知道 FrameSet 是不是全世界的瀏覽器都支援?!

如果是的話 , 就太好了!

# 小黑 said on 10 August, 2011 01:42 AM

請問黑哥,今天收到一個棘手的需求,有一個舊有的網站,

是使用 masterpage 來打造的,由於每次切換頁面畫面都會閃一下,主管要求是否有辦法「不閃」,

小弟查了些資料,不知該如何下手,想請教你了?

# Jeffrey said on 10 August, 2011 02:22 AM

to 小黑, 只要是透過切換URL或Postback來更新網頁內容,就很難避免"閃一下"的感覺。一般常用的做法是透過AJAX方式(或ASP.NET UpdatePanel,但有ViewState過大的副作用,宜審慎為之)更新網頁內容迴避,但改寫幅度恐怕不小... 另一個思考方向是設法讓網頁元素單純化,提升程式執行效率及確保足夠的頻寬,讓"閃一下"的感受不要那麼明顯,也是個切入點。

# 小黑 said on 10 August, 2011 02:39 AM

感謝黑哥提點,若是要用 ajax 來達到,請問有甚麼可以參考的資料嗎?

# Jeffrey said on 10 August, 2011 05:34 PM

to 小黑,你可參考這篇教學,使用jQuery實現的純AJAX式內容管理介面(msdn.microsoft.com/.../dd722592.aspx) 強調不用任何PostBack。

# Oaww said on 08 December, 2011 01:35 AM

Dear 黑哥,我覺得DIV + Iframe也是一種變形的Solution耶 XD

# 茶兒清 said on 06 October, 2013 05:41 AM

慚愧......

上來看到這一篇

沒想到原本我的簡單想法被大大打爆頭了XDDDDD

嗚嗚~受益良多!!

# 紅豆 said on 18 February, 2014 10:29 PM

不好意思,想請教一下

  MasterPage一定會整頁刷新,若底色是深色,會有明顯閃爍現象,想請問一下有沒有辦法解決這個問題,因為板大您的網頁並沒有這樣的問題,不知道能否幫忙一下 感激不盡><

# Jeffrey said on 18 February, 2014 11:31 PM

to 紅豆,

如果不採AJAX動態更新,MasterPage刷新造成的閃爍是無法避免的,只能靠縮短載入時間降低衝擊。你提到深底色閃爍特別明顯的問題,有幾個方向可以思考: 1) 把較耗時Script動作延後到網頁DOM載入後再執行 2) 簡化DOM結構,儘早讓CSS設定完整 3) 檢查網頁所需js/css/圖檔是否存在下載過慢的問題 [可以善用瀏覽器內附的開發工具觀察]

讓瀏覽器愈快解析出body,並得知其底色style設定,即便網頁未100%載入,至少頁面底色已塗好,應可減少白色閃爍感。大致原則是這樣,如果還是難以改善,可能就得進一步檢查網頁是否存在某些載入瓶頸。

以上淺見。

# 紅豆 said on 21 February, 2014 01:46 AM

謝謝~我有稍微做修改,網頁的Loading速度比較快了,問題有獲得改善。

我把一些可以延後載入的東西用Ajax的方式或Script在$(window).load時載入,然後把這部分放在Body的底部,不知道我有沒有誤解你的意思@@

# Jeffrey said on 21 February, 2014 02:34 AM

to 紅豆,恭喜加速成功!

Ajax載入及放入$(window).load等同將工作延後到網頁DOM載入後進行、<script>移至body底部讓瀏覽器先處理解析DOM的內容再處理Script,這些都可讓網頁載入變快。

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<November 2007>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678
 
RSS
創用 CC 授權條款
【廣告】
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication