زمانی که یک فایل جاواسکریپت خارجی را در یک صفحه HTML لود می‌‌کنید، باید دقت کنید که این کار لطمه‌‌ای به عملکرد و بارگزاری صفحه شما وارد نکند. اینکه فایل جاواسکریپت شما در کدام قسمت صفحه و به چه شکلی داخل صفحه لود می‌شود، کاملا می تواند سرعت اجرای صفحه را تحت تاثیر قرار دهد.

همان‌طور که می‎دانید یک اسکریپت به صورت عادی به شیوه زیر به صفحه اضافه می‌شود:

<script src="script.js"></script>

زمانی که مرورگر به این خط می‌رسد، یک درخواست برای فراخوانی اسکریپت داده می‌شود و پس از دریافت موفقیت آمیز فایل، اسکریپت اجرا می‌شود.

به محض اینکه این فرآیند به اتمام برسد، تفسیر صفحه مجددا از سر گرفته می‌شود و بقیه کدهای HTML در صفحه وارد می‌شوند.

واضح است که این عملیات می‌تواند تاثیر زیادی بر سرعت بارگزاری صفحه بگذارد. اگر اجرای اسکریپت بیشتر از انتظار زمان ببرد، برای مثال در حالتی که شبکه اینترنت ضعیف است و یا از اینترنت همراه استفاده می‌‌شود، کاربر فقط یک صفحه سفید می بیند تا زمانی که اسکریپت به صورت کامل لود و اجرا شود.

اهمیت محل قرارگیری اسکریپت

شما ممکن است از روش زیر برای اضافه کردن اسکریپت به صفحه استفاده کنید

<html>
  <head>
    <title>Title</title>
    <script src="script.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

همان طور که پیش از این نیز گفتم، زمانی که مفسر به خط شامل اسکریپت می رسد (که در اینجا در هد قرار گرفته است) تفسیر HTML را رها کرده، اسکریپت را لود و اجرا می کند و سپس به ادامه بررسی صفحه می پردازد.

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

با انجام این کار اسکریپت زمانی لود و اجرا می شود که صفحه به صورت کامل رندر شده باشد که قطعا جایگزین بهتری به جای استفاده از تگ اسکریپت در هد صفحه است. این قابلیت برای سازگاری مرورگرهایی که از ویژگی های جدید HTML (که در ادامه در مورد آن توضیح می دهم) برای لود اسکریپت پشتیبانی نمی کنند بسیار مناسب است.

Async و Defer

در واقع async و defer دو Attribute در HTML هستند. این دو ویژگی در دسته boolean attribute ها قرار می گیرند. یعنی فقط مقدار true و false دارند. نحوه نوشتن آنها به صورت زیر است:

<script async src="script.js"></script>
<script defer src="script.js"></script>

این Attribute ها در واقع به مرورگر می گویند که فایل های جاواسکریپت خارجی به صورت غیرهمزمان در صفحه لود شود. اگر هر دو این attribute ها را در تگ اسکریت بنویسید، مرورگرهای مدرن از async استفاده می کنند و مرورگرهای قدیمی تر از async صرف نظر کرده و به صورت fallback به سراغ defer می روند.

این نکته را در نظر بگیرید که اهمیت استفاده از این attribute ها زمانی است که شما تگ اسکریپت را در head گذاشته باشید. در غیر این صورت اگر تگ شما در انتهای body باشد تغییر خاصی را در صفحه ملاحظه نخواهید کرد.

مقایسه عملکرد

تگ اسکریپت در head، بدون defer و یا async

در شکل زیر نحوه لود یک اسکریپت را می بینید که در تگ هد قرار داده شده است و از async یا defer نیز در آن استفاده نشده است.

استفاده از اسکریپت در head بدون defer و async
استفاده از اسکریپت در head بدون defer و async

تفسیر صفحه تا زمانی که اسکریپت لود و اجرا شود، متوقف می شود و سپس مجددا از سر گرفته می شود.

تگ اسکریپت در انتهای body، بدون defer و یا async

در شکل زیر نحوه لود یک اسکریپت را می بینید که در انتهای تگ body قرار داده شده است و از async یا defer نیز در آن استفاده نشده است.

استفاده از اسکریپت در انتهای body بدون defer و async
استفاده از اسکریپت در انتهای body بدون defer و async

تفسیر صفحه بدون وقفه انجام می شود و زمانی که تمام صفحه لود شد، به تگ اسکریپت می رسد و شروع به دانلود و اجرای آن می کند. بنابراین حتی قبل از دانلود فایل اسکریپت صفحه به سرعت برای کاربر اجرا می شود.

تگ اسکریپت در head با async

در این بخش عملکرد استفاده از async را در تگ اسکریپت در هد مشاهده می کنید:

استفاده از اسکریپت در head با async
استفاده از اسکریپت در head با async

اسکریپت در حقیقت به صورت غیرهمزمان (Async) بدون وقفه در رندر کردن HTML شروع به لود می کند و زمانی که دانلود آن کامل شد، عملیات رند صفحه متوقف شده و اسکریپت اجرا می شود. سپس مجددا رندر صفحه از سر گرفته می شود.

تگ اسکریپت در head با defer

در این بخش عملکرد استفاده از defer را در تگ اسکریپت هد مشاده می کنید:

استفاده از اسکریپت در head با defer
استفاده از اسکریپت در head با async

اسکریپت به صورت غیرهمزمان بدون متوقف کردن رندر HTML شروع به لود می کند و زمانی که دانلود آن کامل شد، رندر صفحه را متوقف نمی کند. بلکه منتظر رندر کامل صفحه می ماند و زمانی که صفحه به صورت کامل ایجاد شد، اسکریپت اجرا می شود.

در حقیقت async برای اجرای script عملیات تفسیر html را متوقف (blocking) می کند در حالیکه defer این کار را انجام نمی دهد.

بهترین حالت

بهترین حالا یا استفاده از تگ اسکریپت در هد به شکل زیر است:

<script defer src="script.js"></script>

و یا استفاده از تگ اسکریپت در انتهای body. که این امر کاملا به نحوه برنامه نویسی شما و طراحی صفحه برمی گردد.