يعتقد مؤلف المادة ، التي ننشر ترجمتها اليوم ، أن
Hyperapp هو بديل جدير بالملاحظة لأطر الويب مثل
React أو
Vue . يقول أن سبب هذا الادعاء هو أنه اكتشف أن Hyperapp كان أسهل في التعلم من الإطارين. تم انتقاد فكرته ، حيث يبدو أنها تستند فقط إلى رأيه ، وهذا النهج ببساطة لا يعطي الأطر الأخرى الفرصة لإظهار نقاط قوتها. تهدف هذه المقالة إلى تحليل موضوعي لـ Hyperapp و React و Vue ، استنادًا إلى أمثلة بسيطة توضح قدراتهم وعلى أساس نتائج اختباراتهم.

المثال رقم 1: تطبيق العداد
من المحتمل أن يكون تطبيق التطبيق المضاد أحد الأمثلة الأكثر استخدامًا في البرمجة التفاعلية. إنه بسيط للغاية ومفهوم:
- نحتاج إلى
count
المتغير ، الذي سيخزن قيمة العداد. - ستكون هناك حاجة إلى طريقتين لزيادة وإنقاص
count
المتغيرات. - مطلوب آلية لعرض القيمة المخزنة في
count
وتقديمها للمستخدم. - هناك حاجة إلى زرين مرتبطين بالطرق المناسبة ، مما يسمح للمستخدم بالعمل على متغير
count
.
فيما يلي تنفيذ لهذا المثال باستخدام الأطر المعنية.
رد الفعل
import React from "react"; import ReactDOM from "react-dom"; Class Counter extends React.Component { constructor(props) { super(props); this.state = { count: 0}; } down(value) { this.setState(state => ({ count: state.count - value })); } up(value) { this.setState(state => ({ count: state.count + value })); } render() { return ( <div> <h1>{this.state.count}</h1> <button onClick = {() => this.down(1)}>-</button> <button onClick = {() => this.up(1)}>+</button> </div> ); } } ReactDOM.render(<Counter />, document.querySelector("#app"));
▍Vue
import Vue from "vue"; new Vue({ data: { count: 0 }, methods: { down: function(value) { this.count -= value; }, up: function(value) { this.count += value; } }, render: function(h) { return( <div> <h1>{this.count}</h1> <button onClick={() => this.down(1)}>-</button> <button onClick={() => this.up(1)}>+</button> </div> ); }, el: "#app" });
yHyperapp
import { h, app } from "hyperapp"; const state = { count: 0 }; const actions = { down: value => state => ({ count: state.count - value}), up: value => state => ({ count: state.count + value}) }; const view = (state, actions) => ( <div> <h1>{state.count}</h1> <button onclick={() => actions.down(1)}>-</button> <button onclick={() => actions.up(1)}>+</button> </div> ); app(state, actions, view, document.querySelector("#app"));
ysisتحليل
إذا لم تكن على دراية بهذه الأطر ، أو حتى مع واحد منها على الأقل ، فمن المحتمل أن تلتقي هنا بشيء غير مفهوم. لذلك دعونا تحليل هذا الرمز.
- عند استخدام جميع الأطر الثلاثة ، هناك أوامر
import
في بداية رمز التطبيق. - يستخدم رد الفعل نموذجًا كائني التوجه. يؤدي هذا إلى إنشاء فئة لمكون
Counter
. Vue يذهب بنفس الطريقة. هنا يتم إنشاء نسخة جديدة من فئة Vue
، يتم تمرير المعلومات إليها. وأخيرًا ، يستخدم Hyperapp نموذجًا وظيفيًا ، ويستخدم view
الكيانات المستقلة state
actions
. - إذا تحدثنا عن
count
المتغير ، في React ، تتم تهيئته في مُنشئ المكون ، وفي Vue و Hyperapp هي خاصية data
وكائنات state
، على التوالي. - إذا ذهبنا إلى استكشاف هذه التطبيقات ، يمكننا أن نرى أن React و Vue يستخدمان طرقًا مشابهة جدًا للتفاعل مع متغير
count
. في React ، لتغيير حالة التطبيق ، يتم setState
الأسلوب setState
الموروث من React.Component
. في Vue ، this.count
تغيير قيمة this.count
مباشرة. تتم كتابة طرق Hyperapp باستخدام بنية دالة السهم ES6. من بين الأطر المعنية ، هو الوحيد الذي يستخدم هذا ، حيث يضطر React و Vue لاستخدام this
الكلمة الرئيسية داخل أساليبهم. من ناحية أخرى ، تتطلب طرق Hyperapp أن يتم تمرير كائن ، كوسيطة ، مع حالة التطبيق. وهذا يعني أنه من المرجح أن يعاد استخدامها في سياقات مختلفة. - الجزء من التطبيق المسؤول عن إخراج البيانات إلى الصفحة يبدو متشابهًا تقريبًا في جميع الأمثلة الثلاثة. تكمن خصوصية Vue في أنه عند استخدام هذا الإطار ، يجب تمرير الوظيفة
h
إلى النظام الفرعي للتقديم. يستخدم Hyperapp onclick
بدلاً من onclick
، وهنا يتم الوصول إلى متغير count
بشكل مختلف عن كل من React و Vue ، نظرًا لخصائص كيفية تخزين حالة التطبيق في كل إطار عمل. - وأخيرًا ، تستخدم جميع الأطر الثلاثة
#app
بعنصر #app
. في كل منها ، يتم تنفيذ هذه العملية بشكل مختلف. وتجدر الإشارة إلى أنه في Vue تبدو هذه العملية هي الأبسط والأكثر قابلية للفهم وتعطي المطور تصميمًا أكثر مرونة ، يعمل مع محدد العناصر ، وليس مع العنصر نفسه.
▍ الاستنتاجات
إذا قارنت مباشرةً الكود الذي يحل نفس المشكلة ، مكتوبًا باستخدام جميع الأطر الثلاثة ، يتبين أن Hyperapp ، لتطبيق تطبيق العداد ، يتطلب أقل عدد من أسطر الكود ، وهذا هو الإطار الوحيد الذي يستخدم نهجًا وظيفيًا. ومع ذلك ، فإن مقدار الرمز المكتوب باستخدام Vue ، إذا قمت بحساب عدد الأحرف ، فإنه يتبين أقل قليلاً ، واستخدام محدد العناصر فيه يبدو جيدًا جدًا. يبدو أن رمز تطبيق React هو الأطول ، ولكن هذا لا يعني أنه من الصعب فهمه أكثر من الرمز المكتوب للعمل مع أطر عمل تم تحليلها.
المثال رقم 2: العمل مع التعليمات البرمجية غير المتزامنة
من الممكن ، في الممارسة العملية ، أن تتعامل مع التعليمات البرمجية غير المتزامنة. أحد أكثر العمليات غير المتزامنة شيوعًا هو إرسال طلب إلى بعض API. لأغراض هذا المثال ،
يتم استخدام واجهة برمجة تطبيقات JSONPlaceholder ، والتي تحتوي على بيانات شرطية وتسرد المنشورات. إليك ما سنفعله هنا:
- نحفظ الصفيف للنشر فيه في حالة التطبيق.
- ندعو ، باستخدام الطريقة المناسبة ،
fetch()
، للإشارة إلى عنوان URL الذي نحتاجه ، وننتظر وصول البيانات ، ونحلل رمز JSON المستلم ، وهو عبارة عن مجموعة من الكائنات ، وأخيرًا نقوم بتحديث متغير المنشورات عن طريق كتابة البيانات المستلمة إليه. - نعرض زرًا على الصفحة يستدعي الطريقة التي تقوم بتحميل قائمة المنشورات.
- أدرج المنشورات من المنشورات باستخدام المفاتيح.
ضع في اعتبارك رمزًا يطبق مخطط الإجراء أعلاه.
رد الفعل
import React from "react"; import ReactDOM from "react-dom"; class PostViewer extends React.Component { constructor(props) { super(props); this.state = { posts: [] }; } getData() { fetch(`https://jsonplaceholder.typicode.com/posts`) .then(response => response.json()) .then(json => { this.setState(state => ({ posts: json})); }); } render() { return ( <div> <button onClick={() => this.getData()}>Get posts</button> {this.state.posts.map(post => ( <div key={post.id}> <h2><font color="#3AC1EF">{post.title}</font></h2> <p>{post.body}</p> </div> ))} </div> ); } } ReactDOM.render(<PostViewer />, document.querySelector("#app"));
▍Vue
import Vue from "vue"; new Vue({ data: { posts: [] }, methods: { getData: function(value) { fetch(`https://jsonplaceholder.typicode.com/posts`) .then(response => response.json()) .then(json => { this.posts = json; }); } }, render: function(h) { return ( <div> <button onClick={() => this.getData()}>Get posts</button> {this.posts.map(post => ( <div key={post.id}> <h2><font color="#3AC1EF">{post.title}</font></h2> <p>{post.body}</p> </div> ))} </div> ); }, el: "#app" });
yHyperapp
import { h, app } from "hyperapp"; const state = { posts: [] }; const actions = { getData: () => (state, actions) => { fetch(`https://jsonplaceholder.typicode.com/posts`) .then(response => response.json()) .then(json => { actions.getDataComplete(json); }); }, getDataComplete: data => state => ({ posts: data }) }; const view = (state, actions) => ( <div> <button onclick={() => actions.getData()}>Get posts</button> {state.posts.map(post => ( <div key={post.id}> <h2><font color="#3AC1EF">{post.title}</font></h2> <p>{post.body}</p> </div> ))} </div> ); app(state, actions, view, document.querySelector("#app"));
ysisتحليل
دعونا نحلل هذا الرمز ونقارن الأطر الثلاثة التي تم التحقيق فيها.
- كما هو الحال في المثال السابق ، فإن تخزين حالة التطبيق وإخراج البيانات والاتصال بعنصر الصفحة متشابهة جدًا في جميع الأطر الثلاثة. هنا لوحظت نفس الاختلافات ، التي ذكرناها أعلاه بالفعل.
- يعد تنزيل البيانات باستخدام وظيفة
fetch()
عملية بسيطة إلى حد ما ؛ فهو يعمل كما هو متوقع في جميع الأطر. لكن الاختلاف الرئيسي هنا هو أن Hyperapp يدعم إجراء عمليات غير متزامنة بشكل مختلف قليلاً عن الأطر الأخرى. بدلاً من تعديل الحالة مباشرة ، داخل إجراء غير متزامن ، يستدعي هذا الإجراء إجراءً متزامنًا آخر ، والذي يتلقى البيانات ويحولها إلى تنسيق مناسب. وهذا يجعل جوهر التطبيق أكثر وظيفية وأكثر ملاءمة لاقتحام أجزاء صغيرة من المحتمل أن تكون مناسبة لإعادة الاستخدام. هذا النهج ، بالإضافة إلى ذلك ، يساعد على تجنب بعض المشاكل الكامنة في الاسترجاعات المتداخلة التي قد تنشأ في مثل هذه الحالات. - إذا تحدثنا عن حجم الكود ، فإن تطبيق Hyperapp يحتاج مرة أخرى إلى عدد أقل من أسطر الكود لتحقيق نفس الهدف ، لكن كود Vue يبدو أقصر ، وإذا قمت بحساب عدد الأحرف في الكود ، فهو أقصر من الخيارات الأخرى.
▍ الاستنتاجات
اتضح أن إجراء العمليات غير المتزامنة أمر بسيط بنفس القدر في جميع الأطر. قد يقود Hyperapp المطور إلى كتابة كود أكثر وظيفية ووحدة نمطية عند العمل مع الإجراءات غير المتزامنة ، ولكن الإطارين الآخرين يؤديان أيضًا مهمتهما الممتازة ، وفي هذا الصدد ، يمنحان المطور فرصة للاختيار.
مثال 3: مكون عنصر القائمة لتطبيق المهام الواجبة
من المحتمل أن تكون تطبيقات المهام الواجبة هي المثال الأكثر شهرة في البرمجة التفاعلية. على ما يبدو ، تم تنفيذ شيء مماثل باستخدام كل إطار موجود تقريبًا. هنا لن نقوم بتنفيذ التطبيق بالكامل. بدلاً من ذلك ، دعنا نركز على مكون بسيط عديم الجنسية لاستكشاف إمكانيات الأطر قيد الدراسة لإنشاء كتل بناء صغيرة لتطبيقات الويب المناسبة لإعادة الاستخدام.
النظر في تنفيذ المكون باستخدام الأطر المدروسة. في هذا المثال ، سنقوم بتوسيع خيارات التعليمات البرمجية قيد النظر من خلال النظر في مكون رد الفعل المكتوب بأسلوب وظيفي.
ea رد (نمط وظيفي)
function TodoItem(props) { return ( <li class={props.done ? "done" : ""} onclick={() => props.toggle(props.id)}> {props.value} </li> ); }
رد الفعل
class TodoItem extends React.Component { render () { return ( <li class={this.props.done ? "done" : ""} onclick={() => this.props.toggle(this.props.id)}> {this.props.value} </li> ); } }
▍Vue
var TodoItem = Vue.component("todoitem", { props: ["id", "value", "done", "toggle"], template: '<li v-bind:class="{done : done}" v-on:click="toggle(id)">{{value}}</li>' });
yHyperapp
يرجى ملاحظة أن Hyperapp يستخدم أيضًا أسلوبًا وظيفيًا.
const TodoItem = ({ id, value, done, toggle }) = ( <li class={done ? "done" : ""} onclick={() => toggle(id)}> {value} </li> )
ysisتحليل
- رد الفعل ، فيما يتعلق باستخدام أنماط التشفير ، هو الإطار الأكثر مرونة. وهو يدعم المكونات الوظيفية ، بالإضافة إلى المكونات المصممة كفئة. بالإضافة إلى ذلك ، React ، في شكله القياسي ، يدعم أيضًا مكونات Hyperapp.
- يدعم Hyperapp أيضًا مكونات التفاعل الوظيفية. هذا يعني أنه عند العمل مع Hyperapp و React ، هناك مساحة كبيرة للتجريب.
- Vue تحتل المرتبة الأخيرة في هذا الاختبار. لديها بنية غريبة نوعًا ما يصعب فهمها على الفور حتى لأولئك المطلعين على React أو Hyperapp.
- إذا تحدثنا عن طول الكود ، فإن جميع الأمثلة لها أحجام متشابهة جدًا. الشيء الوحيد الذي يمكن ملاحظته هنا هو أن الكود الموجود على React ، في أحد الخيارات ، تبين أنه أكبر قليلاً من الآخر.
▍ الاستنتاجات
يستغرق الأمر بعض الوقت لتعتاد على Vue ، لأن قوالبها تختلف قليلاً عن قوالب الإطارين الآخرين. رد الفعل مرن للغاية ، فهو يدعم الأساليب المختلفة المستخدمة لإنشاء المكونات. في الوقت نفسه ، كل شيء بسيط للغاية في Hyperapp ، وهو متوافق أيضًا مع React ، والذي يسمح لك بتغيير الإطار ، إذا لزم الأمر ، في مرحلة ما من المشروع.
مقارنة بين طرق دورة حياة المكون
هناك اعتبار مهم آخر يؤثر على اختيار إطار العمل هو أحداث دورة حياة المكونات التي يدعمها ، والتي يمكنك الاشتراك فيها والتي يمكنك معالجتها وفقًا لاحتياجات المطور. فيما يلي جدول يعتمد على تحليل API للأنظمة قيد الدراسة.
حدث
| رد فعل
| فيو
| Hyperapp
|
التهيئة
| مُنشئ
| beforeCreate ، تم إنشاؤه
| - |
تصاعد
| comoinentDidMount
| beforemount شنت
| إنشاء
|
تحديث
| elementDidUpdate
| قبل التحديث ، تحديث
| عند التحديث
|
إلغاء التركيب
| elementWillUnmount
| - | إزالة
|
دمار
| - | قبل تدمير ، تدمير
| ondestroy
|
ysisتحليل
إليك ما يمكنك فهمه من خلال تحليل هذا الجدول:
- معظم الخطافات لدورة الحياة موجودة في Vue. بمساعدتهم ، لدى المبرمج الفرصة لمعالجة كل ما يحدث مع المكون ، إما قبل استدعاء الحدث المقابل ، أو بعده. قد يكون هذا مفيدًا لإدارة المكونات المعقدة.
- خطافات دورة الحياة لـ React و Hyperapp متشابهة جدًا ، على الرغم من أن React يجمع بين معالجة الأحداث التي تحدث أثناء فك وتركيب مكون ، بينما يعمل Hyperapp أيضًا مع أحداث إنشاء مكون وتركيبه. كلاهما يعطي المطور عدد كاف من الاحتمالات لمعالجة أحداث دورة الحياة.
- لا تتعامل Vue مع حدث إلغاء التحميل (بقدر ما يمكنك فهمه من خلال تحليل واجهة برمجة التطبيقات للإطار) ، بدلاً من ذلك تعتمد على الخطافات المرتبطة بتدمير المكون. لا يتفاعل React مع حدث قتل مكون ، مما يسمح بمعالجة حدث unmount فقط. لا يقدم Hyperapp خطافات للتعامل مع أحداث إنشاء المكونات ، بدلاً من الاعتماد كليًا على أحداث التثبيت. اعتمادًا على احتياجاتك وخبرتك ، يجب مراعاة هذه الاختلافات عند تصميم التطبيق ، مع مراعاة إمكانية معالجة أحداث دورة حياة المكون.
▍ الاستنتاجات
بشكل عام ، يمكن ملاحظة أن طرق التعامل مع الأحداث التي تحدث خلال دورة حياة المكونات تدعم جميع الأطر. ستحل هذه الأساليب العديد من المشاكل. تقدم جميع الأطر الثلاثة خطافات لجميع أنواع الأحداث ، ولكن هناك اختلافات طفيفة بينها ، يمكن أن يكون مصدرها السمات الداخلية للأطر والاختلافات في تنفيذها. ربما يكون Vue في هذا المجال متقدمًا بخطوة على الأنظمة الأخرى ، حيث يقدم نظامًا أكثر تفصيلاً لمعالجة الأحداث ، مما يسمح لك بمعالجة أحداث دورة الحياة إما قبل حدوثها أو بعدها.
مقارنة أداء الإطار
بالإضافة إلى الراحة في استخدام الإطار وتقنيات البرمجة المستخدمة للعمل معه ، يهتم العديد من المطورين بشدة بأداء الإطارات ، خاصة للتطبيقات المعقدة إلى حد ما. مصدر قيم للمعلومات حول أداء مختلف الأطر هو مشروع
js-framework -معيار .
لذلك ، ألق نظرة على نتائج اختبار React و Vue و Hyperapp.
with العمل مع الجداول
فيما يلي نتائج اختبار أطر العمل للعمل مع الجداول. يتوافق المؤشر في خلايا الجدول مع مدة العملية - الانحراف المعياري. تظهر نتيجة تقسيم المؤشر الذي تم الحصول عليه على أفضل مؤشر بين قوسين.
التحليل
- العمليات التي لا تستخدم فيها المفاتيح (بدون مفاتيح) لإخراج البيانات تكون أسرع بكثير من العمليات التي يتم فيها استخدام المفاتيح (ذات المفاتيح).
- كان أسرع الخيارات الستة التي تم النظر فيها هو الخيار الذي يستخدم React بدون استخدام المفاتيح ، مما يظهر أداءً مثيرًا للإعجاب في جميع الاختبارات.
- إذا قارنت Vue و React عند العمل باستخدام المفاتيح ، فإن Vue له ميزة طفيفة. في نفس الوقت ، إذا قارنت React و Vue في المتغيرات التي لا تستخدم فيها المفاتيح ، فإن Vue يظهر أداءً أقل بكثير من React.
- Vue و Hyperapp ، كما ترون من النتائج ، يواجهون بعض الصعوبات في الاختبار ، حيث يتم إجراء التحديث الجزئي للجدول ، ويظهر React بشكل جيد عليه ، ربما بسبب بعض التحسينات التي تهدف إلى تسريع مثل هذا العمليات.
▍ التحميل ، الإطلاق ، أحجام الكود
فيما يلي جدول بنتائج دراسة للمؤشرات المتعلقة بسرعة إطلاق الإطار ، إلى حجمه ، واستخدامه للخيط الرئيسي.
التحليل
- تبين أن رمز Hyperapp هو الأصغر بين الأطر المدروسة. رمز التفاعل و Vue متشابهان تقريبًا.
- يحتاج Hyperapp إلى أقل وقت لبدء التشغيل. والسبب في ذلك ، بالطبع ، هو الحجم الصغير لرمز الإطار والنهج البسيط لتصميم API الخاص به.
- Vue ، عندما يتعلق الأمر بالوقت الذي يستغرقه إطلاق الإطار ، يكون أسرع قليلاً من React.
with العمل مع الذاكرة
الآن خذ بعين الاعتبار نتائج اختبار تخصيص الذاكرة.
التحليل
- Hyperapp هو إطار العمل الأكثر تسامحًا من حيث استهلاك الذاكرة.
- بشكل عام ، يمكن ملاحظة أن جميع الأطر لا تستهلك الكثير من الذاكرة. هذا يشير إلى أنهم ، على أجهزة الكمبيوتر الحديثة ، سيعملون بنفس الطريقة تقريبًا.
▍ الاستنتاجات
إذا كنت بحاجة إلى تحقيق أقصى أداء عند تطوير مشروع ما ، يجب أن تفهم ، أولاً ، نوع التطبيق الذي تقوم بتطويره ، وثانيًا ، تحديد احتياجات هذا التطبيق بوضوح. إذا قمت بدمج تحليل الأداء لجميع الأطر الثلاثة ، ستشعر بأن Vue و React مناسبان أكثر للتطبيقات الأكثر تعقيدًا ، و Hyperapp أفضل في التطبيقات ذات النطاق الأصغر التي تحتاج إلى معالجة بيانات أقل ، والتي تتطلب تشغيلها في أسرع وقت ممكن ، والذين قد يحتاجون للعمل على أسرع الحواسيب.
ومع ذلك ، تجدر الإشارة إلى أن اختبارات الأداء المستخدمة هنا بعيدة كل البعد عن الواقع ، من نوع من السيناريو المتوسط. لذلك ، بعد اختبارها ومقارنتها في مشروع حقيقي ، يمكنك رؤية نتائج أخرى.
ملاحظات إضافية
وتجدر الإشارة إلى أن مقارنة أطر الويب قد تشبه شيء مثل مقارنة التفاح بالبرتقال. فيما يلي بعض الاعتبارات الأخرى المتعلقة بـ React و Vue و Hyperapp التي قد تكون مفيدة في اختيار إطار عمل محدد للمشروع:
- يتجاوز رد الفعل مشكلة وجوب التفاف عناصر JSX المجاورة في العنصر الأصلي ، مع تقديم مفهوم الأجزاء - وهي العناصر التي تسمح لك بتجميع مجموعة من العناصر المتساقطة دون إضافة عقد إضافية إلى DOM.
- يوفر React للمطور مكونات عالية الترتيب ، بينما يستخدم Vue عناصر mixins لإعادة استخدام وظائف المكونات.
- يستخدم Vue بشكل أكثر اكتمالاً مفهوم فصل المسؤوليات ، ويفصل بين هيكل ووظيفة التطبيق باستخدام القوالب .
- Hyperapp ، بالمقارنة مع React و Vue ، يبدو وكأنه نظام يوفر واجهة برمجة تطبيقات ذات مستوى أقل. تبين أن رمز تطبيقات Hyperapp أقصر ، فهو يوفر مرونة كبيرة ، والتي يمكن أن تكون مفيدة في الحالات التي قد يرغب المطور في معالجتها عن طريق الضبط الدقيق والبحث عن آلياته الداخلية.
الملخص
يعتقد مؤلف هذه المادة أنه إذا قرأت حتى هذه النقطة ، فأنت لديك بالفعل فهم لأي من الأطر التي تمت دراستها هنا تناسب احتياجاتك. في النهاية ، لم نكن نتحدث عن أي من الأطر هو الأفضل ، بل عن أي منها هو الأكثر قدرة على إظهار نفسه في مواقف مختلفة. ونتيجة لذلك ، يمكننا استخلاص الاستنتاجات العامة التالية:
- React — , , , - , . , , , , . , React — , .
- Vue , - JavaScript-, — . React, , , , React - . Vue , , , , React.
- , , Hyperapp — , , — . , React Vue, . , . , Hyperapp, , , , Hyperapp-, . , , Hyperapp, , , , React Vue, .
! -?
, - 10% :)