چرا اسکریپتهای سایت شما دوباره بارگذاری میشوند؟ راهنمای wp_enqueue_script
تابع wp_enqueue_script برای بارگذاری اصولی JavaScript در وردپرس؛ بررسی پارامترها، handle، deps، version، in_footer و اشتباهات رایج در قالب و افزونه.
چرا بارگذاری ساده کافی نیست؟
در قالبهای اولیه، فایلهای JavaScript با تگ<script> مستقیم در هدر بارگذاری میشدند. این رویکرد چند مشکل جدی دارد: اول اینکه ترتیب بارگذاری قابل کنترل نیست. دوم اینکه اگر افزونه دیگری همان اسکریپت را بارگذاری کند، دو نسخه در صفحه ظاهر میشود. سوم اینکه مرورگر نمیتواند از کش استفاده کند، چون نسخه فایل قابل تشخیص نیست.
وردپرس با معرفی سیستم صفبندی (Queue) و تابع wp_enqueue_script، این مشکلات را حل کرد. اسکریپتها با یک شناسه یکتا (handle) ثبت میشوند، وابستگیها تعریف میشوند و ترتیب بارگذاری تضمین میشود. این ساختار پایه توسعه حرفهای در وردپرس است.
تابع wp_enqueue_script چیست؟
تابعwp_enqueue_script() یک تابع هسته وردپرس است که در فایل wp-includes/script-loader.php تعریف شده است. این تابع یک اسکریپت را به صف بارگذاری اضافه میکند و وردپرس در زمان مناسب (معمولاً در هدر یا فوتر)، آن را در HTML درج میکند.
اگر اسکریپت با همان handle قبلاً ثبت یا بارگذاری شده باشد، این تابع آن را دوباره بارگذاری نمیکند. این رفتار از بارگذاری تکراری و تداخل جلوگیری میکند.
نکته مهم این است که این تابع نباید در زمان اشتباه فراخوانی شود. اگر در زمان مناسبی که پیش از wp_enqueue_scripts باشد، فراخوانی شود، اسکریپت در HTML نمایش داده نمیشود.
امضای تابع و پارامترها
امضای این تابع بهشکل زیر است:function wp_enqueue_script( $handle, $src = '', $deps = array(), $ver = false, $args = array() ) {
// ...
}
پارامتر اول (handle) شناسه یکتای اسکریپت است. پارامتر دوم (src) آدرس فایل است. پارامتر سوم (deps) آرایهای از handleهای وابسته است. پارامتر چهارم (ver) نسخه اسکریپت است که برای Cache Busting استفاده میشود. پارامتر پنجم (args) میتواند بولی باشد (در فوتر یا هدر بارگذاری شود) یا آرایهای از تنظیمات مانند in_footer، strategy و async.
اگر $src خالی باشد، وردپرس انتظار دارد که اسکریپت قبلاً با wp_register_script ثبت شده باشد.
هوک صحیح فراخوانی
تابعwp_enqueue_script باید در هوک wp_enqueue_scripts فراخوانی شود. اگر در هوک دیگری فراخوانی شود، احتمال دارد اسکریپت در HTML نمایش داده نشود.
نمونه صحیح در قالب:
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_assets' );
function mytheme_enqueue_assets() {
wp_enqueue_script(
'mytheme-main',
get_template_directory_uri() . '/assets/js/main.js',
array( 'jquery' ),
'1.0.0',
true
);
}
نکته مهم: در افزونهها همین هوک استفاده میشود. برای بارگذاری در پنل مدیریت، از هوک admin_enqueue_scripts استفاده کنید که در راهنمای هوک admin_enqueue_scripts به تفصیل بررسی شده است.
مدیریت وابستگی با deps
پارامترdeps یک آرایه از handleهای وابسته است. اگر اسکریپت شما به jQuery یا هر کتابخانه دیگری نیاز دارد، باید آن را در این آرایه قرار دهید. وردپرس تضمین میکند که ابتدا وابستگیها بارگذاری شوند و سپس اسکریپت اصلی.
نمونه:
wp_enqueue_script(
'mytheme-slider',
get_template_directory_uri() . '/assets/js/slider.js',
array( 'jquery', 'mytheme-main' ),
'1.0.0',
true
);
نکته مهم: اگر وابستگیای را فراموش کنید، ممکن است خطای JavaScript رخ دهد. اگر وابستگی اضافی تعریف کنید، ممکن است اسکریپتهای غیرضروری بارگذاری شوند و سرعت کاهش یابد.
نسخهبندی و Cache Busting
پارامترver نسخه اسکریپت را مشخص میکند. وردپرس این مقدار را به انتهای URL اضافه میکند:
/assets/js/main.js?ver=1.0.0
وقتی نسخه را تغییر دهید، مرورگر فایل جدید را از سرور دریافت میکند و از کش قدیمی استفاده نمیکند. این مکانیزم که Cache Busting نامیده میشود، در بهروزرسانی قالبها و افزونهها حیاتی است.
روش حرفهای، استفاده از زمان تغییر فایل است:
$file_path = get_template_directory() . '/assets/js/main.js';
$version = file_exists( $file_path ) ? filemtime( $file_path ) : '1.0.0';
wp_enqueue_script(
'mytheme-main',
get_template_directory_uri() . '/assets/js/main.js',
array(),
$version,
true
);
این رویکرد اطمینان میدهد که با هر تغییر فایل، نسخه بهروزرسانی میشود و مرورگر فایل جدید را بارگذاری میکند.
بارگذاری در فوتر و Performance
پارامتر پنجم (in_footer) تعیین میکند که اسکریپت در هدر یا فوتر بارگذاری شود. مقدار true باعث بارگذاری در فوتر میشود که تجربه بارگذاری سریعتر را فراهم میکند چرا که HTML و CSS ابتدا رندر میشوند.
قاعده ساده:
- اگر اسکریپت در ابتدای بارگذاری صفحه نیاز است، در هدر بارگذاری کنید
- اگر اسکریپت به DOM وابسته است و میتواند پس از رندر اجرا شود، در فوتر بارگذاری کنید
در وردپرس ۶.۳ به بعد، میتوان از پارامترهای strategy برای async و defer استفاده کرد:
wp_enqueue_script(
'mytheme-analytics',
'https://example.com/analytics.js',
array(),
null,
array(
'in_footer' => true,
'strategy' => 'defer',
)
);
نکته مهم: استراتژی defer به مرورگر میگوید که اسکریپت را پس از تجزیه HTML اجرا کند. استراتژی async اسکریپت را مستقل از سایر اسکریپتها بارگذاری میکند. انتخاب بین این دو به وابستگیهای اسکریپت بستگی دارد.
کاربردهای عملی در قالب و افزونه
بارگذاری اسکریپت اصلی قالب:add_action( 'wp_enqueue_scripts', 'mytheme_scripts' );
function mytheme_scripts() {
wp_enqueue_script(
'mytheme-main',
get_template_directory_uri() . '/assets/js/main.js',
array( 'jquery' ),
filemtime( get_template_directory() . '/assets/js/main.js' ),
true
);
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
بارگذاری اسکریپت شرطی در صفحات فروشگاهی:
add_action( 'wp_enqueue_scripts', 'mytheme_shop_scripts' );
function mytheme_shop_scripts() {
if ( function_exists( 'is_woocommerce' ) && ( is_woocommerce() || is_cart() || is_checkout() ) ) {
wp_enqueue_script(
'mytheme-shop',
get_template_directory_uri() . '/assets/js/shop.js',
array( 'jquery' ),
'1.0.0',
true
);
}
}
حذف اسکریپت غیرضروری:
add_action( 'wp_enqueue_scripts', 'mytheme_dequeue_scripts', 100 );
function mytheme_dequeue_scripts() {
if ( ! is_page_template( 'templates/contact.php' ) ) {
wp_dequeue_script( 'contact-form-7' );
wp_deregister_script( 'contact-form-7' );
}
}
این الگو در پروژههای بهینهسازی بسیار کاربردی است و امکان کاهش تعداد درخواستهای HTTP را فراهم میکند.
نقش در Child Theme
در Child Theme، برای بارگذاری اسکریپت سفارشی، ازget_stylesheet_directory_uri استفاده کنید:
add_action( 'wp_enqueue_scripts', 'mychild_scripts' );
function mychild_scripts() {
wp_enqueue_script(
'mychild-custom',
get_stylesheet_directory_uri() . '/assets/js/custom.js',
array( 'jquery' ),
filemtime( get_stylesheet_directory() . '/assets/js/custom.js' ),
true
);
}
نکته مهم: اگر میخواهید اسکریپتی را که Parent Theme ثبت کرده، غیرفعال کنید، از wp_dequeue_script در Child Theme استفاده کنید:
add_action( 'wp_enqueue_scripts', 'mychild_dequeue_parent_scripts', 20 );
function mychild_dequeue_parent_scripts() {
wp_dequeue_script( 'mytheme-old-slider' );
}
برای مطالعه بیشتر درباره ساختار Child Theme به راهنمای get_stylesheet_directory_uri و راهنمای get_template_directory_uri مراجعه کنید.
نکات امنیتی و اشتباهات رایج
اشتباه اول، نبود handle یکتا است. اگر handle تکراری باشد، وردپرس فقط اولین اسکریپت را بارگذاری میکند و بقیه نادیده گرفته میشوند. اشتباه دوم، نبودdeps است. اگر اسکریپت شما به jQuery وابسته است و این وابستگی تعریف نشود، ممکن است خطای JavaScript رخ دهد.
اشتباه سوم، بارگذاری تکراری است. اگر اسکریپت را با تگ <script> مستقیم در هدر و همچنین با wp_enqueue_script بارگذاری کنید، دو نسخه در صفحه ظاهر میشود.
اشتباه چهارم، نبود نسخهبندی است. اگر ver را روی null یا ثابت بگذارید، مرورگر پس از بهروزرسانی فایل، نسخه قدیمی را از کش بارگذاری میکند.
اشتباه پنجم، نبود شرط برای بارگذاری شرطی است. اگر اسکریپت را در همه صفحات بارگذاری کنید، سرعت سایت کاهش مییابد و کاربران در صفحات غیرمرتبط فایلهای اضافی دریافت میکنند.
اشتباه ششم، نبود escape در URL است. اگر از متغیر پویا برای URL استفاده میکنید، همیشه esc_url را بهکار ببرید. راهنمای این تابع در صفحه esc_html آمده است.
اشتباه هفتم، نبود تست است. باید در همه صفحات قالب (برگه، نوشته، آرشیو، ۴۰۴) بررسی کنید که اسکریپت بهدرستی بارگذاری میشود و هیچ خطای JavaScript رخ نمیدهد.
تحلیل فنی پیشرفته
در نگاه مهندسی، تابعwp_enqueue_script() یک نقطه معماری در لایه رندر است که بر چند جنبه از سیستم اثر میگذارد. لایه اول لایه صفبندی است. وردپرس یک ساختار داخلی برای صف نگه میدارد که شامل اسکریپتهای ثبتشده، وابستگیها و ترتیب بارگذاری است. این ساختار با توابع wp_scripts() قابل دسترسی است.
لایه دوم لایه ترتیب بارگذاری است. وردپرس با تحلیل گراف وابستگیها، ترتیب صحیح بارگذاری را تعیین میکند. اگر یک حلقه وابستگی وجود داشته باشد، وردپرس بهصورت خودکار تشخیص میدهد و از بارگذاری جلوگیری میکند.
لایه سوم لایه Performance است. بارگذاری اسکریپتهای غیرضروری در همه صفحات، تعداد درخواستهای HTTP را افزایش میدهد و زمان بارگذاری را کند میکند. استفاده از بارگذاری شرطی و defer و async میتواند سرعت را چند برابر کند.
لایه چهارم لایه کشینگ است. مرورگر فایلهای JavaScript را بر پایه URL کش میکند. اگر نسخه در URL تغییر نکند، مرورگر نسخه قدیمی را بارگذاری میکند. پارامتر ver این مشکل را حل میکند.
لایه پنجم لایه امنیت است. اگر URL اسکریپت از منبع بیرونی باشد، باید بررسی شود که منبع معتبر است. بارگذاری اسکریپت از منابع نامعتبر میتواند به حمله XSS منجر شود.
لایه ششم لایه Integration است. اسکریپتها اغلب با دادههای PHP تعامل دارند. برای پاس دادن داده از PHP به JS، از wp_localize_script استفاده کنید که در راهنمای wp_localize_script به تفصیل بررسی شده است.
لایه هفتم لایه Multisite است. در شبکههای Multisite، هر سایت میتواند قالب متفاوتی داشته باشد و اسکریپتها در هر سایت جداگانه صفبندی میشوند.
لایه هشتم لایه تست است. تستهای End-to-End باید مطمئن شوند که اسکریپتها در همه صفحات بارگذاری میشوند و خطای JavaScript رخ نمیدهد. مفاهیم پایهای JavaScript در JavaScript در ویکیپدیا توضیح داده شده است.
برای مطالعه بیشتر روی توابع مرتبط، میتوانید به راهنمای wp_enqueue_style، راهنمای wp_register_script، راهنمای wp_localize_script، راهنمای هوک wp_enqueue_scripts، راهنمای هوک admin_enqueue_scripts و راهنمای get_template_directory_uri مراجعه کنید.
پرسشهای پرتکرار
تفاوتwp_enqueue_script و wp_register_script چیست؟ اولی اسکریپت را ثبت و بلافاصله بارگذاری میکند؛ دومی فقط ثبت میکند و بارگذاری را به زمان دیگری میسپارد.
آیا میتوان اسکریپت را در فوتر بارگذاری کرد؟ بله، با پارامتر پنجم روی true.
چطور از بارگذاری تکراری جلوگیری کنیم؟ با handle یکتا و بررسی wp_script_is.
چطور از Cache Busting استفاده کنیم؟ با پارامتر ver یا با استفاده از filemtime.
چطور یک اسکریپت را حذف کنیم؟ با wp_dequeue_script و wp_deregister_script در هوک wp_enqueue_scripts با اولویت بالا.
نتیجه و مسیر ادامه
تابعwp_enqueue_script() ابزار استاندارد وردپرس برای بارگذاری اصولی اسکریپتها است. استفاده درست از آن یعنی تعریف handle یکتا، تعریف وابستگیها، نسخهبندی مناسب، بارگذاری شرطی و استفاده از defer و async. اشتباههای کوچک در این تابع اغلب به کاهش سرعت، خطای JavaScript یا بارگذاری تکراری منجر میشوند.
اگر این تابع را در پروژهای واقعی به کار بردهاید و رفتار غیرمنتظرهای دیدهاید — بهخصوص در ترکیب با افزونههای کش یا در سایتهای فروشگاهی — تجربهتان میتواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.