تکامل سیگنال ها در جاوا اسکریپت
اخیراً در دنیای جلویی در مورد اصطلاح “سیگنال” سروصداهایی به وجود آمده است. بهنظر میرسد که در یک ترتیب کوتاه، همه جا در همه چیز از Preact گرفته تا Angular ظاهر میشوند.
اما آنها چیز جدیدی نیستند. حتی اگر فکر کنید نمی توانید ریشه در تحقیقات در اواخر دهه 1960 داشته باشید. اساس آن همان مدلسازی است که اولین صفحات گسترده الکترونیکی و زبانهای توصیف سختافزار (مانند Verilog و VHDL) را فعال کرد.
حتی در جاوا اسکریپت، ما آنها را از ابتدای پیدایش چارچوب های جاوا اسکریپت اعلامی داشته ایم. آنها در طول زمان نام های مختلفی را یدک می کشند و در طول سال ها محبوبیت زیادی پیدا کرده اند. اما ما دوباره اینجا هستیم، و زمان خوبی است که کمی بیشتر در مورد چگونگی و چرایی توضیح دهیم.
سلب مسئولیت: من نویسنده SolidJS هستم. این مقاله تکامل را از منظر تأثیرات من منعکس می کند. سیگنالهای Elm، ویژگیهای محاسبهشده Ember، و Meteor همگی شایستگی فریاد زدن دارند، اگرچه در مقاله پوشش داده نشدهاند.
مطمئن نیستید سیگنال ها چیست یا چگونه کار می کنند؟ این مقدمه بر واکنش پذیری ریز دانه را بررسی کنید:
در آغاز…
گاهی اوقات تعجب آور است که متوجه شوید چندین طرف دقیقاً در یک زمان به راه حل های مشابه می رسند. شروع چارچوب های جاوا اسکریپت اعلامی دارای 3 برداشت بود که همه آنها در عرض 3 ماه از یکدیگر منتشر شدند: Knockout.js (ژوئیه 2010)، Backbone.js (اکتبر 2010)، Angular.js (اکتبر 2010).
بررسی کثیف Angular، رندرهای مبتنی بر مدل Backbone و بهروزرسانیهای دقیق Knockout. هر کدام کمی متفاوت بود اما در نهایت به عنوان مبنایی برای نحوه مدیریت وضعیت و به روز رسانی DOM امروز عمل می کند.
Knockout.js اهمیت ویژهای برای موضوع این مقاله دارد، زیرا بهروزرسانیهای دقیق آنها بر اساس چیزی ساخته شدهاند که ما آن را سیگنالها مینامیم. آنها در ابتدا 2 مفهوم را معرفی کردند observable
(ایالت) و computed
(عوارض جانبی) اما در طی چند سال آینده سومین مورد را معرفی خواهد کرد pureComputed
(وضعیت مشتق شده) به زبان پیشانی.
const count = ko.observable(0);
const doubleCount = ko.pureComputed(() => count() * 2);
// logs whenever doubleCount updates
ko.computed(() => console.log(doubleCount()))
غرب وحشی
الگوها ترکیبی از الگوهای آموخته شده از توسعه MVC در سرور و چند سال گذشته جی کوئری بودند. یک مورد رایج خاص Data Binding نام داشت که توسط Angular.js و Knockout.js به اشتراک گذاشته شد، هرچند به روشهای کمی متفاوت.
Data Binding این ایده است که یک قطعه حالت باید به قسمت خاصی از درخت view متصل شود. یکی از کارهای قدرتمندی که می شد انجام داد، ساخت این دو جهته بود. بنابراین می توان DOM را به روز رسانی کرد و به نوبه خود، رویدادهای DOM به طور خودکار وضعیت را به روشی ساده به روز می کنند.
با این حال، سوء استفاده از این قدرت به یک تفنگ پا تبدیل شد. اما بدون دانستن بهتر، ما برنامه های خود را به این ترتیب ساختیم. در Angular بدون اطلاع از چه تغییراتی، کل درخت را کثیف بررسی می کند و انتشار رو به بالا می تواند باعث شود چندین بار اتفاق بیفتد. در ناک اوت، پیمودن مسیر تغییر را دشوار میکرد، زیرا از درخت بالا و پایین میرفتید و چرخهها معمول بودند.
زمانی که React با یک راه حل ظاهر شد، و برای شخص من، صحبت های جینگ چن بود که آن را تثبیت کرد، ما برای پرش از کشتی آماده بودیم.
اشکال رایگان
آنچه در پی داشت، پذیرش گسترده React بود. برخی از افراد هنوز مدلهای واکنشی را ترجیح میدهند و از آنجایی که React در مورد مدیریت دولتی چندان نظری نداشت، ترکیب هر دو بسیار ممکن بود.
Mobservable (2015) این راه حل بود. اما بیشتر از کار با React، چیز جدیدی را روی میز آورد. این بر ثبات و انتشار بدون اشکال تأکید داشت. این بدان معناست که برای هر تغییر معین، هر بخش از سیستم فقط یک بار و به ترتیب مناسب به طور همزمان اجرا می شود.
این کار را با معامله واکنش پذیری مبتنی بر فشار معمولی که در پیشینیان خود با یک سیستم هیبریدی فشار-کشش یافت می شد انجام داد. اعلان تغییرات حذف می شود اما اجرای حالت مشتق شده به جایی که خوانده شده است به تعویق افتاده است.
برای درک بهتر رویکرد اصلی Mobservable، نگاه کنید به: Becoming Fully Reactive: An Depth Explanation of Mobservable توسط Michel Westrate.
در حالی که این جزئیات تا حد زیادی تحت الشعاع این واقعیت بود که React فقط مؤلفههایی را که تغییرات را میخوانند دوباره رندر میکرد، این یک گام بزرگ رو به جلو در ایجاد اشکالزدایی و سازگاری این سیستمها بود. در طی چندین سال بعد، با اصلاحتر شدن الگوریتمها، شاهد روندی به سمت معناشناسی مبتنی بر کشش خواهیم بود.
تسخیر ناظران نشتی
واکنش ریز دانه نوعی از الگوی مشاهده گر گروه چهار است. در حالی که یک الگوی قدرتمند برای همگام سازی است، یک مشکل کلاسیک نیز دارد. سیگنال یک مرجع قوی به مشترکین خود نگه می دارد، بنابراین یک سیگنال با عمر طولانی همه اشتراک ها را حفظ می کند مگر اینکه به صورت دستی دفع شود.
این حسابداری با استفاده قابل توجه، به ویژه در مواردی که تودرتو در آن دخیل است، بسیار پیچیده می شود. تودرتو در هنگام کار با منطق شاخهای و درختان رایج است، همانطور که هنگام ساخت نماهای UI پیدا میکنید.
یک کتابخانه کمتر شناخته شده، S.js (2013)، پاسخ را ارائه می دهد. S مستقل از بسیاری از راه حل های دیگر توسعه یافت و مستقیماً پس از مدارهای دیجیتالی که در آن تمام تغییرات حالت بر روی چرخه های ساعت کار می کرد، مدل سازی شد. این حالت خود را سیگنال های اولیه نامید. اگرچه اولین باری نیست که از این نام استفاده می کند، اما امروزه از این اصطلاح استفاده می کنیم.
مهمتر از آن، مفهوم مالکیت واکنشی را معرفی کرد. یک مالک تمام محدودههای واکنشگرای کودک را جمعآوری میکند و دفع آنها را در اختیار خود مالک یا در صورت اجرای مجدد مدیریت میکند. گراف واکنشی شروع به پیچیده شدن در یک مالک ریشه می کند و سپس هر گره به عنوان مالک برای فرزندان خود عمل می کند. این الگوی مالک نه تنها برای دفع مفید است، بلکه به عنوان مکانیزمی برای ایجاد زمینه ارائه دهنده/مصرف کننده در نمودار واکنشی مفید است.
برنامه ریزی
Vue (2014) نیز کمک بزرگی به جایگاه امروزی کرده است. Vue علاوه بر همگام بودن با MobX با پیشرفتهایی در بهینهسازی برای سازگاری، از همان ابتدا دارای واکنشپذیری ظریف بوده است.
در حالی که Vue استفاده از Virtual DOM را با React به اشتراک میگذارد، واکنشپذیری درجه یک به این معنی است که همراه با چارچوب ابتدا به عنوان یک مکانیسم داخلی برای تقویت API Options خود در چند سال گذشته توسعه داده شده است تا در چند سال گذشته در جلو و مرکز Composition API قرار گیرد. (2020).
Vue با برنامه ریزی زمان انجام کار، مکانیسم فشار/کشش را یک قدم به جلو برد. بهطور پیشفرض با Vue، همه تغییرات جمعآوری میشوند اما تا زمانی که صف افکتها در میکروتسک بعدی اجرا نشود، پردازش نمیشوند.
با این حال، این زمانبندی میتواند برای انجام کارهایی مانند keep-alive
(حفظ نمودارهای خارج از صفحه بدون هزینه محاسباتی) و Suspense
. حتی چیزهایی مانند رندر همزمان با این رویکرد امکان پذیر است، که واقعاً نشان می دهد که چگونه می توان بهترین ها را از هر دو جهان رویکردهای کششی و مبتنی بر فشار به دست آورد.
تلفیقی
در سال 2019، Svelte 3 به همه نشان داد که چقدر میتوانیم با یک کامپایلر انجام دهیم. در واقع، آنها واکنش پذیری را به طور کامل جمع آوری می کنند. این بدون معاوضه نیست، اما جالبتر اینکه Svelte به ما نشان داده است که چگونه یک کامپایلر میتواند کاستیهای ارگونومیکی را برطرف کند. و این روند در اینجا ادامه خواهد داشت.
زبان واکنش پذیری: حالت، حالت مشتق شده و اثر. نه تنها هر آنچه را که برای توصیف سیستم های همگام شده مانند رابط های کاربری نیاز داریم به ما می دهد، بلکه قابل تجزیه و تحلیل است. ما دقیقا می دانیم که چه چیزی و کجا تغییر می کند. پتانسیل ردیابی عمیق است:
من فکر می کنم این یکی از دلایل اصلی است که هر رویکرد مبتنی بر سیگنال بهتر از قلاب است. این بینش اشکال زدایی اضافی را فعال می کند که با قلاب ها امکان پذیر نیست، مانند اینکه دقیقاً *چرا* یک قسمت از وضعیت به روز شده را به شما نشان می دهد.
در حال برنامه ریزی برای اضافه کردن تجسم مشابه به DevTools خود نیز هستیم twitter.com/thetarnav/stat…
09:36 – 14 فوریه 2023
روز انتشار برای @solid_js devtools! 0.21.0 یک روش اساسی برای بازرسی واکنشپذیری اضافه میکند: نمودار وابستگی – منابع جاری (مستقیم و غیر مستقیم) و ناظران سیگنال یا محاسبات انتخابی را نشان میدهد https://t.co/oFNeKHMTzj https://t.co/ cyDpdZmG1s
اگر زمان کامپایل را بدانیم، می توانیم جاوا اسکریپت کمتری ارسال کنیم. ما می توانیم با بارگذاری کدمان آزادتر باشیم. این پایه و اساس قابلیت مجدد در Qwik و Marko است.
سیگنال هایی به آینده
سیگنال ها VDOM جدید هستند.
انفجار علاقه وجود دارد: بسیاری از مردم در حال آزمایش چیزهایی هستند. این به ما امکان می دهد فضا را کشف کنیم، استراتژی های مختلف را امتحان کنیم، چیزها را بفهمیم و بهینه کنیم.
مطمئن نیستیم که در پایان قرار است به چه چیزی بپردازیم، اما این اکتشاف جمعی عالی است!
20:41 بعد از ظهر – 24 سپتامبر 2022
با توجه به قدمت این فناوری، احتمالاً تعجب آور است که بگوییم چیزهای بیشتری برای کشف وجود دارد. اما این به این دلیل است که روشی برای مدلسازی راهحلها است تا یک روش خاص. چیزی که ارائه می دهد زبانی برای توصیف همگام سازی حالت مستقل از هر گونه عارضه جانبی است که می خواهید انجام دهد.
شاید تعجب آور به نظر نمی رسد که توسط Vue، Solid، Preact، Qwik و Angular پذیرفته شود. ما دیدهایم که با Leptos و Sycamore که WASM را در DOM نشان میدهند، به Rust راه پیدا کرده است. لازم نیست کند باشد. حتی توسط React در نظر گرفته شده است که در زیر کاپوت استفاده شود:
ممکن است یک سیگنال اولیه شبیه به React اضافه کنیم، اما فکر نمیکنم این روش خوبی برای نوشتن کد UI باشد. برای عملکرد عالی است. اما من مدل React را ترجیح میدهم که در آن هر بار وانمود میکنید که همه چیز دوباره ساخته شده است. برنامه ما استفاده از کامپایلر برای دستیابی به عملکرد قابل مقایسه است.
14:34 بعد از ظهر – 17 فوریه 2023
و شاید این مناسب باشد زیرا DOM مجازی برای React همیشه فقط یک جزئیات پیاده سازی بوده است.
به نظر می رسد سیگنال ها و زبان واکنش در جایی است که همه چیز در حال همگرایی است. اما این از اولین ورودش به جاوا اسکریپت چندان واضح نبود. و شاید به این دلیل است که جاوا اسکریپت بهترین زبان برای آن نیست. من تا آنجا پیش می روم که بگویم بسیاری از دردهایی که این روزها در طراحی فریم ورک فرانت اند احساس می کنیم، نگرانی های زبانی است.
هرجا که این همه به پایان می رسد، تا کنون کاملاً سواری بوده است. و با توجه بسیاری از مردم به Signals، من نمی توانم صبر کنم تا ببینم در نهایت به کجا می رسیم.