سال گذشته پروژه‌ای به من سپرده شد که در نگاه اول، حجم نیازهایش آدم را می‌ترساند: یک سامانهٔ سفارش خدمات صنعتی با پورتال مشتری، فرم پیش‌فاکتور چندمرحله‌ای، فایل‌های اختصاصی برای هر مشتری، اطلاع‌رسانی پیامکی، اتصال به یک سامانهٔ خارجی برای همگام‌سازی سفارش، و چندین نوع کاربر با دسترسی‌های متفاوت. مشتری از تجربهٔ پروژهٔ قبلی‌اش با یک تیم دیگر می‌گفت که «حدود بیست و پنج افزونه برای این کار لازم است». من پس از چند جلسه، درخواست یک تغییر رویکرد دادم و گفتم «بیایید اول نقشه را ساده کنیم، بعد افزونه انتخاب کنیم». سه ماه بعد، همان پروژه با هشت افزونه تحویل داده شد. این مقاله، داستان همان ساده‌سازی است — نه به‌عنوان یک تبلیغ برای کم‌افزونه‌بودن، بلکه به‌عنوان یک چارچوب عملی که در آن پروژه جواب داد.

مشکل واقعی در پروژه‌های پیچیده چیست؟

در پروژه‌های پیچیده، طبیعی‌ترین واکنش این است که برای هر نیاز، یک افزونه پیدا کنیم. هر افزونه به‌نظر منطقی می‌آید: این یکی برای فرم، آن یکی برای عضویت، آن یکی برای پیامک. ولی در عمل، تجربهٔ کاری من در چند پروژهٔ بزرگ نشان داده که افزونه‌ها، مثل آجر در ساخت یک دیوار هستند: تا وقتی چند تا باشند، مشکلی نیست؛ ولی وقتی ده‌ها آجر روی هم می‌روند، وزن دیوار به مرز شکست می‌رسد. سه هزینهٔ پنهان هر افزونهٔ اضافه: هزینهٔ نگهداری (هر افزونه به‌روزرسانی جداگانه نیاز دارد)، هزینهٔ سازگاری (هر افزونه ممکن است با دیگری تعارض داشته باشد) و هزینهٔ عملکرد (هر افزونه، حتی کوچک، بخشی از هر درخواست را می‌گیرد). اگر با مفهوم افزونه و لایه‌بندی‌اش آشنایی ندارید، ابتدا افزونه وردپرس چیست و چگونه افزونه مناسب انتخاب کنیم را بخوانید.

در پروژه‌های پیچیده، انتخاب درست افزونه، در نهایت به تصمیم «چه چیزی نباید افزونه باشد» برمی‌گردد.

اصل اول: مدل سه‌سؤالی پیش از هر نصب

پیش از هر نصب افزونه در آن پروژه، سه سؤال را از خود و تیم می‌پرسیدیم:

  1. آیا هستهٔ وردپرس یا ووکامرس (در صورت وجود) این قابلیت را دارد؟
  2. آیا این قابلیت با کد سفارشی در چایلد تم قابل ساخت است؟
  3. آیا در نهایت باید از افزونه استفاده کنیم؟

پاسخ این سه سؤال، به سه سرنوشت متفاوت منتهی می‌شد: استفاده از هسته، کد سفارشی، یا افزونه. در آن پروژه، بیست و هفت نیاز استخراج شد. از این تعداد، شش مورد با هستهٔ وردپرس و ووکامرس حل شد، نه مورد با کد سفارشی، و دوازده مورد با افزونه. پس از بازبینی، تعداد افزونه‌ها به هشت کاهش یافت — چون چهار نیاز هم‌پوشان بودند و سه نیاز دیگر به کد سفارشی منتقل شد.

نقشه‌برداری از نیازها پیش از انتخاب افزونه

اولین قدم جدی در ساده‌سازی پروژه، نقشه‌برداری از نیازها بود. یک برگهٔ بزرگ برداشتم و در سه ستون، همهٔ نیازهای پروژه را نوشتم:

  • ستون اول — نیازهای داده‌ای: مانند «هر سفارش باید چند فایل اختصاصی داشته باشد»، «هر مشتری باید یک پورتال شخصی داشته باشد».
  • ستون دوم — نیازهای فرآیندی: مانند «پیش‌فاکتور باید در سه مرحله تأیید شود»، «اطلاع‌رسانی پیامکی باید در مراحل مشخص ارسال شود».
  • ستون سوم — نیازهای ظاهری: مانند «پورتال مشتری باید با هویت برند طراحی شود»، «فرم پیش‌فاکتور باید در موبایل روان کار کند».

