Turbo FramesでRedmineのフォーラム機能の画面遷移を削減できるか試した話


My Redmine

前田 稔です。今回は、Turbo Framesを使ってRedmineのフォーラム機能の画面遷移を減らすことができるかを検証します。

なお、以下のサイトを参考にさせていただきました。

期待と検証結果

Redmineのフォーラム機能では、トピックの最初のメッセージや返答を編集する際に画面遷移が発生します。この画面遷移を減らすことで、操作の応答が速くなり、ユーザー体験が向上することを期待していました。

検証の結果、Turbo Framesを活用することで、事前に宣言した部分をリクエストに応じて更新できるようになり、画面遷移を減らすことができました。

Redmineのフォーラム機能における画面遷移が発生する様子
Redmineのフォーラム機能における画面遷移が発生する様子

メッセージの編集フォームをトピックの閲覧画面に埋め込む検証

以下の方針で検証を行いました。

turbo-rails gemの導入とturbo.jsの配置

今回の検証では、bin/rails turbo:install ではなく turbo.js を直接 Redmine の app/assets/javascripts に配置して読み込み対象に追加しました。

Gemfile:

gem "turbo-rails"

app/helpers/application_helper.rb:

  # Returns the javascript tags that are included in the html layout head
  def javascript_heads
    tags = javascript_include_tag(
      'jquery-3.6.1-ui-1.13.2',
      'rails-ujs',
      'tribute-5.1.3.min',
      'tablesort-5.2.1.min.js',
      'tablesort-5.2.1.number.min.js',
      'application',
      'turbo.js',
      'responsive')

Turbo Framesでメッセージを表示している箇所を置き換える枠として宣言する

トピックの閲覧画面では、最初のメッセージを表示している箇所と返答のメッセージを表示している箇所が分かれており、それぞれ置き換える枠として宣言します(以下、フレーム化と呼びます)。

app/views/messages/show.html.erb:

<%= board_breadcrumb(@message) %>
<!-- トピックの最初のメッセージを表示している箇所をフレーム化 -->
<%= turbo_frame_tag dom_id(@topic) do %>
  <div class="contextual">
    :
  </div>
 
  <h2><%= avatar(@topic.author) %><%= @topic.subject %></h2>
 
  <div class="message">
    <p><span class="author"><%= authoring @topic.created_on, @topic.author %></span></p>
    <div class="wiki">
      <%= textilizable(@topic, :content) %>
    </div>
    <%= link_to_attachments @topic, :author => false, :thumbnails => true %>
  </div>
<% end %>
:
<div id="replies">
  :
  <% @replies.each do |message| %>
    <!-- 返答のメッセージを表示している箇所をフレーム化 -->
    <%= turbo_frame_tag dom_id(message) do %>
      <div class="message reply" id="<%= "message-#{message.id}" %>">
        :
        <div class="wiki"><%= textilizable message, :content, :attachments => message.attachments %></div>
        <%= link_to_attachments message, :author => false, :thumbnails => true %>
      </div>
    <% end %>
  <% end %>
</div>

フレームに罫線を付けて可視化すると以下のようになります。

app/assets/stylesheets/application.css:

turbo-frame {
  border: 1px solid #00BCD4;
  display: block;
  padding: 1px;
}
メッセージを表示している箇所をフレーム化した状態
メッセージを表示している箇所をフレーム化した状態

編集フォームを埋め込めるようにする

メッセージを表示している箇所と同様にフレーム化します。 トピックの閲覧画面では以下のように、IDでフレームを識別しています。フレームの中にある編集リンクは従来の挙動と異なり、画面遷移せずフレームが一致する部分が自動的に置き換えられます。

メッセージを表示している箇所をフレームIDを可視化した状態
メッセージを表示している箇所をフレームIDを可視化した状態

app/views/messages/edit.html.erb:

<!-- トピックの最初のメッセージまたは返答のメッセージIDでフレーム化 -->
<%= turbo_frame_tag dom_id(@message) do %>
  <h2><%= avatar(@topic.author) %><%= @topic.subject %></h2>
 
  <%= form_for @message, {
                :as => :message,
                :url => {:action => 'edit'},
                :html => {:multipart => true,
                          :id => 'message-form',
                          :method => :post}
            } do |f| %>
    <%= render :partial => 'form',
              :locals => {:f => f, :replying => !@message.parent.nil?} %>
    <%= submit_tag l(:button_save) %>
  <% end %>
