تگ Script رو کجا قرار بدیم ؟ فرق بین defer و async

یکی از سوال هایی که اکثر Front-end developer ها براشون مطرحه این هست که تگ Script که حاوی کدهای جاوااسکریپت بصورت بیرونی هستش رو کجای فایل HTML قرار بدیم که هم به خوبی و بدون تاثیر در سرعت و نمایش صفحه لود بشن و هم اینکه تا زمانیکه کامل لود نشدن مشکلی برای Render شدن اصل محتوای Body و کل فایل HTML بوجود نیارن .... ؟!؟!

البته ناگفته نماند که تو اکثر مصاحبه های Front-end هم این سوال مطرح میشه و با پرسیدن این مسئله می خوان به این قضیه پی ببرن که برنامه نویس چقدر به اتفاق هایی که از باز شدن URL داخل مرورگر رخ میده باخبر هستش و به کنترل Performance و بهینه بودن کدها اهمیت میده.

تگ script , فرق بین defer و async
تگ script , فرق بین defer و async

رفتار مرورگر در زمان Load شدن وب سایت چطوریه ؟!

خیلی نمی خوام وارد مسایل خارج از کدنویسی و مرتبط به شبکه و سرور بشم ... چون اول زمانیکه روی اینترنت یک وب سایت رو باز می کنید خیلی از مسایل پشت پرده مرتبط با موضوعات شبکه ای هستش !

زمانیکه شما یک وب سایت رو داخل مرورگر باز می کنید بعد از بررسی cache , کوکی ها و set شدن session های مربوطه توسط سرور , مرورگر شروع به parse کردن کدهای HTML و ... موجود می کنه و response رو مورد بررسی قرار میده. از بالا که DOCTYPE هستش شروع به پردازش می کنه تا به پایین. در این بین ما یکسری asset داریم که اونها رو دریافت می کنه و یکسری کدهای جاوااسکریپت که بصورت بیرونی و external به بدنه HTML اضافه شدن و باید اونها رو هم لود کنه.

در زمان پردازش فایل HTML وقتی مرورگر به تگ میرسه بقیه لود شدن صفحه و خواندن کدها رو متوقف می کنه تا کل فایل Script دانلود و روی حافظه مربوطه cache بشه. بخاطر این قضیه خیلی ها می آمدن تگ های Script رو در آخرین خط تگ Body قرار میدادن که در ابتدا کل کدهای HTML پردازش بشه , تمام عکس ها و Asset های موجود دانلود و بعد اون نوبت به Script برسه که اگر داخل کدهای جاوااسکریپت کارهای مرتبط به DOM رو انجام دادید بدون هیچ مشکلی کار انجام بگیره.

فرض کنید یک کدی مثل document.getElementById دارید و اگر Script رو بالا مثلا داخل Head یا اول Body بزارید و HTML یا المان مربوطه نیست کد جاوااسکریپت خطا میده و کار عملا error داره ...

حالا مشکل اینکار چیه ؟!

گفتیم یک trick بکار بردیم و اسکریپت هماون رو آخر تگ Body قرار دادیم که زمانیکه مرورگر به تگ Script میرسه متوقف نشه و کار به خطا نخوره , حالا مشکلی هم این قضیه داره که در ادامه توضیح میدم.

برای کنترل Performance و بالا رفتن سرعت لود شما باید دریافت و cache شدن script هارو در الویت قرار بدید , علی الخصوص زمانیکه حجم بالایی دارن و صفحه شما خیلی سنگین هستش. نمیشه اینکار رو به آخرین مرحله موکول کرد و خیلی بهینه نیست ....

برای حل اینکار باید از دو attribute مناسب به نام های defer و async استفاده کرد که خیلی کاربردی هستن و به شما این امکان رو میدن که همزمان فایل رو دانلود و بقیه کدهای HTML خوانده بشن.

<script type="text/javascript" src="path/to/script1.js" async>
<script type="text/javascript" src="path/to/script2.js" defer>

آشنایی با Defer و Async و فرقی که دارند

وقتی شما از async استفاده می کنید , کدهای جاوااسکریپت فایل external بصورت asynchronously دریافت شده و همزمان کدهای HTML بعد تگ script هم parse میشن , ولی درجا بعد از دانلود کامل فایل script کل فایل اجرا میشه.

یعنی اگر دو تگ script دارید که بصورت async قراره لود بشن , اونیکه حجمش کمتره و یا زودتر دانلود میشه زودتر هم اجرا میشه. یعنی ربطی به این نداره که اول کدومشون رو نوشتید و یا کدومشون خط اول و کدوم خط دوم یا بعدی هستش. به نوعی order نداره الویت به حجم و زمان دانلود هستش.

ولی وقتی از defer استفاده می کنید لود و اجرای تگ های script به نوعی order داره و نسبت به اینکه اول کدام تگ script رو قرار دادید الویت بندی میشن. البته مثل async لطمه ای به اجرا و لود شدن کدهای HTML بعد خودشون نمیزنن ولی یک تفاوت دارن که فقط کل document کامل لود شدن اجرا بشن.

نتیجه گیری

پس در نتیجه با استفاده از defer یا async نگران محل قرار گرفتن تگ های script حتی در بالا ترین خط فایل html مثلا داخل head نباشید و مطمئن باشید مرورگر با support کردن این دو امکان با بهترین حالت ممکن و performance مناسب صفحه HTML شما رو parse می کنه.

امیدوارم این مقاله مورد توجهتون قرار بگیره

موفق باشید