این نقشه‌برداری، تفکیک بین «قابلیت» و «ظاهر» را روشن کرد. نکتهٔ کلیدی: نیمی از نیازهایی که در ابتدا «افزونه‌ای» به نظر می‌رسیدند، در واقع نیازهای ظاهری بودند که با CSS و قالب قابل حل بودند. برای مطالعهٔ چارچوب تفکیک قابلیت از ظاهر، مسیر افزونه وردپرس چیست را پیشنهاد می‌کنم.

ماتریس تصمیم: هسته، افزونه، کد سفارشی

پس از نقشه‌برداری، هر نیاز از ماتریس زیر عبور می‌کرد:

  1. هسته: اگر هستهٔ وردپرس یا ووکامرس می‌توانست نیاز را برآورده کند، انتخاب اول بود. مثال: نیاز به انواع مختلف محصولات در ووکامرس، با انواع محصول موجود در هسته حل شد.
  2. کد سفارشی در چایلد تم یا افزونهٔ اختصاصی: اگر نیاز، منطق ساده‌ای داشت (کمتر از ۱۰۰ خط کد) و افزونه‌ای استاندارد متناسب نداشت، به کد سفارشی منتقل می‌شد. مثال: اعتبارسنجی سفارشی فرم پیش‌فاکتور که با یک اسنیپت PHP در چایلد تم حل شد.
  3. افزونه: اگر نیاز، منطق پیچیده یا قابلیت تخصصی داشت که از صفر ساختنش مقرون‌به‌صرفه نبود، به افزونه منتقل می‌شد. مثال: سیستم پیامک، که افزونهٔ تخصصی موجود به‌مراتب بهتر از ساخت سفارشی عمل می‌کند.

در این ماتریس، معیار اصلی «قابل نگهداری بودن در سه سال آینده» بود، نه سرعت تحویل امروز. با این معیار، بسیاری از نیازها به کد سفارشی منتقل شدند، چون نگهداری یک افزونهٔ پیچیده در سه سال، به‌مراتب پرهزینه‌تر از نگهداری ۱۰۰ خط کد سفارشی است.

هشت افزونه‌ای که برای پروژه انتخاب شد

در نهایت، هشت افزونه برای پروژه انتخاب شد. فهرست و دلیل هر انتخاب:

  • ووکامرس: به‌عنوان هستهٔ سفارش‌ها، چون در همان ساختار، همهٔ نیازهای اولیه حل می‌شد.
  • افزونهٔ عضویت: برای ساخت پورتال مشتری و کنترل دسترسی، چون کد سفارشی این حجم، زمان‌بر و پرریسک بود.
  • افزونهٔ فرم‌ساز: برای فرم پیش‌فاکتور چندمرحله‌ای، چون فرآیند تأیید و اعتبارسنجی پیچیده در آن پشتیبانی می‌شد.
  • افزونهٔ پیامک: برای اطلاع‌رسانی، چون اتصال به سرویس‌های پیامک سفارشی، خارج از توان تیم نبود ولی نگهداری‌اش پیچیده بود.
  • افزونهٔ بکاپ: برای حفاظت داده‌ها — مسیر انتخاب در بهترین افزونه‌های پشتیبان‌گیری وردپرس.
  • افزونهٔ امنیتی: برای سخت‌سازی لاگین و پایش — مسیرش در بهترین افزونه‌های امنیتی وردپرس.
  • افزونهٔ کش: برای سرعت و TTFB.
  • افزونهٔ اتصال به API بیرونی: برای همگام‌سازی با سامانهٔ خارجی، چون منطق OAuth و Retry در آن از قبل پیاده شده بود.

