مقدمة
أعتقد أن كل شخص واجه العديد من المشكلات المتعلقة بتحميل نص JavaScript. أساسا في عدة نقاط -
1> مشاكل تحميل الملفات واعتماد الملفات وتنفيذها الناتجة عن البرامج النصية المتزامنة والبرامج النصية غير المتزامنة
2> مشاكل تحسين الأداء الناتجة عن البرامج النصية المتزامنة والبرامج النصية غير المتزامنة
إن الفهم العميق لجميع جوانب تحميل النصوص لا يفضي إلى حل المشكلات العملية فحسب ، بل يفضي أيضًا إلى استيعاب تحسين الأداء وتنفيذه.
انظر أولاً إلى أي رمز علامة نصية -
نسخة الكود كما يلي:
<script src = "js/myapp.js"> </script>
إذا تم وضعها على <head> ، فسيحظر جميع الأعمال التي تقدم صفحات ، مما يتسبب في بقاء المستخدم في حالة "شاشة بيضاء للموت" حتى يتم تحميل البرنامج النصي وتنفيذه. لن يسمح البرنامج النصي في نهاية <Body> فقط للمستخدم بمشاهدة الصفحة الثابتة دون حيوية. حيث من المفترض أن يكون عرض العميل مبعثرًا بعناصر تحكم غير فعالة وصناديق فارغة. خذ حالة اختبار -
نسخة الكود كما يلي:
<! doctype html>
<html>
<head lang = "en">
<meta charset = "utf-8">
<title> برنامج التحميل Async </title>
<script src = "js/test.js"> </script>
</head>
<body>
<div> أنا راضٍ </div>
<img src = "img/test.jpg">
</body>
</html>
من بينها ، المحتوى في test.js -
نسخة الكود كما يلي:
تنبيه ('أنا رمز البرنامج النصي في الرأس. بعد تنفيذ JS هنا ، يبدأ عرض محتوى الجسم! ") ؛
سنرى أن التنبيه هو نقطة توقف مؤقت ، وفي هذا الوقت ، تكون الصفحة فارغة. ومع ذلك ، كن على علم بأن الصفحة بأكملها قد تم تحميلها في هذا الوقت. إذا كان الجسم يحتوي على علامات لبعض سمات SRC (مثل علامة IMG أعلاه) ، فقد بدأ المتصفح في تحميل المحتوى ذي الصلة في هذا الوقت. باختصار ، تجدر الإشارة إلى أن توقيت العمل لمحرك JS ومحرك التقديم حصريان بشكل متبادل (بعض الكتب تسميها خيط واجهة المستخدم).
لذلك ، نحتاج إلى أن يتم تحميل البرامج النصية المسؤولة عن جعل الصفحة أفضل واستخدامها بشكل أفضل على الفور ، وسيتم تحميل البرامج النصية التي يمكن تحميلها لاحقًا لاحقًا.
1. تأخير تنفيذ النص
أصبح الآن أكثر وأكثر شعبية لوضع البرامج النصية في نهاية الصفحة <Body>. وبهذه الطريقة ، من ناحية ، يمكن للمستخدم رؤية الصفحة بشكل أسرع ، ومن ناحية أخرى ، يمكن للنص تشغيل عناصر DOM التي تم تحميلها مباشرة. هذا "الحركة" هو تحسن كبير لمعظم النصوص. نموذج الصفحة كما يلي -
نسخة الكود كما يلي:
<! doctype html>
<html>
<head lang = "en">
<!-بيانات التعريف وشرائح النصوص تذهب هنا->
<script src = "headscript.js"> </script>
</head>
<body>
<!-المحتوى يذهب هنا->
<script src = "bodyscript.js"> </script>
</body>
</html>
هذا يؤدي إلى تسريع وقت عرض الصفحة بشكل كبير ، ولكن كن على علم بأن هذا قد يمنح المستخدمين الفرصة للتفاعل مع الصفحة قبل تحميل bodyscript. إن السبب وراء عدم قدرة المتصفح على تحميل البرامج النصية قبل تحميل المستند الكامل هو عنق الزجاجة الكبير للمستندات الكبيرة المنقولة عبر الاتصالات البطيئة.
من الناحية المثالية ، يجب أن يتم تحميل البرنامج النصي في وقت واحد مع تحميل المستند ولا يؤثر على عرض DOM. وبهذه الطريقة ، بمجرد أن يكون المستند جاهزًا ، يمكن تشغيل البرنامج النصي لأنه تم تحميل البرنامج النصي المقابل بترتيب علامة <script>.
يمكننا إنجاز هذا المطلب باستخدام التأجيل ، أي ،
نسخة الكود كما يلي:
<script src = "deferredscript.js"> </script>
تعد إضافة السمة المؤجلة مكافئة لإخبار المتصفح: يرجى البدء في تحميل هذا البرنامج النصي على الفور ، ولكن يرجى الانتظار حتى يصبح المستند جاهزًا ، وقد انتهت جميع البرامج النصية مع السمة المؤجلة قبل تشغيله.
وبهذه الطريقة ، فإن وضع البرامج النصية للتأخير في علامة الرأس سيؤدي إلى جميع فوائد وضع البرامج النصية على علامة الجسم ، ويمكن أن تحسن بشكل كبير من سرعة التحميل للمستندات الكبيرة. وضع الصفحة في هذا الوقت هو -
نسخة الكود كما يلي:
<! doctype html>
<html>
<head lang = "en">
<!-بيانات التعريف وشرائح النصوص تذهب هنا->
<script src = "headscript.js"> </script>
<script src = "deferredscript.js" defer> </script>
</head>
<body>
<!-المحتوى يذهب هنا->
</body>
</html>
ومع ذلك ، لا تدعم جميع المتصفحات تأجيلًا (بالنسبة لبعض المتصفحات الحديثة ، إذا تم الإعلان عن تأجيلها ، فلن تقوم البرامج النصية الداخلية بإجراء عمليات تقديم و DOM. كل من سمات التأجيل IE4+). هذا يعني أنه إذا كنت ترغب في التأكد من أنه يمكن تشغيل البرنامج النصي للتأخير بعد تحميل المستند ، فيجب عليك تغليف رمز جميع البرامج النصية للتأخير في بنية مثل $ $ (وثيقة). هذا يستحق ذلك ، لأن ما يقرب من 97 ٪ من الزوار يمكنهم الاستمتاع بفوائد التحميل الموازي ، في حين أن 3 ٪ أخرى من الزوار لا يزال بإمكانهم استخدام JavaScript كامل الميزة.
2. التوازي الكامل للنصوص
دع البرامج النصية يتم تحميلها وتنفيذها خطوة واحدة أسرع. لا أريد الانتظار حتى تقوم البرامج النصية المؤجلة بتشغيل واحدة تلو الأخرى (يذكرنا تأجيل سيناريو طابور مرتبة حيث تنتظر المستند بهدوء تحميل المستند) ، ولا أريد الانتظار حتى يصبح المستند جاهزًا قبل تشغيل هذه البرامج النصية. أريد تحميل هذه البرامج النصية وتشغيلها في أقرب وقت ممكن. هنا نفكر في سمة Async لـ HTML5 ، ولكن كن على علم بأنها فوضى فوضوية.
على سبيل المثال ، نقوم بتحميل اثنين من البرامج النصية لجهة خارجية غير ذات صلة تمامًا ، وتستمر الصفحة بشكل جيد بدونهما ، ولا تهتم من يركض أولاً ومن يركض لاحقًا. لذلك ، فإن استخدام سمة ASYNC في هذه البرامج النصية الطرف الثالث يعادل تحسين سرعة الجري دون إنفاق فلس واحد.
تتم إضافة سمة ASYNC حديثًا إلى HTML5. تشبه الوظيفة المؤجلة ، أي أنها تتيح عرض DOM أثناء تنزيل البرامج النصية. ومع ذلك ، سيتم تنفيذها في أقرب وقت ممكن بعد التنزيل (على سبيل المثال ، محرك JS هو خمول وتنفيذ على الفور) ، وليس هناك ما يضمن تنفيذ البرنامج النصي بالترتيب. سيتم الانتهاء منها قبل حدث Onload.
يدعم Firefox 3.6 ، Opera 10.5 ، IE 9 ، وأحدث Chrome و Safari سمة Async. يمكن استخدام Async و Defer في نفس الوقت ، بحيث تدعم جميع IES بعد IE 4 التحميل غير المتزامن ، ولكن كن حذرًا من أن Async سوف يتأرجح.
ثم يكون نموذج الصفحة في هذا الوقت كما يلي -
نسخة الكود كما يلي:
<! doctype html>
<html>
<head lang = "en">
<!-بيانات التعريف وشرائح النصوص تذهب هنا->
<script src = "headscript.js"> </script>
<script src = "deferredscript.js" defer> </script>
</head>
<body>
<!-المحتوى يذهب هنا->
<script src = "asyncscript1.js" async defer> </script>
<script src = "asyncscript2
</body>
</html>
انتبه إلى أمر التنفيذ هنا - يتم تحميل كل ملف نصي ، ثم يتم تنفيذ HeadScript.js ، ثم يتم تحميل defferedscript.js في الخلفية أثناء تقديم DOM. بعد ذلك ، سيتم تشغيل defferedscript.js والبرامج النصية غير المتزامنة في نهاية عرض DOM. لاحظ أنه بالنسبة للمتصفحات التي تدعم سمة Async ، سيتم نفاد ترتيب هاتين البرامج النصية.
3. تحميل البرنامج النصي القابل للبرمجة
على الرغم من أن وظائف خصائص البرنامج النصي أعلاه جذابة للغاية ، إلا أنها لا تستخدم على نطاق واسع بسبب مشكلات التوافق. لذلك ، نستخدم البرامج النصية لتحميل البرامج النصية الأخرى أكثر. على سبيل المثال ، نريد فقط تحميل برنامج نصي للمستخدمين الذين يستوفون شروطًا معينة ، وهو "التحميل كسول" المذكور غالبًا.
على مستوى API للمتصفح ، هناك طريقتان معقولتان للزحف وتشغيل نصوص الخادم -
1> قم بإنشاء طلب AJAX واستخدم وظيفة EVAL لمعالجة الاستجابة
2> أدخل علامة <script> في DOM
الطريقة الأخيرة أفضل لأن المتصفح سوف يقلق من إنشاء طلبات HTTP لنا. علاوة على ذلك ، لدى Eval أيضًا بعض المشكلات العملية: نطاق التسرب ، تصحيح الأخطاء فوضوي ، وقد يقلل أيضًا من الأداء. لذلك ، إذا كنت ترغب في تحميل برنامج نصي يسمى الميزات. js ، يجب علينا استخدام رمز مثل ما يلي:
نسخة الكود كما يلي:
var head = document.getElementSbyTagName ('head') [0] ؛
var script = document.createElement ('script') ؛
script.src = 'feature.js' ؛
head.appendchild (script) ؛
بالطبع ، نحتاج إلى التعامل مع الاستماع إلى رد الاتصال ، وتحدد مواصفات HTML5 خاصية OnLoad التي يمكن أن تربط عمليات الاسترجاعات.
نسخة الكود كما يلي:
script.onload = function () {
console.log ('script loaded ...') ؛
}
ومع ذلك ، لا تدعم IE8 والإصدارات القديمة Onload ، فهي تدعم onReadyStateChange. علاوة على ذلك ، لا يزال هناك العديد من الأشياء الغريبة للتعامل مع الأخطاء. هنا ، يمكنك الرجوع إلى بعض مكتبات التحميل الشهيرة المستندة إلى المدارس ، مثل LABJS ، Yepnope ، requirejs ، إلخ.
على النحو التالي ، أقوم بتغليف ملف loadjs بسيط بنفسي -
نسخة الكود كما يلي:
var loadjs = function (url ، callback) {
var head = document.getElementSbyTagName ('head') [0] ؛
var script = document.createElement ('script') ؛
script.src = url ؛
script.type = "text/javaScript" ؛
head.appendchild (script) ؛
// علامة البرنامج النصي ، هناك حدث onReadyStatechange تحت IE ، وهناك حدث Onload ضمن معيار W3C
// IE9+ يدعم أيضًا تشغيل معيار W3C
var ua = navigator.useragent ،
ua_version ؛
// ie6/7/8
if (/msie ([^؛]+)/. test (ua)) {
ua_version = parsefloat (regexp ["$ 1"] ، 10) ؛
if (ua_version <= 8) {
script.OnReadyStateChange = function () {
if (this.readyState == "Loaded") {
أتصل مرة أخرى()؛
}
}
} آخر {
script.onload = function () {
أتصل مرة أخرى()؛
} ؛
}
} آخر {
script.onload = function () {
أتصل مرة أخرى()؛
} ؛
}
} ؛
لن أتحدث عن التحميل غير المتزامن للنصوص في المستند. الآن قلة من الناس يفعلون ذلك لأن اختلافات المتصفح ساحقة حقًا.
لاحظ أنه باستخدام كائن الصورة إلى ملفات JS قبل التحميل بشكل غير متزامن ، لن يتم تنفيذ رمز JS في الداخل.
أخيرًا ، دعنا نتحدث عن البرنامج النصي غير المتزامن في Termjs.
لا تضمن Termjs تشغيل البرامج النصية المستهدفة بشكل متتابع ، ولكن فقط يضمن أن ترتيب التشغيل الخاص بهم يمكن أن يفي بمتطلبات التبعية الخاصة بكل منها. لذلك ، فإننا نضمن تحميل جميع البرامج النصية بالتوازي في أقرب وقت ممكن وتنفيذها بطريقة منظمة وفقًا لطوبولوجيا التبعية.
4. ملخص
حسنًا ، عندما يتعلق الأمر بذلك ، انتهى بيان البرنامج النصي غير المتزامن. اسمحوا لي أن أتحدث عن أمر التحسين هنا مرة أخرى -
1> بالطريقة التقليدية ، نستخدم علامات البرنامج النصي لتضمينها مباشرة في مستندات HTML. فيما يلي حالتان -
A> تم التضمين في علامة الرأس - كن حذرًا من أن القيام بذلك لن يؤثر على التحميل الموازي لملفات الموارد الثابتة الأخرى في محتوى المستند. إنه يؤثر على تقديم محتوى المستند ، أي أن عرض DOM في هذا الوقت سيتم حظره وسيتم تقديم الشاشة البيضاء.
B> تم تضمينها في أسفل علامة الجسم - من أجل تجنب ظاهرة الشاشة البيضاء ، نعطي الأولوية لتقديم DOM ثم تنفيذ البرنامج النصي ، لكن المشكلة تأتي مرة أخرى. دعنا نتحدث عن السؤال الأول أولاً - إذا كان محتوى مستند DOM كبيرًا نسبيًا ، فسيتم تأخير ربط حدث التفاعل ، وستكون التجربة أسوأ قليلاً. بالطبع ، نحن بحاجة إلى جعل البرامج النصية المهمة تنفذ أولاً بناءً على الاحتياجات. دعنا نتحدث عن المشكلة الثانية - لأن ملفات النصوص هي بقدر الجزء السفلي من الجسم ، يتم تأخير تحميل هذه البرامج النصية مقارنة بالبرامج النصية في الرأس. لذلك ، أما بالنسبة لأسفل الجسم ، فهي ليست نقطة نهاية التحسين.
C> أضف السمة المؤجلة - نأمل أن يتم تحميل البرنامج النصي بالتوازي في أقرب وقت ممكن ، وسنظل نضع هذه الدفعة من البرامج النصية في الرأس. يجب أن يتم تحميل البرنامج النصي في وقت واحد مع تحميل المستند ولا يؤثر على عرض DOM. وبهذه الطريقة ، يمكن تشغيل البرنامج النصي بمجرد أن يكون المستند جاهزًا. لذلك هناك سمة تأجيل. لكن انتبه إلى توافقه. بالنسبة للمتصفحات التي لا تدعم السمة المؤجلة ، نحتاج إلى تغليف الرمز في $ (وثيقة). جاهزة مثل jQuery. تجدر الإشارة إلى أن جميع البرامج النصية ذات السمات المؤجلة يتم تنفيذها بالتسلسل وفقًا لترتيب المظهر ، لذلك يتم مزامنتها أيضًا.
2> النقطة السابقة تدور حول البرامج النصية للتنفيذ المتزامنة (لاحظ أن عملية التحميل لهذه البرامج النصية متوازية ، ولكن الفرق بين من يطلق الطلب أولاً ومن الذي يثير الطلب). نقطة التحسين التالية هي "البرامج النصية للتنفيذ الموازية". بالطبع ، نحن نعلم أنه في مرحلة ما ، يتم تنفيذ ملف JS واحد فقط. "الموازي" هنا يعني أن كل من يتم تحميله أولاً ، طالما كان محرك JS خاملاً في هذا الوقت ، سيتم تنفيذه على الفور. ينقسم التحسين هنا إلى نوعين -
A> إضافة خاصية Async - يمكنها بالفعل إكمال نقطة التحسين التي ذكرناها أعلاه ، ولكن لها قيود عالية ، أي أنها فقط لتحميل البرنامج النصي غير الاعتماد. المثال الأنسب هو تقديم نصوص متعددة من الطرف الثالث. أيضا ، الجمع مع سمة deffer هو حقا صفقة كبيرة. بالطبع ، لديها أيضا قضايا التوافق. أدت المشكلات الثلاثة المذكورة أعلاه إلى تطبيقها النادر. عند استخدام ASYNC ، يجب أن تولي اهتمامًا وثيقًا لقضايا التبعية.
B> Script Loading Scripts - من الواضح أننا نستخدم هذا لتحقيق الغرض من "التنفيذ الموازي للنصوص". في الوقت نفسه ، نسهل أيضًا التحكم في تبعيات البرنامج النصي ، لذلك نستخدم إدارة الحمل الذكية للتحميل غير المتزامن في المتطلبات.
حسنًا ، هذا كل شيء.
هنا ، أنا أتحدث فقط عن المحتوى المتعلق بنصوص التحميل غير المتزامنة. هناك جزء آخر من المحتوى ، وهو تحميل غير متزامن لملفات النمط أو الموارد الثابتة الأخرى. يتبع......