<% end %>

編集画面でもフレームIDを一致させると、以下の通り、編集操作時にはメッセージを表示している箇所が編集フォームに置き換わります。フレーム内のフォーム送信に対する応答(リダイレクトや画面描画)は従来の挙動と異なり、フレームが一致する部分が自動的に置き換えられます。

メッセージ編集操作の時に、メッセージを表示している箇所が編集フォームに置き換わる様子
メッセージ編集操作の時に、メッセージを表示している箇所が編集フォームに置き換わる様子

トピックの最初のメッセージと返答のメッセージをそれぞれ編集できるようにする

画面遷移を減らすことには成功しましたが、従来の編集画面は複数の編集フォームが共存する考慮がなされていません。そのため、入力項目のID設定を一意にする必要があります。

app/views/messages/_form.html.erb:

<% message_content_dom_id = message_content_dom_id.presence || dom_id(@message, 'content') %>
<p>
  <%= label_tag message_content_dom_id, l(:description_message_content), :class => "hidden-for-sighted" %>
  <%= f.text_area :content, :cols => 80, :rows => 15, :class => 'wiki-edit', :id => message_content_dom_id,
                  :accesskey => accesskey(:edit),
                  :data => {
                      :auto_complete => true
                  }
  %>
</p>
<%= wikitoolbar_for message_content_dom_id, preview_board_message_path(:board_id => @board, :id => @message) %>

まとめ

Turbo Framesを活用することで、事前に宣言した部分をリクエストに応じて更新できるようになり、画面遷移を減らすことができました。また、Turbo Streamsを活用することでフォーラムのメッセージ更新を他の利用者の画面に反映させることもできそうです。

トピックの最初のメッセージと返答のメッセージをそれぞれ編集する様子
トピックの最初のメッセージと返答のメッセージをそれぞれ編集する様子

【スタッフ募集中】
弊社ではAWSを活用したソリューションの企画・設計・構築・運用や、Ruby on Rails・JavaScriptフレームワークなどを使用したアプリケーション開発を行うスタッフを募集しています。採用情報の詳細
弊社での勤務に関心をお持ちの方は、知り合いの弊社社員・関係者を通じてご連絡ください。

My Redmine

こちらの記事もオススメです!
Web版VSCodeでRedmineのWasmを試した話
Web版VSCodeを使用してRedmineをWasm(WebAssembly)で動作させることを試しました。
社内事務システムの開発者とのミーティングを行なっています
社内の事務システムの改善について開発者と話し合える場ができ、業務の改善に繋がっています。
仮想化ソフトウェアUTMを使ってみた
macOSで使用できる仮想化ソフトウェアのひとつに「UTM」というソフトウェアがあります。わかりやすいGUIで使いやすいと思います。
RubyKaigi 2024で印象に残ったセッションとRubyistと一緒に過ごした楽しい時間
5/15〜17に沖縄で開催されたRubyKaigi 2024に参加しました。
オライリー本の全冊公開日ともくもく勉強会を毎月開催しています
ファーエンドテクノロジーではオライリー本を全冊所蔵しています。
ファーエンドテクノロジーからのお知らせ(2025/01/15更新)
「しまね移住の先輩セミナー ~未経験からはじめるIT移住~」に弊社社員の呂 勝男が登壇
「しまね移住の先輩セミナー ~未経験からはじめるIT移住~」に、ファーエンドテクノロジー社員の呂勝男が登壇いたします。
オープンソースカンファレンス2025 Osakaに弊社代表の前田が登壇(ブース出展あり)
2025年1月25日に開催されるオープンソースカンファレンス2025 Osakaで、弊社代表の前田によるセミナー発表とブース出展を行います。
プロジェクト管理ツール「RedMica」バージョン 3.1.0をリリース Redmine互換のオープンソースソフトウェア
ファーエンドテクノロジー株式会社は、2024年11月19日(日本時間)、Redmine互換のプロジェクト管理ソフトウェア「RedMica 3.1.0」をリリースしました。
プロジェクト管理ツールRedmineのクラウドサービス「My Redmine」の海外向けサービス「My Redmine Global Edition」の提供を開始
「My Redmine」の海外向けサービスとして、新たに「My Redmine Global Edition」の提供を開始しました。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け