Turbolinks เป็นเครื่องมือที่ยอดเยี่ยมในการทำให้การนำทางเว็บแอปพลิเคชันของคุณเร็วขึ้น ไม่ได้อยู่ภายใต้การพัฒนาอีกต่อไป มันถูกแทนที่ด้วยเฟรมเวิร์กใหม่ที่เรียกว่า Turbo ซึ่งเป็นส่วนหนึ่งของกลุ่ม Hotwire
ทีมที่อยู่เบื้องหลังเข้าใจว่าสิ่งอื่น ๆ สามารถใช้แนวคิดที่คล้ายกันซึ่งดึงมาจาก Turbolinks เพื่อยึดติดกับเว็บที่เร็วขึ้น เช่น เฟรม การส่งแบบฟอร์ม และแอปที่มาพร้อมเครื่อง
บทความนี้มีจุดมุ่งหมายเพื่อให้คำแนะนำสำหรับเฟรมเวิร์ก Turbo ซึ่งใช้แทน Turbolinks ใหม่ รวมถึงคู่มือการโยกย้ายที่ใช้งานได้จริง ซึ่งจะอธิบายวิธีใช้ Turbolink ที่สำคัญและใช้กันทั่วไปใน Turbo
เพื่อให้เข้าใจสิ่งที่เราจะพูดถึงได้ดีขึ้น คุณจำเป็นต้องมีความรู้เกี่ยวกับ Turbolinks บ้าง คุณสามารถอ่านเพิ่มเติมได้ที่นี่และที่นี่
แนะนำเทอร์โบ
Turbo คือชุดของเทคนิคต่างๆ มากมายสำหรับการสร้างเว็บแอปที่ทันสมัยและรวดเร็วโดยใช้ JavaScript น้อยลง ทำได้โดยอนุญาตให้เซิร์ฟเวอร์จัดการกับตรรกะทั้งหมดที่จะส่งในรูปแบบของ HTML ไปยังเบราว์เซอร์โดยตรง ในทางกลับกัน ความรับผิดชอบเพียงอย่างเดียวของเบราว์เซอร์คือการประมวลผล HTML ธรรมดา
ในการทำเช่นนี้ Turbo แบ่งตัวเองออกเป็นสี่ส่วนหลัก:
- เทอร์โบไดรฟ์ หัวใจสำคัญของ Turbo หลีกเลี่ยงการโหลดซ้ำแบบเต็มหน้าผ่านการสกัดกั้นอัตโนมัติของการคลิกทั้งหมดบนลิงก์และแบบฟอร์มของคุณ ป้องกันไม่ให้เบราว์เซอร์เรียกมัน เปลี่ยน URL ผ่าน API ประวัติ ขอหน้าเบื้องหลังผ่าน Ajax และแสดงการตอบสนอง อย่างเหมาะสม
- เทอร์โบเฟรม เกี่ยวข้องกับชุดย่อย/เฟรมของหน้าโดยคิดค้นวิธีที่ Front-end devs จัดการกับเฟรมสำหรับจัดการกับชุดย่อยของหน้าอย่างอิสระ มันแยกหน้าออกเป็นชุดบริบทที่เป็นอิสระด้วยขอบเขตที่แยกจากกันและความสามารถในการโหลดแบบ Lazy Loading
- สตรีมแบบเทอร์โบ ช่วยแทนที่การอัปเดตบางส่วนของหน้าทั่วไปผ่านการจัดส่งแบบอะซิงโครนัสผ่านซ็อกเก็ตเว็บด้วยชุดแท็กคอนเทนเนอร์ CRUD อย่างง่าย คุณสามารถส่งส่วนย่อย HTML ผ่านซ็อกเก็ตเว็บเดียวกันได้ และให้หน้าเข้าใจและประมวลผล UI อีกครั้ง
- เนทีฟเทอร์โบ จัดเตรียมเครื่องมือที่จำเป็นทั้งหมดเพื่อจัดการกับ Turbo ในเว็บแอปแบบฝังสำหรับ Native Shell หากคุณใช้งานบน iOS/Android
การตั้งค่าโครงการ
เพื่อช่วยให้สิ่งต่างๆ เร็วขึ้น ฉันจึงตัดสินใจจัดเตรียมโปรเจ็กต์แอป Rails ที่พร้อมใช้งานพร้อมโฟลว์โพสต์แบบนั่งร้านที่ฝังอยู่ภายในนั้น พร้อมด้วย Bootstrap สำหรับการจัดรูปแบบ
วิธีนี้จะช่วยป้องกันไม่ให้คุณเสียเวลาในการตั้งค่า รวมถึงให้โปรเจ็กต์การทำงานที่มี Turbolinks ถูกเพิ่มโดยอัตโนมัติ หากคุณมีโครงการอยู่แล้ว ก็ไม่เป็นไร คุณยังสามารถติดตามบทความได้
คุณยังสร้างแอป Rails แบบนั่งร้านใหม่ได้ด้วย rails
คำสั่ง
คุณสามารถค้นหาลิงก์ GitHub ของที่เก็บได้ที่นี่ อย่าลืมโคลนในเครื่องแล้วรันคำสั่ง bundle install
เพื่อติดตั้งการพึ่งพา Rails ทั้งหมด
เมื่อทุกอย่างพร้อมแล้ว ให้เริ่มเซิร์ฟเวอร์ Rails ผ่าน rails s
คำสั่งและตรวจสอบ /posts
URI ดังที่แสดงด้านล่าง:
โพสต์ CRUD ใน Rails
หากต้องการตรวจสอบการทำงานของ Turbolinks เพียงไปที่ลิงก์เพื่อสร้างโพสต์ใหม่หรือแสดงรายการ คุณจะเห็นว่า URL เปลี่ยนแปลงโดยไม่ต้องโหลดหน้าซ้ำ
ขั้นตอนการโยกย้าย
เริ่มต้นด้วยการติดตั้งแพ็คเกจโหนดที่เหมาะสม เนื่องจากคุณไม่ต้องการ turbolinks
. อีกต่อไป เราสามารถลบออกจากรายการโหนดของเราและเพิ่มการพึ่งพารางเทอร์โบตามที่แสดงในสองคำสั่งด้านล่าง:
yarn remove turbolinks
yarn add @hotwired/turbo-rails
อีกวิธีที่ยอดเยี่ยมในการตรวจสอบให้แน่ใจว่าทุกอย่างได้รับการติดตั้งอย่างถูกต้อง หากคุณใช้งาน Rails อยู่ คือการรันคำสั่งต่อไปนี้:
rails turbo:install
สิ่งนี้จะติดตั้ง Turbo ผ่าน npm หากติดตั้ง Webpacker ในแอปพลิเคชันซึ่งก็คือ คำสั่งนี้ยังพยายามลบการพึ่งพาเก่าของ Turbolinks ทั้งหมดออกจากโปรเจ็กต์ของคุณในกรณีที่คุณพลาดบางสิ่งไป
จากนั้น เปิด app/javascript/packs/application.js ไฟล์และค้นหาบรรทัดของรหัสต่อไปนี้:
import Turbolinks from "turbolinks";
Turbolinks.start();
โปรดทราบว่าการนำเข้าอาจเปลี่ยนแปลงเล็กน้อยขึ้นอยู่กับเวอร์ชันของแอป Rails ของคุณ (เวอร์ชันที่เก่ากว่าใช้ require
แทน import
). อย่างไรก็ตาม กระบวนการก็เหมือนกันสำหรับทั้งคู่
จากนั้นให้แทนที่ด้วยสิ่งต่อไปนี้:
import "@hotwired/turbo-rails";
ใช่ นำเข้าเพียงครั้งเดียว ไม่จำเป็นต้องเริ่มดำเนินการใดๆ ด้วยตนเอง Turbo
อินสแตนซ์ถูกกำหนดโดยอัตโนมัติให้กับ window.Turbo
วัตถุเมื่อนำเข้าซึ่งง่ายต่อการจัดการ
หากต้องการทดสอบและดูว่าเราต้องการแค่ Turbo เท่านั้น ไม่ใช่ Turbolink อีกต่อไป ให้เพิ่มข้อมูลโค้ดต่อไปนี้ที่ส่วนท้ายของไฟล์:
$(document).on("turbolinks:load", () => {
console.log("turbolinks!");
});
$(document).on("turbo:load", () => {
console.log("turbo!");
});
หลังจากที่หน้าโหลดซ้ำในเบราว์เซอร์ของคุณ ให้ตรวจสอบบันทึกของคอนโซลเพื่อดูว่ามีการพิมพ์อะไรบ้าง:
ดูบันทึกเหตุการณ์การโหลดเทอร์โบ
มีการเปลี่ยนแปลงอื่นที่เราต้องทำกับ app/views/layouts/application.html.erb ซึ่งโดยพื้นฐานแล้วจะเปลี่ยนแอตทริบิวต์ข้อมูล Turbolinks เก่าให้เทียบเท่ากับ Turbo ค้นหาแท็กทั้งสองโดยใช้ data-turbolinks-*
และแทนที่ด้วยสิ่งต่อไปนี้:
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbo-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbo-track': 'reload' %>
นี่เป็นสิ่งสำคัญที่จะอนุญาตให้ Turbo ติดตามสินทรัพย์ที่นำเข้าทั้งหมดใน head
และอย่าลืมโหลดซ้ำในกรณีที่มีการเปลี่ยนแปลง สิ่งนี้ใช้กับไฟล์ทั้งหมด รวมถึงสคริปต์และสไตล์ทั้งหมดที่คุณเพิ่มไว้ที่นั่น
สำรวจคุณลักษณะเทอร์โบ
เนื่องจาก Turbo จะสกัดกั้นลิงก์ทั้งหมดในแอปพลิเคชันของคุณโดยอัตโนมัติเพื่อเรียกใช้โดยไม่ต้องโหลดซ้ำ ตัวอย่างเช่น หากคุณต้องการปิดฟังก์ชันนั้นสำหรับลิงก์ใดลิงก์หนึ่ง คุณจะต้องเขียนโค้ดนี้อย่างชัดเจน
มาทดสอบกันโดยอัปเดตปุ่ม "โพสต์ใหม่" ใน app/views/posts/index.html.erb ไฟล์ต่อไปนี้:
<%= link_to 'New Post', new_post_path, :class => "btn btn-primary btn-sm", "data-turbo" => "false" %>
โปรดทราบว่าเรากำลังเพิ่มแอตทริบิวต์ข้อมูลใหม่อย่างชัดแจ้ง data-turbo
เพื่อขอให้ Turbo ไม่ค้นหาลิงก์เฉพาะนี้เมื่อคลิก
หากคุณโหลดแอปพลิเคชันซ้ำแล้วคลิกปุ่ม "โพสต์ใหม่" คุณจะเห็นว่าขณะนี้หน้าเว็บกำลังโหลดซ้ำอย่างสมบูรณ์เหมือนที่ทำในแอปทั่วไป
นั่นเป็นวิธีที่ยอดเยี่ยมในการทดสอบว่า Turbo ได้รับการตั้งค่าและทำงานในแอปพลิเคชันของคุณหรือไม่
เช่นเดียวกับแบบฟอร์มของคุณ Turbo จะดูแลการส่งแบบฟอร์มทั้งหมดโดยอัตโนมัติ ดังนั้น จึงเกิดขึ้นแบบไม่พร้อมกัน หากคุณต้องการปิดการใช้งานสำหรับแบบฟอร์มภายใต้ app/views/posts/_form.html.erb คุณควรเปลี่ยนปุ่มส่งเป็นดังต่อไปนี้:
<div class="actions">
<%= form.submit class: "btn btn-primary btn-sm", "data-turbo" => false %>
</div>
โหลดแอพใหม่และทดสอบ! คุณจะเห็นการทำงานแบบเดียวกันเมื่อสร้างโพสต์ใหม่
ส่งแบบฟอร์ม
เมื่อพูดถึงแบบฟอร์ม Turbo จัดการกับพวกมันในลักษณะที่คล้ายคลึงกันมากกับลิงก์ อย่างไรก็ตาม การขอแบบฟอร์มอาจไม่สำเร็จเสมอไป
มาดูกันในทางปฏิบัติ! ขั้นแรก เพิ่มการตรวจสอบสองสามครั้งเพื่อเปลี่ยน name
. ของโพสต์ และ title
คุณสมบัติที่จำเป็น สำหรับสิ่งนี้ ให้เปิด app/models/post.rb ไฟล์และเปลี่ยนเป็นดังต่อไปนี้:
class Post < ApplicationRecord
validates :name, presence: true
validates :title, presence: true
end
โหลดแอปซ้ำแล้วลองเพิ่มโพสต์ใหม่ทันที โดยปล่อยให้ฟิลด์ทั้งหมดว่าง คุณจะสังเกตได้ว่าไม่มีอะไรเกิดขึ้น หากคุณตรวจสอบคอนโซลของเบราว์เซอร์ คุณจะเห็นสิ่งต่อไปนี้:
การตอบกลับแบบฟอร์มต้องเปลี่ยนเส้นทางไปยังตำแหน่งอื่น
ในการแก้ไขปัญหานั้น เรามีสองแนวทางที่เป็นไปได้ ขั้นแรกประกอบด้วยการเพิ่ม status
ไปยังแต่ละการดำเนินการที่อัปเดตได้ของตัวควบคุมโพสต์ (POST, PUT เป็นต้น) และทำให้ได้รับวัตถุเอนทิตีที่ประมวลผลไม่ได้เป็นค่าของมัน
ด้านล่างนี้ คุณจะพบการเปลี่ยนแปลงโค้ดสำหรับทั้ง create
และ update
(post_controller.rb ) วิธีการ:
# def create
format.html { render :new, status: :unprocessable_entity }
# def update
format.html { render :edit, status: :unprocessable_entity }
บันทึกการแก้ไขของคุณและทดสอบแบบฟอร์มอีกครั้ง คุณจะเห็นว่าข้อผิดพลาดแสดงอย่างถูกต้องในครั้งนี้:
การแสดงข้อผิดพลาดในการตรวจสอบความถูกต้องใน UI
วิธีที่สองในการทำเช่นนี้คือผ่าน turbo_frame_tag
. ในแอป Rails ที่ใช้ Turbo แท็กนี้จะแสดง Turbo Frames ที่เราพูดถึง
เป็นทรัพยากรที่ยอดเยี่ยมเมื่อคุณต้องการแยกส่วนของเพจและเปิดอุโมงค์ข้อมูลโดยตรงด้วยแอปแบ็กเอนด์ เพื่อให้ Turbo แนบคำขอและตอบกลับไปยังเฟรมเฉพาะนี้ได้
ในการทดสอบ ก่อนอื่นคุณต้องรวมเนื้อหาทั้งหมดของ _form.html.erb ของคุณ ไฟล์ภายในแท็กนี้:
<%= turbo_frame_tag post do %>
...
<% end %>
โพสต์มีเหตุผลที่ชัดเจนในกรณีของแบบฟอร์ม เมื่อคุณกลับมาที่เบราว์เซอร์และทดสอบอีกครั้ง ข้อผิดพลาดในการตรวจสอบความถูกต้องเดิมจะปรากฏขึ้นตามที่คาดไว้
สิ่งที่น่าสนใจอีกอย่างที่ควรทราบที่นี่คือ HTML ที่สร้างขึ้นสำหรับแบบฟอร์มนั้น ลองดูสิ:
<turbo-frame id="new_post">
<form action="/posts" accept-charset="UTF-8" method="post">
...
</form>
</turbo-frame>
องค์ประกอบ HTML ที่กำหนดเองนี้เป็นวิธีที่ Turbo แยกแยะเฟรมจากการกระทำแบบทั้งหน้า
แถบความคืบหน้า
เป็นเรื่องปกติที่เมื่อคุณลบกลไกการโหลดเริ่มต้นของเบราว์เซอร์ คุณจะต้องระบุกลไกอื่นสำหรับกรณีที่หน้าเว็บโหลดช้า
Turbo มีแถบความคืบหน้าแบบ CSS ในตัวอยู่แล้วที่ด้านบนสุดของหน้า ซึ่งคล้ายกับที่มีให้ในไลบรารีหลักๆ เช่น Bootstrap และ Material Design
โดยตั้งค่าให้แสดงเฉพาะเมื่อคำขอใช้เวลาประมวลผลมากกว่า 500 มิลลิวินาที ซึ่งไม่นานพอสำหรับโครงการทดสอบของเรา
หากคุณต้องการเปลี่ยนรูปแบบหรือลบออกทั้งหมด คุณสามารถลองใช้ .turbo-progress-bar
คลาส CSS ดังที่แสดงด้านล่าง:
.turbo-progress-bar {
height: 15px;
background-color: gold;
}
หากต้องการทดสอบ คุณจะต้องลดความล่าช้าของแถบความคืบหน้าใน application.js ไฟล์ด้วยรหัสต่อไปนี้:
window.Turbo.setProgressBarDelay(1);
เวลาที่ระบุมีหน่วยเป็นมิลลิวินาที ด้านล่างนี้ คุณจะพบการแสดงรูปแบบที่อัปเดตสำหรับแถบความคืบหน้า
แสดงแถบความคืบหน้าที่อัปเดต
สรุปผล
มีอะไรอีกมากมายให้พูดคุยเกี่ยวกับ Turbo และคุณสมบัติที่น่าทึ่ง เช่น สตรีมและโมดูลเนทีฟ อย่างไรก็ตาม เพื่อให้บทความมีความเข้มข้น เราจะยึดตามขั้นตอนเริ่มต้นเหล่านี้
เช่นเคย ฉันไม่สามารถหลีกเลี่ยงการแนะนำ Turbo Handbook อย่างเป็นทางการได้ เนื่องจากมันมีประโยชน์มากเมื่อฉันเริ่มต้นกระบวนการย้ายข้อมูลทั้งหมดนี้ คุณจะพบเอกสารทั้งหมดที่จำเป็นสำหรับจัดการกับเงื่อนไขพิเศษที่โครงการต้องการที่นั่น
ตัวอย่างเช่น หากแอปของคุณใช้ Devise คุณอาจต้องมีการดัดแปลงบางอย่าง โชคดีที่ทีม Turbo ได้จัดทำบทแนะนำที่ยอดเยี่ยมเกี่ยวกับหัวข้อนี้เพื่อช่วยเหลือเกี่ยวกับสิ่งเล็กๆ น้อยๆ เกี่ยวกับ Devise with Turbo