国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Ruby - 舉例理解Ruby on Rails的頁面緩存機制

舉例理解Ruby on Rails的頁面緩存機制

2020-04-26 10:36腳本之家 Ruby

這篇文章主要介紹了舉例理解Ruby on Rails的頁面緩存機制,本文來自于IBM官方網站技術文檔,需要的朋友可以參考下

有了頁面緩存,Rails 就可以不再介入。在某種程度上,這是件好事,因為您的確可以獲得優秀的性能。Rails 只需創建 HTML 頁面,將其放入目錄,之后,就可以置之于腦后。從那時起,就由應用服務器管理這些頁面,且頁面進入應用服務器無需任何循環。從性能的角度而言,頁面緩存真是天賜之福。

我也鐘愛頁面緩存,Rails 使之簡單利落。只需使用一行代碼就可以啟用緩存。如果再加入一些代碼,就能通過簡單地刪除文件操作或使用 Rails 較高層的 API 終止緩存。這里存在一個問題。并不是每個網站都能使用頁面緩存。如果頁面上的數據會根據訪問它的用戶而改變,那么就不能進行頁面緩存。而且,如果很難判斷頁面何時到期終止,就會發現頁面緩存的要求太過苛刻。

比如,幾乎在每個頁面上,ChangingThePresent.org(參閱 側欄)都有某些用戶數據是根據當前登錄的用戶而變化的。圖 1 顯示了我們最新主頁的一部分。(我們一直在努力完善它,所以它有可能會改變。)這個頁面呈現出的問題相對簡單。如果能判斷用戶是否已經登錄,就可以用 Flash、JavaScript、DHTML 或任何其他基于瀏覽器的代碼動態定制視圖。您會發現已登錄的用戶可以登出系統或查看其配置文件,而已登出的用戶則可以注冊或再次登錄。
圖 1. ChangingThePresent.org 上的登錄和登出視圖

舉例理解Ruby on Rails的頁面緩存機制

圖 2 顯示了稍微有些高級的用戶數據視圖,我們的站點就使用了這個視圖。圖 2 中的兩個視圖有極大的不同。為了處理頁面緩存,我必須先解決所有的差異。對于每個已登錄的用戶,我都必須替換掉頁面的登出內容,使之顯示登錄用戶的登錄 ID 和用戶圖片。緩存這些內容會帶來另一層面的挑戰,因為每個用戶的數據都不盡相同。
圖 2. 兩個截然不同的視圖

舉例理解Ruby on Rails的頁面緩存機制

這種情況并非 ChangingThePresent.org 所獨有。如果需要個性化用戶體驗,那么不可修改的 Rails 頁面緩存的使用就會受到限制。但如果定制不多,那么實際上還是能很容易地緩存這些頁面的。

解決這些問題的方法很多。我更傾向于使用如下這些技巧:

  •     在 Rails 框架的約束之內,取消頁面緩存并使用段緩存替代它。
  •     先加載頁面的大部分,然后使用 JavaScript 和 Ajax 加載該頁面較小的動態部分。服務器端代碼可以檢測用戶是否登錄,然后用 Ajax 呈現合適的部分。
  •     將某些用戶狀態(比如用戶是否已登錄)存儲在客戶端的 cookie 中。然后,根據 cookie 的內容,使用 JavaScript 動態更改頁面的外觀。

在這三種技巧中,我更喜歡第三種,因為第一和第二種技巧都會將 Rails 應用程序牽扯進來。要獲得最大限度的可伸縮性,就要盡量多地使用靜態內容。在本文中,我會側重于介紹第三種方式。請不要使用該方法存儲任何不能丟失的敏感數據,比如 ICBM 啟動代碼或信用卡號。對于我們所處理的這些有限的數據而言,這種方法效果很好。
使用 Show and tell 還是 hide and seek?

在我剛開始試著緩存這個主頁時,我本可以簡單地用 JavaScript 替換這些鏈接??梢詫⑦@種技巧看成是 Show-and-tell?;谖覀儗σ训卿浻脩舻牧私?,可以使用 JavaScript 選擇性地替換或注入 Web 頁的部分內容,從而為用戶提供正確的體驗。為了進一步細分,我會進行如下操作:

  •     創建只具有所有用戶的公共元素的 Web 頁。
  •     當用戶登錄時,將一些有關該用戶的數據存入 cookie,比如說登錄信息。
  •     然后,使用 JavaScript 依據 cookie 的內容注入 HTML 段,借此填充該頁面的剩余部分。

