احتمالاً تا حالا اسم Hotwire به گوشت خورده و شاید پیش خودت فکر کردی "چه اسم بامزه ای، ولی واقعاً چیه؟ و اصلاً من باید بهش اهمیت بدم؟"
منم دقیقاً همین سوال تو ذهنم بود، پس شروع کردم به تحقیق و هر چی یاد گرفتم رو نوشتم. اگه ۱۰ دقیقه وقت داری و کنجکاوی بدونی Hotwire و Turbo چیه، ادامه مطلب رو بخون.
نگران نباش! لازم نیست حتماً برنامه نویس Ruby on Rails باشی تا این موضوع رو بفهمی. ایدههای پشت Hotwire و رندر سمت سرور الان دارن توی تکنولوژیهای مختلف وب استفاده میشن. پلتفرم هایی مثل PHP/Laravel، Elixir/Phoenix، Python/Django هم ابزارهای مشابهی دارن که Hotwire رو پیاده سازی میکنن. حتی React هم به تازگی پشتیبانی از رندر سمت سرور رو اضافه کرده.
اینجا میخوایم مفاهیم رو کامل و ساده برات توضیح بدیم. پس یه فنجون قهوه بردار و شروع به خوندن کن. ☕😊
Hotwire در واقع یه روش برای ساخت اپلیکیشنهای وبه، اما خودش یه تکنولوژی خاص نیست. میشه گفت یه "چتر" هست که سه تا تکنولوژی اصلی رو در بر گرفته: Turbo، StimulusJS و Strada (تو دنیای Ruby on Rails). ولی اون چیزی که واقعاً Hotwire رو به کار میندازه، همون Turbo هست. توربو در واقع کدیه که این روش رو ممکن میکنه.
حتی اگه Turbo رو تیم Ruby on Rails ساخته باشه و یه جورایی نسخه پیشرفته Turbolinks باشه، اما اون فقط محدود به Rails نیست. این تکنولوژی رو میتونی تو زبانها و فریمورکهای بک اند دیگه مثل PHP، Python و... هم استفاده کنی. پس Turbo فقط برای Rails نیست.
Turbo به توسعه دهندهها کمک میکنه که اپلیکیشنهای وب رو سریعتر و سادهتر بسازن، بدون اینکه نیاز زیادی به جاوااسکریپت باشه. تو این روش، همه محاسبات و منطقها روی سرور انجام میشن و مرورگر فقط HTML نهایی رو میگیره و نمایش میده. این یعنی لازم نیست کلی کد جاوااسکریپت بنویسی تا دادهها رو از سرور بگیری و روی صفحه نشون بدی.
برای مقایسه، روش SPA (Single Page Application) رو در نظر بگیر. تو SPA ما دادههای JSON رو از سرور میگیریم، بعد کلی جاوااسکریپت مینویسیم تا اون دادهها رو تبدیل کنیم به HTML و صفحه رو به روز کنیم. ولی تو Turbo، این کارا به سادگی و با کمترین جاوااسکریپت انجام میشه و بیشتر کارها رو سرور هندل میکنه.
وعده Turbo اینه که به جای اینکه وقتت رو برای نوشتن کلی کد جاوااسکریپت هدر بدی، میتونی بیشتر از زبان بک اند دلخواهت مثل Ruby، PHP یا Python استفاده کنی. همه منطقها و محاسبات تجاری تو یه جا یعنی روی سرور قرار میگیرن. علاوه بر این، از پیچیدگیهای استفاده از فریم ورکهای جاوااسکریپتی و ابزارهایی مثل webpack خلاص میشی. تنها چیزی که نیاز داری، همون Turbo.js هست.
Turbo با چند تا بخش اصلی کار میکنه:
نکته: فرق WebSocket و SSE اینه که WebSocket ارتباط دوطرفه بین سرور و مرورگر رو ممکن میکنه، ولی تو SSE فقط سرور میتونه دادهها رو به مرورگر بفرسته.
خب، بیایم ببینیم Turbo Drive چطوری کار میکنه. هدفش اینه که همون سرعت بالای اپلیکیشنهای تک صفحه ای (SPA) رو بهت بده، بدون اینکه لازم باشه از روشهای پیچیده استفاده کنی. یه جورایی Turbo همه کارها رو مدیریت میکنه؛ نیازی به روتر سمت کلاینت نیست و لازم نیست حالتها رو به دقت کنترل کنی.
Turbo Drive کلیک روی تمام لینکهای <a href> که به همون دامنه اشاره میکنن رو رهگیری میکنه. یعنی چی؟ یعنی وقتی روی یه لینک کلیک میکنی، Turbo به جای اینکه مرورگر صفحه جدید رو بارگذاری کنه، خودش URL رو با استفاده از History API تغییر میده، محتوای جدید رو با استفاده از fetch میگیره و بعد نتیجه رو به صورت HTML توی صفحه نشون میده. اینطوری بدون اینکه کل صفحه بارگذاری بشه، فقط همون بخشهای مورد نیاز تغییر میکنن.
نکته: History API بهت اجازه میده تاریخچه مرورگر رو دستکاری کنی. مثلاً از تابع pushState() استفاده میکنه تا URL رو بدون بارگذاری دوباره صفحه به روز کنه، همون کاری که pjax قبلاً انجام میداد.
وقتی فرم ارسال میشه، Turbo Drive کل محتوای <body> صفحه رو جایگزین میکنه و محتوای داخل <head> رو به روزرسانی میکنه. جالب اینجاست که آبجکتهای جاوااسکریپتی مثل window و document و حتی عنصر <html> بین بارگذاریهای مختلف ثابت میمونن. این یعنی بدون نیاز به بارگذاری مجدد کل صفحه، صفحه با سرعت آپدیت میشه.
نکته جذاب اینجاست که این سرعت بالا رو فقط با رعایت چند تا قاعده ساده به دست میاری. البته اگه بخوای، میتونی خودت مستقیماً با Turbo Drive تعامل داشته باشی و کنترل بیشتری روی اینکه چطوری بازدیدها انجام بشن یا به چرخه حیات درخواستها دسترسی پیدا کنی. ولی معمولاً با تنظیمات پیش فرضش هم کار رو به بهترین شکل انجام میده.