هر افزونه، پیش از نصب، روی استیجینگ تست شد و اثر آن روی TTFB (Time To First Byte — زمان تا اولین بایت) و زمان اجرای صفحه سنجیده شد. سه افزونه از فهرست اولیه در این تست رد شدند — چون تفاوت معناداری در عملکرد نداشتند، ولی پیچیدگی اضافه می‌کردند. تفاوت رویکرد ما با فهرست رایج، در همین بازبینی بود: در فهرست رایج، تعداد افزونه‌ها بیش از ۲۰ عدد بود. تفاوت اصلی، در پنج دستهٔ زیر خلاصه می‌شد که ما حذف کردیم:

  • افزونهٔ آماری — با Analytics گوگل و یک اسکریپت ساده جایگزین شد.
  • افزونهٔ اسلایدر — با بلوک گوتنبرگ و CSS حل شد.
  • افزونهٔ گالری — با بلوک گالری بومی ووکامرس.
  • افزونهٔ بهینه‌سازی تصویر — با فشرده‌سازی پیش از آپلود و یک اسنیپت.
  • افزونهٔ ریدایرکت — با کد سفارشی در چایلد تم.

کد سفارشی: آنچه افزونه نشد

نُه نیاز پروژه با کد سفارشی حل شد، نه با افزونه. سه نمونهٔ شاخص:

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

جدول مقایسه انتخاب ما با گزینهٔ رایج

بخشگزینهٔ رایجانتخاب مادلیل
فرم پیش‌فاکتورافزونهٔ فرم‌ساز پیشرفتهافزونه + کد سفارشی برای اعتبارسنجیکاهش وابستگی
پورتال مشتریافزونهٔ عضویت + پنل اختصاصیافزونهٔ عضویت + قالب‌های سفارشیکاهش پیچیدگی نگهداری
اطلاع‌رسانیافزونهٔ پیامک + افزونهٔ ایمیلافزونهٔ پیامک + SMTP در هستهکاهش افزونه
همگام‌سازیسه افزونهٔ اتصال APIیک افزونهٔ اتصال با منطق مشترککاهش نقاط شکست
آمار و تحلیلافزونهٔ آماری درون‌سایتیGoogle Analytics + یک اسنیپت سفارشیکاهش بار دیتابیس

نتیجه در عمل: سه معیار قابل اندازه‌گیری

پروژه سه ماه بعد از تحویل، سه معیار قابل اندازه‌گیری را نشان داد که تأیید رویکرد ما بود:

  • سرعت سایت: TTFB صفحهٔ اصلی زیر ۲۰۰ میلی‌ثانیه، LCP (Largest Contentful Paint — زمان نمایش بزرگ‌ترین عنصر) زیر ۲.۵ ثانیه در موبایل. این اعداد، در مقایسه با نسخهٔ اولیه که ۴.۲ ثانیه بود، تفاوت چشمگیری داشت. تفاوت اصلی، در حذف پنج افزونهٔ اضافه و انتقال منطق به کد سفارشی بود.
  • نرخ خطای سفارش: در سه ماه اول، تعداد سفارش‌های ناقص یا خطادار، نزدیک صفر بود. در پروژه‌های مشابه با افزونه‌های بیشتر، معمولاً ماهانه چند مورد خطا گزارش می‌شود که هر یک به ساعت‌ها بررسی نیاز دارد.
  • زمان نگهداری: فهرست هشت افزونه، در یک ساعت قابل بازبینی و به‌روزرسانی است. در مقابل، نگهداری بیست‌وپنج افزونه، حداقل نیم‌روزکاری در هر ماه می‌طلبد و ریسک بالاتری برای تعارض دارد.

درس‌های عمومی این پروژه

  • ساده‌سازی، نه فقط کاهش: هدف اصلی، کمتر کردن تعداد افزونه‌ها نبود؛ هدف، ساده کردن معماری برای نگهداری بلندمدت بود.
  • نقشه‌برداری پیش از انتخاب: نیمی از پیچیدگی پروژه، از نبود نقشه‌برداری دقیق می‌آید. اگر نیازها در ابتدا روشن شوند، تصمیم‌های فنی ساده‌تر می‌شوند.
  • کد سفارشی، دشمن نیست: در پروژه‌های پیچیده، بخشی از نیازها با کد سفارشی تمیزتر، سریع‌تر و کم‌ریسک‌تر از افزونه حل می‌شوند.
  • تست استیجینگ، غیرقابل بحث: هر افزونه‌ای که روی سایت زنده نصب می‌شود، باید قبلاً روی استیجینگ تست شده باشد. مسیر راه‌اندازی استیجینگ در توسعه وردپرس با محیط لوکال.
  • مستندسازی تصمیم‌ها: برای هر افزونه یا کد سفارشی، یک یادداشت کوتاه نوشتیم: چرا انتخاب شد؟ روز خروج چه خواهد بود؟ این مستندسازی، سه سال بعد ارزشش را نشان می‌دهد.