對于 ChangingThePresent 主頁而言,show-and-tell 技巧有些威力過度,因為我只有兩套鏈接要根據所登錄的用戶加以顯示。因此,我選擇了第二種技巧,我稱之為 hide-and-seek。首先,顯示出所有用戶的公共頁面元素,并通過每種數據可能 的隱藏版本顯示頁面的變化部分。這就是 hide 部分。然后,根據用戶的角色使用 JavaScript 在文件中找到該用戶的內容并顯示出來。這就是 seek 部分。您可能會想,顯示所有可能數據的版本有點威力過度,實際上,選擇性地為不同的安全角色啟用多種特性時,這種方式是十分常見的。hide-and-seek 方式非常適合 ChangingThePresent 主頁。要實現這種方法,可以執行如下操作:

  •     創建只具有所有用戶的公共元素的 Web 頁。
  •     將用戶按類型分區。為每個用戶類型添加內容版本。就我的具體情況而言,ChangingThePresent 主頁的用戶類型包括登錄用戶和登出用戶。最初,讓此內容可見。
  •     當用戶登錄時,將一些可區分用戶分組的數據存入 cookie,比如說用戶角色或登錄狀態。
  •     當用戶訪問此頁時,選擇性地顯示用戶類型的內容版本。

實現 hide and seek

對于 ChangingThePresent 主頁而言,hide-and-seek 實現起來異常簡單。在之前的圖 1 中,此主頁有一個部分顯示的是與用戶帳戶相關的一些鏈接。這些鏈接可以根據用戶是否登錄而變化。首要工作是構建此頁的所有公共內容。我在本文并未給出具體做法。第二頁需要顯示出所有用戶的全部動態內容,而不管用戶是否已經登錄:
清單 1. 在單一視圖中創建動態內容的所有版本

?
1
2
3
4
5
6
7
8
9
<div id='logged_out'>
 <%= link_to "login", :controller => 'members', :action => 'login' %>
 <br />
 <%= link_to "register", :controller => 'members', :action => 'signup' %>
</div>
<div id='logged_in' style="display: none;">
 <%= link_to "your profile", :controller => 'profiles', :action => 'show' %>
 <%= link_to "logout" , :controller => "members", :action => "logout" %>
</div>

您可能已經注意到 my profile 鏈接。起初,該鏈接指向用戶特定的配置文件,但這樣可能會妨礙我們的主頁緩存。相反,我只簡單地將此鏈接指向了無任何用戶 ID 的索引操作。然后,索引操作會將用戶重定向到正確的配置文件頁:
清單 2. 將用戶重定向到正確的配置文件頁

?
1
2
3
def index
  redirect_to my_profile_url
end

在清單 2,my_profile_url 是一個方法,該方法可以根據用戶的類型(這可能是名人、顧問或會員)決定正確的配置文件 URL。每個用戶類型都有一個單獨的配置文件頁。這時,程序的功能已經完成,您總共可以看到四個鏈接,logged_in 和 logged_out 各有兩個鏈接:

  •     login
  •     register
  •     your profile
  •     logout

下一步,獲取含有當前用戶類型的 cookie。對于 ChangingThePresent,我在登錄時創建了一個 cookie,其中含有當前的登錄 ID。之后,在登出時再銷毀這個 cookie:
清單 3. 在登錄和登出時創建和銷毀 cookies

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def login
 if request.post?
  self.current_user = User.authenticate(params['user_login'], params['user_password'])
  ...
 
  if logged_in?
   set_cookies
   ...
  end
end
 
def logout
end
 
private
 
def set_cookies
 cookies[:login] = current_user.login
 cookies[:image] = find_thumb(current_user.member_image)
end
 
def logout
 cookies.delete :login
 cookies.delete :image
 ...
 
end

在清單 3 中,logged_in? 是一個私有方法,如果當前用戶已登錄則返回 true。上述的 Rails 方法會在您登錄時創建三個 cookie,并在登出時刪除它們。這里不需要為數據費神。尚且不需用到數據??梢赃@樣理解:無需調用 Rails 框架,我就可以判斷用戶是否登錄。我無需確保 cookie 到期終止是否與站點的到期終止規定相符。在我的例子中,二者是相符的,所以我現在盡可以開始頁面緩存了。

下一步,根據用戶的 cookie 選擇性地隱藏和顯示正確的條目。將如下的 JavaScript 代碼添加到 public/javascripts/application.js 中:
清單 4. 支持 show and hide 登錄 div 的 JavaScript 代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}
 
function handle_cached_user() {
 var login_cookie = readCookie('login');
  var logged_in = document.getElementById('logged_in');
  var logged_out = document.getElementById('logged_out');
  if(login_cookie == null) {
   logged_in.style.display = 'none';
   logged_out.style.display = 'block';
  } else {
   logged_out.style.display = 'none';
   logged_in.style.display = 'block';
  }
}

第一個函數從 Javascript 中讀取 cookie 值,第二個函數處理此 DOM。可以通過使用 Prototype 庫簡化這段代碼,但我包括了基本的 DOM 查找以便于讀者理解。最后一步是在頁面加載時調用 JavaScript 函數。我向布局中添加了如下代碼:
清單 5. 當頁面加載時調用 JavaScript 函數

?
1
2
3
4
5
6
7
8
<script type="text/javascript">
 window.onload = function() {
   handle_cached_user();
 
   <%= render_nifty_corners_javascript %>
    <%= yield :javascript_window_onload %>
 }
</script>

上述 JavaScript 代碼十分簡單。在頁面加載時,將加載 handle_cached_user 函數,而它會相應地顯示或隱藏正確的內容。現在,我盡可以通過向控制器中添加如下代碼來啟用頁面緩存:

?
1
caches_page :index

上述代碼效果極佳。我還是需要定期地從緩存中刪除前頁,這樣我才能使該頁期滿終止。為此,我只需簡單地定期刪除 public/index.html。hide-and-seek 方式對于有幾類用戶的頁面十分有效,但對于如圖 2 中所示的用戶 partial 效果卻不佳。對于后者,需要綜合使用 hide-and-seek 和 show-and-tell 技巧。
實現 show-and-tell

再來看看 圖 2。我將使用 hide-and-seek — 根據用戶是否已登錄 — 選擇 partial 的正確版本,然后使用 show-and-tell 技巧根據我之前在清單 3 的行 4 和行 5 中所寫的 cookies 的內容填充頁面的動態部分。請記住,對于 show-and-tell,我特別更改了頁面的元素以符合單個用戶的情況。

首先,完成在這兩個 partial (即登出用戶和登錄用戶)上呈現的靜態內容。我假設用戶已經登出,所以我會通過附加 display: none 風格隱藏 logged_in div。之后,如果必要,我就可以用 JavaScript 顯示或隱藏它們。請注意,我使用了相同的兩個名稱:logged_in 和 logged_out,來識別每個 div,這樣便無需對我為這個主頁所編寫的 JavaScript 進行修改:
清單 6. 呈現登錄和登出這兩個 partial

?
1
2
3
4
5
6
7
8
<div class="boxRight sideColumnColor">
  <div id='logged_in'>
    <%= render :partial => 'common/logged_in' style="display: none; %>
  </div>
  <div id='logged_out'>
    <%= render :partial => 'common/logged_out' %>
  </div>
</div>

接下來,完成 logged_in partial 的內容。注意,每個包含動態內容的 HTML 組件都有一個 ID,從而我可以使用 JavaScript 找到它并隨后將其替換:
清單 7. 顯示 logged_in partial

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id='logged_in' style="display: none;">
 
 <%= link_to %(<span class="mainBodyDark">Hi, </span>) +
    %(<span class="textLarge mainBodyDark"><b id='bold_link'>) + "my_login" +
    %(</b></span>), {:controller => 'profiles', :action => 'show', :id => 'my_login'},
 {:id => 'profile_link'} %>
 <br/>
 
 <div id='picture_and_link'>
   <a href="http://member/my_login" id='link_for_member_thumbnail'>
     <img id='member_thumbnail'
        alt="Def_member_thumbnail"
        src="/images/default/def_member_thumbnail.gif" /></a>
 </div>
 
 <div id="not_mine">Not my_login?</div>
 <br/>
 <%= image_button "logout", :controller => "members", :action => "logout" %>