حالا برسیم به Turbo Frames. این ابزار یه راه خیلی خوب برای اینه که بخشهای مختلف یه صفحه رو به قسمتهای مستقل تقسیم کنی. این بخشها داخل یه عنصر به اسم turbo-frame قرار میگیرن و میتونن با تاخیر (یا همون lazy loading) بارگذاری بشن. نکته جالب اینجاست که وقتی داخل یه فریم روی لینک کلیک میکنی یا یه فرم ارسال میکنی، فقط همون بخش آپدیت میشه و بقیه صفحه همونطوری که هست، میمونه.
یه بار تو مصاحبه ای با DHH (سازنده Ruby on Rails) شنیدم که میگفت ایده Turbo Frames از اینجا اومده که میخواستن ایمیلهای موبایلی تو سرویس Hey درست کار کنن.
مثلاً این کد رو ببین:
<turbo-frame id="new_message">
<form action="/messages" method="post">
...
</form>
</turbo-frame>وقتی این فرم رو ارسال میکنی، Turbo اون بخشی از پاسخ سرور که مربوط به همون فریم new_message هست رو میگیره و محتوای جدید رو تو همون فریم بارگذاری میکنه. بقیه صفحه اصلاً دست نمیخوره و همونطوری که بود باقی میمونه.
اگه بخوای یه بخش از صفحه رو با تاخیر بارگذاری کنی، میتونی از ویژگی src استفاده کنی:
<turbo-frame id="messages" src="/messages">
<p>This message will be replaced by the response from /messages.</p>
</turbo-frame>این یعنی وقتی صفحه لود شد، محتوای این بخش بعداً از /messages درخواست میشه و جایگزین پیام پیش فرض میشه.
شاید فکر کنی Turbo Frames شبیه iframes باشه، ولی نه! فرق دارن. Turbo Frames توی همون DOM صفحه اصلی هستن، همون CSS رو استفاده میکنن و توی همون کانتکست جاوااسکریپت قرار دارن. پس از اون مشکلات و عجیب وغریب بودن iframes خبری نیست!
تا اینجا با Turbo Frames آشنا شدی که بهت اجازه میدن بخش هایی از صفحه رو بر اساس تعاملات مستقیم مثل کلیک روی لینک یا ارسال فرم، به روزرسانی کنی. حالا Turbo Streams یه قدم جلوتر میره و بهت امکان میده هر قسمتی از صفحه رو بر اساس دادههای زنده از WebSocket یا SSE به روز کنی، بدون اینکه نیاز باشه خودت دستی وارد عمل بشی.
یه نکته تاریخی جالب: مفهوم Streams در واقع ادامه همون چیزی هست که تو سالهای قبل بهش RJS و بعدش SJR میگفتن. RJS که تو Rails 1.1 در سال ۲۰۰۶ معرفی شد، این ایده رو داشت که برای اضافه کردن قابلیتهای Ajax نیازی نیست جاوااسکریپت بنویسی، میتونستی همون رو با نوشتن کد Ruby انجام بدی. ایده ای که هنوزم ادامه داره!
بعدش، SJR (Server-generated Javascript Response) که تو سال ۲۰۱۳ معرفی شد، خیلی شبیه به چیزی بود که الان با Turbo داریم. جریان کار اینطوری بود: یه فرم از طریق درخواست Ajax ارسال میشد، سرور یه پاسخ جاوااسکریپتی میفرستاد که شامل یه قالب HTML به روز شده بود و مرورگر این کد جاوااسکریپت رو اجرا میکرد تا DOM رو آپدیت کنه. با Streams، ما همین جریان رو ادامه میدیم ولی با این تفاوت که حالا دیگه نیازی به نوشتن جاوااسکریپت نیست و تمرکز روی ارسال HTML و به روزرسانی مستقیم DOM شده.
برخلاف RJS و SJR، در Turbo Streams به طور عمدی امکان ارسال جاوااسکریپت سفارشی رو نداری! این به این دلیل طراحی شده که تمرکز فقط روی ارسال HTML و به روزرسانی خودکار DOM باشه. اگه نیاز به رفتار خاصی داری، میتونی از اکشنها و کال بکهای Stimulus استفاده کنی تا رفتارهای اضافی رو مدیریت کنی.
این رویکرد جدید، یعنی به جای جاوااسکریپت تمرکز روی HTML و DOM، تجربه توسعه وب رو سادهتر میکنه و باعث میشه کمتر درگیر کدهای پیچیده جاوااسکریپتی بشی. این همون چیزیه که باعث میشه اپلیکیشنهای وب مدرن سریعتر و بهتر کار کنن، درست مثل زمانی که در سال ۲۰۱۳ گفته شد ترکیب Turbolinks، Russian Doll-caching و SJR یه ترکیب جادویی برای ساخت اپهای سریع و زیباست.
حالا بیایم ببینیم Turbo Streams دقیقاً چطور کار میکنه. یه عنصر جدید به اسم <turbo-stream> معرفی میکنه که دو تا ویژگی مهم داره: action و target. اکشنها کارهایی مثل append (اضافه کردن به انتهای یه بخش)، prepend (اضافه کردن به ابتدای یه بخش)، replace (جایگزینی یه بخش)، update (به روزرسانی یه بخش)، remove (حذف کردن) و چند تا چیز دیگه مثل before و after رو شامل میشه.
وقتی این عنصر رو توی HTML قرار بدی، Turbo خودش بقیه کارها رو انجام میده. فقط کافیه که محتوای جدیدی که میخوای اضافه یا جایگزین بشه رو توی یه تگ <template> قرار بدی، و Turbo به طور خودکار اون رو به صفحه اضافه میکنه یا تغییرات رو اعمال میکنه.
نکته: تگ <template> توی HTML یه روشه برای نگه داشتن محتوایی که قرار نیست همون لحظه که صفحه لود میشه نمایش داده بشه، ولی بعداً میتونه با جاوااسکریپت به صفحه اضافه بشه.
Turbo Streams این کارو خیلی راحت و بدون نیاز به نوشتن کدهای پیچیده جاوااسکریپتی برات انجام میده.
۱. استفاده مجدد از قالبهای سمت سرور: Turbo Streams بهت این امکان رو میده که همون قالب هایی که برای بار اول صفحه استفاده شدن رو برای آپدیتهای زنده هم به کار ببری. یعنی لازم نیست دوباره از اول یه قالب جدید بنویسی. فقط گاهی ممکنه نیاز باشه با یه مقدار CSS، بعضی از عناصر رو مخفی یا نمایش بدی تا تو هر دو حالت درست کار کنه.
۲. ارسال HTML به جای JSON: یه ویژگی فوق العاده Turbo Streams اینه که دیگه نیازی به جاوااسکریپت سمت کلاینت (جز Turbo.js) نداری. این یعنی لازم نیست کلی وقت بذاری تا JSON رو بگیری و تبدیلش کنی به HTML. با Turbo، همون HTML از سرور میاد و مستقیماً توی صفحه استفاده میشه.
۳. جریان کنترلی ساده تر: با Turbo Streams، کنترل کارها خیلی راحتتر میشه. تو فقط به HTML نگاه میکنی و میبینی چه بخشی از صفحه داره تغییر میکنه. دیگه خبری از پیچیدگیهای روتر سمت کلاینت، event bubbling و این جور چیزا نیست. همه چیز ساده و شفافه!
خب، بذار در مورد Turbo Native یه توضیح خودمونی بدم. شاید مثل من موبایل دولوپر نباشی، ولی اینجا چند نکته که از خوندن درباره Turbo Native یاد گرفتم رو برات مینویسم:
Turbo Native یه گزینه خیلی خوبه برای ساخت اپلیکیشنهای هیبریدی. یعنی چی؟ یعنی میتونی از HTML رندر شده روی سرور استفاده کنی تا بخشهای اصلی اپلیکیشن رو بسازی، و فقط چند تا صفحه بومی (native) هم داشته باشی که به دقت بیشتری نیاز دارن. اینطوری ترکیبی از سرعت توسعه وب و کارایی اپلیکیشنهای بومی رو داری.
یکی از مزیتهای هیبریدی بودن اینه که هر وقت خواستی اپ رو آپدیت کنی، لازم نیست صبر کنی تا تاییدیه اپ استور رو بگیری. هر چی که با HTML انجام دادی رو میتونی توی اپلیکیشن وب تغییر بدی و بلافاصله به دست کاربرا برسه.
اما یه نکته مهم: Turbo Native یه فریم ورک نیست که بخواد APIهای بومی رو خلاصه کنه یا کدی ایجاد کنه که بین پلتفرمها (iOS و Android) به اشتراک گذاشته بشه. در واقع هنوز هم به توسعه دهندههای بومی نیاز داری، ولی کارشون کمتر میشه چون فقط باید روی بخشهای بومی کار کنن. اون چیزی که بین پلتفرمها مشترک هست، همون HTMLیه که از سمت سرور رندر میشه.
تا اینجا با Turbo Drive، Turbo Frames و Turbo Streams آشنا شدیم. حالا وقتشه یه سری نکات ریزتر رو هم بدونیم که موقع ساخت اپلیکیشن با Turbo باید مدنظر داشته باشیم.
یه نکته مهم: درسته که Turbo مختص Rails نیست، اما gem turbo-rails پیاده سازی مرجع Turbo برای Rails محسوب میشه. توی مستندات Turbo هم گفته شده که برای استفاده از Turbo نیاز به یه فریم ورک بک اند نداری. (البته این یکی رو هنوز درست متوجه نشدم، چون به نظر من بک اند باید HTML درست با تگهای <turbo-stream> و <turbo-frame> برگردونه تا همه چیز سر جای خودش باشه!)
خب، حالا که توی Turbo خبری از بارگذاری کامل صفحات نیست، یه سری نکات ریز وجود داره که باید حواسمون بهشون باشه. چون آبجکتهای جاوااسکریپت مثل window و document و هر چیزی که توی حافظه گذاشتیم، بین تغییرات صفحه ثابت میمونن. یعنی نمیتونیم به بارگذاری دوباره صفحه برای ریست کردن محیط اپلیکیشن تکیه کنیم. باید اپلیکیشنمون رو جوری طراحی کنیم که با این وضعیت سازگار باشه.
وقتی با Turbo به صفحات مختلف میریم، اسکریپت هایی که توی تگ <head> هستن مشکلی ندارن؛ Turbo Drive اونها رو به تگ <head> فعلی اضافه میکنه و مرورگر همونجا لودشون میکنه.
اما اسکریپت هایی که توی <body> باشن دردسر درست میکنن. اگه میخوای موقع تغییر صفحه یه سری عملیات پیچیده انجام بدی یا رفتاری رو به صفحه اضافه کنی، به جای اینکه از تگ اسکریپت استفاده کنی، بهتره از رویداد turbo استفاده کنی.
برای اسکریپت هایی که نمیخوای Turbo بعد از رندر کردن صفحه ارزیابی کنه، باید از ویژگی data-turbo-eval="false" استفاده کنی. مرورگر فقط توی بارگذاری اول اونها رو اجرا میکنه.
برای لود کردن باندلهای جاوااسکریپت اپلیکیشن، همیشه این کار رو توی تگ <head> انجام بده. اگه هم میخوای Turbo یه بارگذاری کامل صفحه رو انجام بده وقتی که باندل جدید جاوااسکریپت منتشر شد، میتونی به اسکریپتت ویژگی data-turbo-track="reload" رو اضافه کنی.
قبل از هر چیز، باید بدونیم منظور از Restoration visits و Application visits چیه.
وقتی Turbo Drive یه کپی از صفحه رو توی کش ذخیره میکنه، از تابع cloneNode(true) استفاده میکنه. این یعنی لیسنرهای رویداد و دادهها پاک میشن (چون cloneNode فقط خود DOM رو کپی میکنه).
اگه لازم باشه قبل از اینکه Turbo صفحه رو کش کنه، کاری انجام بدی (مثل ریست کردن فرمها یا جمع کردن اجزای UI)، میتونی به رویداد turbo
گوش بدی و تغییرات لازم رو اعمال کنی. مثلاً میتونی این کار رو با document.addEventListener انجام بدی.
وقتی Turbo Drive یه صفحه رو از کش نمایش میده، به تگ <html> ویژگی data-turbo-preview اضافه میکنه. میتونی از این ویژگی برای فعال یا غیرفعال کردن رفتارهای خاص توی صفحه استفاده کنی.
اگه بخوای کشینگ رو برای یه صفحه خاص غیرفعال کنی، میتونی از تگ <meta> توی <head> صفحه استفاده کنی، مثل این:
<head>
...
<meta name="turbo-cache-control" content="no-cache">
</head>معمولاً اتفاقات مثل window.onload، DOMContentLoaded یا JQuery ready فقط بعد از بارگذاری اولیه صفحه اجرا میشن. اما وقتی با Turbo کار میکنیم و صفحهها به صورت جزئی لود میشن، نیاز داریم که یه راه حل برای نصب رفتارهای جاوااسکریپت بعد از هر بار لود شدن صفحه پیدا کنیم. دو تا گزینه داریم:
یه رویدادی داریم به اسم turbo:load
که بعد از بارگذاری اولیه صفحه و هر بار که با Turbo Drive صفحه ای رو باز میکنی، اجرا میشه. میتونیم از این رویداد به این شکل استفاده کنیم:
document.addEventListener("turbo:load", function() {
// اینجا کد جاوااسکریپتت رو مینویسی
})نکته مهم اینه که نباید از turbo:load برای اضافه کردن مستقیم لیسنرهای رویداد به عناصر داخل بدنه صفحه (body) استفاده کنی. به جای این کار بهتره از event delegation استفاده کنی، یعنی لیسنرها رو فقط یه بار روی کل سند (document) یا پنجره (window) ثبت کنی.
وقتی داری با Turbo کار میکنی، ممکنه هر لحظه یه عنصر جدید توی صفحه ظاهر بشه؛ چه از طریق ناوبری با فریم ها، چه پیامهای استریم، چه رندر سمت کلاینت و یا بارگذاری صفحه با Turbo Drive. اینجاست که Stimulus به درد میخوره. Stimulus با استفاده از callbackهای چرخه عمرش و روشهای ساده ای که داره، میتونه همه این تغییرات رو تو یه جا مدیریت کنه.
Stimulus با استفاده از MutationObserver API، تغییرات توی سند رو بررسی میکنه و کنترلرها و لیسنرهای رویدادش رو به صورت خودکار وصل و قطع میکنه. این باعث میشه که Stimulus بتونه همه نوع به روزرسانیهای DOM رو مدیریت کنه.
اینجا منظور از تغییرات بی اثر اینه که وقتی یه تابع یا تغییر رو به HTML اعمال میکنی، مهم نیست چند بار این کار رو تکرار کنی؛ نتیجه باید مثل دفعه اول باقی بمونه. یعنی بعد از اولین بار اعمال تغییر، دیگه چیزی نباید تغییر کنه.
چرا این مهمه؟ به خاطر کشینگ. مثلا فرض کن یه تابع داری که تو رویداد turbo:load اجرا میشه و به یه مجموعه از عناصر تاریخ اضافه میکنه. وقتی به صفحه میری، این تابع سربرگهای تاریخ رو اضافه میکنه. حالا تصور کن که از صفحه خارج میشی و Turbo Drive یه کپی از این صفحه رو توی کش ذخیره میکنه. وقتی دوباره با دکمه «برگشت» مرورگر به صفحه برمی گردی، Turbo Drive صفحه رو از کش بازمی گردونه و دوباره رویداد turbo:load اجرا میشه. اگه حواست نباشه، این دفعه سربرگهای تاریخ دوباره اضافه میشن و صفحه به هم میریزه.
راه حل چیه؟ قبل از اینکه تابع رو دوباره اجرا کنی، چک کنی که آیا این تغییرات قبلاً اعمال شدن یا نه. مثلاً میتونی بررسی کنی که آیا یه عنصر تقسیم کننده ی تاریخ قبلاً وجود داره یا نه. (همچنین میتونی یه flag از طریق data اضافه کنی، ولی این روش کمتر مطمئن هست.)
بعضی وقتها ممکنه نخوایم که یه سری از عناصر توی صفحه، وقتی کاربر بین صفحات جابجا میشه، تغییر کنن. اینجاست که Turbo Drive بهت اجازه میده اون عناصر رو ثابت (permanent) کنی. مثلا تصور کن که یه آیکون سبد خرید داری که تعداد آیتمها رو نشون میده. نمیخوای وقتی کاربر بعد از اضافه کردن آیتم به سبد، با دکمه "بازگشت" مرورگر به صفحه قبل برمی گرده، این شمارنده به عدد پایینتری تغییر کنه.
برای این کار، کافیه که اون عنصر رو به عنوان "ثابت" مشخص کنی:
<div id="cart-counter" data-turbo-permanent>1 item</div>اینجا، id عنصر خیلی مهمه چون Turbo Drive همه عناصر ثابت رو از طریق id شناسایی میکنه. وقتی صفحه جدید لود میشه، Turbo Drive این عناصر رو از صفحه قبلی به صفحه جدید منتقل میکنه و دادهها و لیسنرهای رویدادها رو هم حفظ میکنه.

