کد زیر رو در نظر بگیرید:
توی این کد تگ script داره یک اسکریپت حجیم مثل جیکوئری رو لود میکنه. همونطور که میدونیم، وقتی مرورگر میخواد این صفحه رو پردازش کنه، وقتی با این script مواجه میشه، ابتدا به طور کامل اون رو دانلود و اجرا میکنه و بعد به ادامهٔ پردازش صفحه میپردازه. این یعنی کاربری که از این صفحه دیدن میکنه، تا زمانی که این اسکریپت لود نشده نمیتونه صفحه رو به طور کامل ببینه و با اون تعامل داشته باشه. برای همین معمولاً پیشنهاد میشه که اسکریپتهای حجیم رو انتهای یک صفحه HTML قرار بدیم تا وقفهای توی پردازش صفحه به وجود نیاد.
اما خوبه که بدونیم راههای دیگهای هم وجود داره که بتونیم از یک اسکریپت توی هر جایی از صفحه استفاده کنیم بدون اینکه نگران بلاک شدن پردازشهای مرورگر باشیم. اون راهها استفاده از اتریبیوتهای defer و async هست.
defer
از این اتریبیوت (Attribute) به این صورت استفاده میکنیم:
defer به مرورگر میگه منتظر نباش تا من لود بشم. بنابراین پردازش صفحه متوقف نمیشه و مرورگر میره به ادامه پردازش صفحه میپردازه. اون اسکریپت توی بکگراند لود میشه و به محض اینکه DOM بهطور کامل ساخته شد اجرا میشه. بنابراین defer باعث وقفه توی کار مرورگر نمیشه.
اگه توی یک صفحه چندین اسکریپت defer داشته باشیم، همهٔ اونها توی بکگراند و به صورت موازی دانلود میشن. اما به همون ترتیبی اجرا میشن که توی کد قرار گرفتن:
توی این کد حتی اگه اسکریپت 2.js زودتر دانلود بشه، ابتدا باید منتظر باشه تا اسکریپت 1.js دانلود و اجرا بشه.
async
از اتریبیوت async به این صورت استفاده میکنیم:
اسکریپت async هم توی بکگراند دانلود و بعد اجرا میشه. پردازش DOM و همچنین بقیه اسکریپتها منتظر این اسکریپت نمیمونن و کاملاً مستقل از همدیگه به کارشون میپردازن. به بیان سادهتر، اسکریپت async به محض اینکه لود شد اجرا میشه؛ بدون توجه به اینکه آیا صفحه به طور کامل لود شده یا نه.
همچنین اگه توی صفحه چندین اسکریپت async داشته باشیم، همهٔ اونها مستقل از همدیگه دانلود و اجرا میشن. همچنین ترتیب اجرا اهمیتی نداره و اسکریپتی که زودتر دانلود شد اجرا میشه:
از این اتریبیوت معمولاً زمانی استفاده میکنیم که DOM وابسته به اون اسکریپت نیست. مثلاً اسکریپتهای آمارگیری مثل Google Analytics.
خلاصه
defer و async رو به تگهای script ـ اضافه میکنیم که قراره یک اسکریپت خارجی رو دانلود و اجرا کنن. این دو اتریبیوت باعث میشن که اسکریپتها به صورت مستقل دانلود بشن تا وقفهای توی پردازش صفحه ایجاد نشه. توی defer یک اسکریپت زمانی اجرا میشه که DOM کاملاً توسط مرورگر پردازش شده باشه. اما async به این توجه نمیکنه که آیا DOM لود شده یا نه و یا مرورگر هنوز مشغول پردازش صفحه هست یا نه.