如果對 Rails 有足夠的了解,您可能會注意到其中的幾個定制幫助程序函數。從中可以看到四處很明顯的動態內容,我需要使用 JavaScript 為每個加載的頁面替換這些內容:三處登錄,一處會員圖像。此處的 JavaScript 代碼對 handle_cached_user 函數作了一處修改,并且還含有一個為動態用戶處理頁面更新的方法。針對本文的具體情況,我稍微對這段代碼做了少許簡化。可以將如下函數添加到 application.js 文件中:
清單 8. 替換用戶 partial 的元素

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function handle_user_partial() {
 var login_cookie = readCookie('login');
 var image_cookie = readCookie('image');
 
  var profileLink = document.getElementById('profile_link');
  profileLink.href = '/member/' + login_cookie;
 
  document.getElementById('bold_link').firstChild.nodeValue=login_cookie;
 
  document.getElementById('not_mine').firstChild.nodeValue="Not " + login_cookie + "?";
 
  document.getElementById('link_for_member_thumbnail').href="/member/" + login_cookie;
 
  document.getElementById('member_thumbnail').src=image_cookie.replace(/%2[Ff]/g,"/");
 
  document.getElementById('member_thumbnail').alt=login_cookie;
 
}

在清單 8 中,這個 JavaScript 函數首先讀取此 cookies 并獲取 DOM 樹的一部分:即到當前的用戶配置文件的鏈接,稱為 profile_link。然后是 handle_user_partial 函數:

  •     將登錄用戶的名稱(存儲在 login_cookie 內)替換成 my_login 以為用戶配置文件頁創建正確的 URL。
  •     將登錄用戶名插入到 DOM 元素中,此元素使用粗體文本表示登錄用戶。
  •     將簡單的句子 “Not login?” 插入到 DOM 元素中,這個元素包含 login partial 中的 logout 標題。
  •     找到包含會員圖像的 dom 元素,將一般圖像的 URL 替換成會員圖像的 URL,會員圖像保存在 image_cookie 中。
  •     此外,還要將此圖像的 alt 標記替換成 login 名稱,以防圖像不出現。

在 DOM 中導航時,會發現有時需要直接轉到 DOM 元素,而有時又需要轉到該元素的特定子元素,比如在處理文本的時候。我就使用了 firstChild 函數根據需要尋找 DOM 元素的第一個子元素。由于語法更為友好,所以 Prototype 庫使處理特定的 DOM 元素較為容易一些,但這超出了本文的討論范圍。

我已經創建好了所有的 cookies,最后一步就是從 handle_cached_user 函數調用 JavaScript。請記住,該函數在 public/javascripts/application.js中:
清單 9. 將 handle_user_partial 函數添加到 handle_cached_user

?
1
2
3
4
5
6
7
8
9
10
11
12
13
function handle_cached_user() {
 var login_cookie = readCookie('login');
  var logged_in = document.getElementById('logged_in');
  var logged_out = document.getElementById('logged_out');
  if(login_cookie == null) {
   logged_in.style.display = 'none';
   logged_out.style.display = 'block';
  } else {
  handle_user_partial();
   logged_out.style.display = 'none';
   logged_in.style.display = 'block';
  }
}

請注意,else 條件中的 handle_cached_user 函數下面還有額外兩行代碼。這兩行代碼可以在使 logged_in DOM 元素可見之前進行適當的替代。剩下所需做的就是使用本篇文章和 上個月 的那篇文章中所介紹的頁面緩存指令來緩存整個頁。
結束語

本篇文章中介紹的這種高級技巧為我們打開了許多方便之門。在 ChangingThePresent.org 上,我們估計使用非常簡單的基于時間的清除器能夠緩存超過 75% 的頁面。通過使用稍微有些復雜的清除技巧,我們就能緩存超過 90% 的頁面,而且還可能更多。如果您想試圖影響我們的圖像緩存計劃,那么您只能觸及應用服務器 1% 到 3% 的 Web 請求。

但同時,我們也應該看到不利的一面。我向此系統添加了明顯的復雜性。我必須維護更加復雜的 HTML 代碼,并確保 HTML 和 JavaScript 能夠保持同步。但好的一面是在需要獲得更好的性能時,我就能夠使用最為簡單和有效的緩存技術。您也可以嘗試使用這種技巧 — 訪問 ChangingThePresent.org 并加載主頁。接下來,加載每個頂端的菜單。您會發現我們會頁面緩存六個頂端菜單中的四個。創建一個帳號并重載每一個菜單。您能猜到哪個頁面被緩存了么?在下一篇文章中,在繼續深入真實世界中的 Rails 的同時,我將帶您探究能增進 ActiveRecord 性能的一些技巧。

延伸 · 閱讀

精彩推薦
  • Ruby剖析 Ruby 訪問控制

    剖析 Ruby 訪問控制

    前面,我們說 Ruby 沒有函數,只有方法.而且實際上有不止一種方法.這一節我們介紹 訪問控制 (accesscontrols). 想想當我們在最高層而不是在一個類的定義里定義...

    ruby教程網3572020-04-08
  • RubyCentOS中配置Ruby on Rails環境

    CentOS中配置Ruby on Rails環境

    經過一個上午的折騰,終于把ROR環境在CentOS中搞定,繞了很多彎路,把文章寫下來總結一下 ...

    可樂加糖4762020-04-12
  • RubyRuby簡潔學習筆記(一):字符串、數字、類和對象

    Ruby簡潔學習筆記(一):字符串、數字、類和對象

    這篇文章主要介紹了Ruby簡潔學習筆記(一):字符串、數字、類和對象,本文是學習筆記第一篇,需要的朋友可以參考下 ...

    腳本之家2472020-04-20
  • RubyRuby迭代器的7種技巧分享

    Ruby迭代器的7種技巧分享

    這篇文章主要介紹了Ruby迭代器的7種技巧分享,Ruby中的迭代器非常人性化,本文既是講解了7個技巧也是講解了7種迭代器,需要的朋友可以參考下 ...

    腳本之家4782020-04-20
  • RubyRuby進行文件信息輸出實例代碼

    Ruby進行文件信息輸出實例代碼

    Ruby進行文件信息輸出實例代碼,數據是隨機的,所以每次的記錄都會不同。 ...

    ruby教程網2962020-04-10
  • Ruby簡要說明Ruby中的迭代器

    簡要說明Ruby中的迭代器

    這篇文章主要介紹了Ruby中的迭代器,迭代器的概念在動態語言的編程中十分重要,文章中介紹了Ruby中的each迭代器和collect迭代器,需要的朋友可以參考下 ...

    goldensun2772020-04-25
  • RubyRuby環境下安裝使用bundler來管理多版本的gem

    Ruby環境下安裝使用bundler來管理多版本的gem

    這篇文章主要介紹了Ruby環境下安裝使用bundler來管理多版本的gem的方法,舉了Ruby On Rails中的應用實例來進行演示,需要的朋友可以參考下 ...

    日拱一卒4332020-05-10
  • RubyRuby設計模式編程中使用Builder建造者模式的實例

    Ruby設計模式編程中使用Builder建造者模式的實例

    這篇文章主要介紹了Ruby設計模式編程中使用Builder建造者模式的實例,建造者模式將一個復雜對象的構造與它的表示分離,使同樣的構建過程可以創建不同的表...

    范孝鵬2192020-05-07
主站蜘蛛池模板: 成人精品国产免费网站 | 亚洲免费美女视频 | 亚洲片国产一区一级在线观看 | 久久视频一区 | 欧美日韩亚洲系列 | 国产精品a久久久久 | 欧美另类视频 | 亚洲在线中文字幕 | 精品美女在线观看视频在线观看 | 毛片在线视频 | 国产毛片av | 亚洲一区二区三区免费观看 | 久久综合久色欧美综合狠狠 | 亚洲天堂五码 | 精品一区二区在线观看 | 欧美在线网站 | 国产精品18久久久 | 亚洲成人激情在线观看 | av伊人网| 欧美日韩第一页 | 久久久久久久国产毛片 | 中文在线一区二区 | 免费黄网视频 | 日韩一区二区三区福利视频 | 在线看的av | 激情五月婷 | 欧美大片免费观看 | 久久综合伊人 | 九九热精品国产 | 欧美国产精品一区二区三区 | 综合久久久久 | 欧美色综合天天久久综合精品 | 免费三片在线观看网站 | 国产精品一级毛片在线 | 乱视频在线观看 | 欧美日韩第一区 | 成人午夜 | 免费看一区二区三区 | 一区在线视频 | 日韩欧美国产一区二区 | 中文字幕一区二区三区四区不卡 |