動作控制器 Streaming
允許在畫面呈現時,將畫面串流傳回至用戶端。
預設Rails
畫面會先呈現樣板,然後再呈現版面配置。當完整的樣板被呈現,所有的查詢都做完,與版面配置被處理完後,回覆才會傳送至用戶端。
Streaming
會先呈現版面配置,然後在處理的同時,陸續呈現版面配置的每個部分,這會讓 HTML 的標題 (通常在版面配置中) 可以很快的串流回傳到用戶端,讓 JavaScript 和樣式表比平常更早載入。
某些 Rack 中間件可能無法工作,所以在使用串流時請多加注意。以下內容有更詳細的說明,請參閱 Streaming
中的中間件 章節。
Streaming
可以輕易加入既有的樣板,唯一要做的事就是傳遞 :stream
選項給 render
。
class PostsController
def index
@posts = Post.all
render stream: true
end
end
串流適用的時機
Streaming
可能被視為用在類似 new
或 edit
等簡單動作時會有矯枉過正之嫌。串流真正的優勢在於處理耗費時間的動作,例如對資料庫執行大量的查詢。
在這些動作中,您可能會想要盡量延後查詢的執行時間。例如,想像有以下的 dashboard
動作
def dashboard
@posts = Post.all
@pages = Page.all
@articles = Article.all
end
大部分的查詢在此是在控制器中發生的。為了受惠於串流,您會想要將其改寫成
def dashboard
# Allow lazy execution of the queries
@posts = Post.all
@pages = Page.all
@articles = Article.all
render stream: true
end
請注意 :stream
僅適用於樣板。使用 :stream
來 呈現
:json
或 :xml
將無法作用。
版面配置與樣板間的溝通
在執行串流時,畫面呈現是由上而下的,而非由內而外。 Rails
會從版面配置開始,樣板則會在稍後,到達其 yield
時才會被呈現。
這表示,如果您的應用程式目前依賴樣板中設定的實例變數在版面配置中使用,當您轉換到串流時,它們將無法運作。在版面配置與樣板間進行溝通的正確做法 (不論是否使用串流) 是使用 content_for
、provide
與 yield
。
以下是一個簡單的範例,版面配置期望樣板告訴它要使用哪個標題
<html>
<head><title><%= yield :title %></title></head>
<body><%= yield %></body>
</html>
您可以在樣板中使用 content_for
來指定標題
<%= content_for :title, "Main" %>
Hello
最後的結果會是
<html>
<head><title>Main</title></head>
<body>Hello</body>
</html>
然而,如果 content_for
被呼叫多次,最後的結果將會是所有的呼叫串接在一起。舉例來說,如果我們有以下的樣板:
<%= content_for :title, "Main" %>
Hello
<%= content_for :title, " page" %>
最後的結果會是
<html>
<head><title>Main page</title></head>
<body>Hello</body>
</html>
這表示若您的版面配置中有 yield :title
,而您又想要使用串流,您必須在串流標題與所有資源以前呈現整個樣板 (而最終觸發所有的查詢),這違背了串流的宗旨。另一種做法是使用一個名為 provide
的輔助程式,其功能與 content_for
相同,但會告知版面配置停止搜尋其他條目並繼續呈現。
例如,使用 provide
的範例範本如下:
<%= provide :title, "Main" %>
Hello
<%= content_for :title, " page" %>
最後的呈現結果為:
<html>
<head><title>Main</title></head>
<body>Hello</body>
</html>
換句話說,在進行串流時,您需要適當地檢查範本並選擇使用 provide
或 content_for
。
詳情請參閱 ActionView::Helpers::CaptureHelper
。
標頭、Cookie、階段和簡訊
在串流播放時,HTTP 標頭會在呈現第一行之前傳送給用戶端。這表示在範本開始呈現之後修改標頭、Cookie、階段或簡訊,將不會傳播至用戶端。
中介軟體
需要處理本體中介軟體無法使用串流播放。在開發或製作中串流播放時,您應停用這些中介軟體。例如,Rack::Bug
在串流播放時無法使用,因為它需要將內容插入 HTML 本體。
此外,Rack::Cache
也無法與串流播放配合使用,因為它還不支援串流播放本體。在串流播放 Cache-Control
時,會自動設定為「no-cache」。
錯誤
在串流播放方面,例外情況會複雜一點。會發生這種情況是因為範本的部分已呈現並串流播放至用戶端,因此無法呈現整個例外情況頁面。
目前,當在開發或製作時發生例外情況,Rails
將自動串流至用戶端
"><script>window.location = "/500.html"</script></html>
在為特定標籤呈現屬性時發生例外情況,則需要頭兩個字元 (">
)。您可以在記錄器中查看例外情況的真正原因。
Web 伺服器支援
所有相容於 Rack 3+ 的伺服器都支援串流播放。