نگاه لایه‌ای: ساده‌سازی به‌عنوان تصمیم معماری

برای توسعه‌دهندهٔ ارشد و معمار نرم‌افزار، ساده‌سازی یک پروژهٔ پیچیده، خودش یک تصمیم معماری است، نه یک نتیجهٔ جانبی. سه اصل که این پروژه را به موفقیت رساند:

اصل اول — تفکیک «قابلیت» از «ابزار». یک قابلیت، می‌تواند با ابزارهای مختلفی پیاده شود. مثال: قابلیت «پورتال مشتری» با افزونهٔ عضویت، با ساختار کاربری سفارشی، یا با ترکیب هر دو ممکن است. انتخاب ابزار درست، در سایهٔ تفکیک قابلیت از ابزار اتفاق می‌افتد. بدون این تفکیک، هر نیاز به یک افزونهٔ جداگانه منجر می‌شود و پروژه به یک انبار افزونه تبدیل می‌شود. اصل دوم — حداقل‌سازی نقاط شکست. هر افزونه، یک نقطهٔ شکست است. اگر پروژه‌ای به ده افزونه وابسته باشد، در هر بازهٔ زمانی، احتمال این که یکی از آن‌ها با نسخهٔ جدید وردپرس یا افزونهٔ دیگر تعارض پیدا کند، به‌مراتب بیشتر است. حداقل‌سازی تعداد افزونه‌ها، مستقیماً کاهش نقاط شکست است.

اصل سوم — سادگی در مرزهای تصمیم. در پروژه‌های پیچیده، سادگی نباید در جزئیات اجرا اتفاق بیفتد، بلکه در مرزهای تصمیم. یعنی تصمیم‌های کلان (چه چیزی افزونه، چه چیزی کد سفارشی) باید روشن و مستند باشند. در آن پروژه، ما برای هر نیاز یک برگهٔ تصمیم نوشتیم: چرا این مسیر انتخاب شد، در چه شرایطی بازبینی می‌شود، و اگر روزی این افزونه حذف شود، جایگزین چیست؟ این مستندسازی، ارزشش را در ماه هفتم نشان داد — وقتی یک افزونه به‌روزرسانی نشد و ما بدون بحران، آن را با یک جایگزین عوض کردیم، چون از قبل برنامهٔ خروج داشتیم. برای مطالعهٔ چارچوب کلی این تصمیم‌ها، مسیر چگونه یک پروژه توسعه وردپرس را ساختاربندی کنیم و چند افزونه وردپرس روی یک سایت نصب کنیم؟ و افزونه‌های وردپرس چطور روی سرعت سایت اثر می‌گذارند را پیشنهاد می‌کنم. قاعدهٔ پایانی که در پروژه‌های اخیر روی آن تأکید کرده‌ام: در پروژه‌های پیچیده، هدف «کمترین افزونه» یا «بیشترین افزونه» نیست؛ هدف «کمترین افزونه‌ای است که می‌تواند نیازها را با کمترین بدهی فنی پوشش دهد». این تعریف، تفاوت بین یک پروژهٔ ساده‌سازی‌شده و یک پروژهٔ ساده‌نماست.

اگر در پروژه‌ای مشابه، تصمیم ساده‌سازی گرفته‌اید و نتیجهٔ واقعی آن را دیده‌اید — چه کاهش افزونه، چه انتقال بخشی از منطق به کد سفارشی — سناریو را در دیدگاه بنویسید. تجربه‌های واقعی در این حوزه، به‌خصوص در پروژه‌های پیچیده‌ای که تصمیم‌های متعدد دارند، از هر راهنمای نظری ارزشمندتر است. 🧩