Hotwire یه مفهوم کلیه که روشهای مختلفی مثل Turbo، Stimulus و Strada رو در بر میگیره. Turbo در واقع یکی از تکنولوژی هاییه که توی Hotwire قرار داره و وظیفه اش به روزرسانی سریع صفحه هاست، بدون اینکه نیازی به بارگذاری کامل صفحه باشه.
نه، درسته که Turbo توسط تیم Rails ساخته شده، ولی میتونی ازش توی هر فریم ورک یا زبان بک اند دیگه ای هم استفاده کنی. مثلاً زبان هایی مثل PHP، Python، و Elixir هم تکنولوژی هایی مشابه Turbo دارن که میتونی باهاشون کار کنی.
خوشبختانه نیازی به نوشتن کلی جاوااسکریپت نیست. Turbo برای این طراحی شده که تا حد امکان بدون جاوااسکریپت سمت کلاینت کار کنه. فقط لازمه که از Turbo.js استفاده کنی و بقیه کارها با HTML و سمت سرور انجام میشه.
بله، چون Turbo به جای استفاده از JSON، از HTML استفاده میکنه. محتوای صفحهها به شکل HTML رندر شده و به مرورگر ارسال میشه، که برای موتورهای جستجو مثل گوگل کاملاً قابل فهمه.
Turbo Drive کلیکها روی لینکها و ارسال فرمها رو مدیریت میکنه و به جای اینکه کل صفحه رو دوباره لود کنه، فقط بخشهای ضروری رو آپدیت میکنه. این باعث میشه سرعت سایت بالا بره و تجربه کاربری بهتر بشه.
بله، با استفاده از Turbo Native میتونی اپلیکیشنهای هیبریدی بسازی که هم از قدرت HTML رندر شده روی سرور استفاده کنن و هم از صفحههای بومی (native) که توی iOS و Android به صورت اختصاصی اجرا میشن.
Turbo Frames شبیه iframes هستن چون بهت اجازه میدن فقط بخشی از صفحه رو آپدیت کنی، ولی فرقشون اینه که Turbo Frames توی همون DOM قرار دارن، از همون CSS استفاده میکنن و توی همون کانتکست جاوااسکریپت اجرا میشن. پس مشکلات عجیبی که iframes داره اینجا وجود نداره.
Turbo Streams بهت اجازه میده بخشی از صفحه رو به صورت زنده آپدیت کنی. مثلاً وقتی از WebSocket یا SSE استفاده میکنی، میتونی بدون نیاز به رفرش کل صفحه، دادههای جدید رو به صفحه اضافه کنی یا بخشی از صفحه رو تغییر بدی.
Turbo به طور پیش فرض صفحات رو کش میکنه. اما اگه بخوای کشینگ رو برای یه صفحه خاص غیرفعال کنی، میتونی از این تگ استفاده کنی:
<meta name="turbo-cache-control" content="no-cache">نه، برای بعضی از اپلیکیشنهای پیچیده که نیاز به رندر سمت کلاینت دارن، مثل ویرایشگرهای متنی پیشرفته، ممکنه استفاده از تکنولوژیهای دیگه مثل فریم ورکهای جاوااسکریپتی مناسبتر باشه. اما برای اکثر اپلیکیشنهای مدرن، استفاده از Hotwire و Turbo یه انتخاب عالی هستن چون پیچیدگیها رو کاهش میدن و تجربه توسعه رو سادهتر میکنن.
خب، رسیدیم به آخر خط! تا اینجا بیشتر مفاهیم اصلی Turbo و Hotwire رو توضیح دادیم. اصل ماجرا اینه که چطور میتونیم چیزهایی که تو صفحه هست رو سریع و روان آپدیت کنیم، بدون اینکه مجبور بشیم کلی کد جاوااسکریپت سمت کاربر بنویسیم.
Hotwire یا همون HTML-over-the-wire یه مفهومه، نه یه تکنولوژی خاص. ایده اصلی اینه که به جای ارسال جیسون، HTML رندر شده از سمت سرور رو به مرورگر بفرستیم و بیشتر منطق اپلیکیشن هم توی سرور اجرا بشه.
Turbo همون تکنولوژیه که تو دنیای Rails پیاده سازی Hotwire رو انجام میده. البته سایر فریم ورکها و زبانهای بک اند هم نسخههای خودشون از Turbo رو دارن. Turbo از سه بخش اصلی تشکیل شده: Drive، Frames و Streams.
موقع ساخت اپلیکیشن با Turbo باید حواست باشه که اپلیکیشنت به صورت یه فرایند پایدار و طولانی مدت تو مرورگر اجرا میشه. دیگه نمیتونی به بارگذاری مجدد صفحه برای ریست کردن محیطت تکیه کنی. باید به مسائل مهمی مثل کشینگ، اسکریپتها و نصب رفتارهای جاوااسکریپتی دقت کنی.
آخر سر، اینم بگم که روش Hotwire و Turbo برای همه نوع اپلیکیشن وب مناسب نیست. بعضی وقت ها، پیچیدگی رندر سمت کلاینت با یه اپلیکیشن تک صفحه ای (SPA) لازمه تا تجربه کاربری کاملی داشته باشیم، مثل ویرایشگر متن Trix از جامعه Rails. ولی برای خیلی از اپلیکیشنهای مدرن، استفاده از Hotwire و Turbo میتونه پیچیدگیها رو به شدت کاهش بده و تجربه ساخت رو سادهتر کنه.
اگه تا اینجا همراه ما بودی، دمت گرم! 💙 امیدوارم چیزهای خوبی یاد گرفته باشی!
دوره الفبای برنامه نویسی با هدف انتخاب زبان برنامه نویسی مناسب برای شما و پاسخگویی به سوالات متداول در شروع یادگیری موقتا رایگان شد: