بهینه سازی عملکرد اپلیکیشن های PHP – به زبان ساده


در این نوشته قصد داریم به بررسی روشهای بهینهسازی عملکرد اپلیکیشن های PHP بپردازیم. دقت کنید که عملکرد اپلیکیشن صرفاً یک مسئله فنی نیست؛ بلکه عملکرد میتواند منجر به موفقیت یا شکست تجاری یک پروژه شود. بنابراین اگر تصور میکنید چند میلیثانیه اهمیت چندانی ندارد، باید در معلومات خود تجدیدنظر کنید.
چرا عملکرد مهم است؟
اصولاً سه دلیل برای چرایی اهمیت عملکرد میتوان برشمرد. دلیل نخست تجربه کاربری است؛ اگر اپلیکیشن شما به زمان زیادی برای بارگذاری نیاز دارد، در این صورت این ریسک وجود دارد که کاربران از خدمات رقبای شما استفاده کنند یا نظرات نامناسبی در مورد آن انتشار دهند که تأثیر بدی روی کسب و کار شما میگذارد. دلیل دوم برای اهمیت عملکرد، مفهوم «نرخ تبدیل» است. منظور از تبدیل، تعداد کاربرانی است که عملاً محصول شما را خریداری یا دانلود میکنند و یا به طور کلی کاربرانی که برای خدمات شما پول پرداخت میکنند. دلیل سوم، «مقیاسپذیری» است. هر چه اپلیکیشن شما درخواستهای بیشتری را بتواند در هر ثانیه مدیریت کند، میتوانید ترافیک بیشتری را دریافت کنید. برای نمونه اگر یک اپلیکیشن میتواند هر ثانیه به 10 درخواست پاسخ دهد، با نصف کردن زمان پردازش هر درخواست ظرفیت اپلیکیشن به دو برابر افزایش مییابد.
مطالعات موردی عملکرد
- فایرفاکس: زمانی که فایرفاکس توانست سرعت بارگذاری صفحه خود را 2.2 ثانیه کاهش دهد، 10 میلیون دانلود بیشتر دریافت کرد.
- Shopzilla: این وبسایت با افزایش سرعت بارگذاری وبسایت خود به میزان 5 ثانیه، نرخ تبدیل خود را 7 تا 12 درصد افزایش داد.
- Bing: موتور جستجوی مایکروسافت زمانی که 1 ثانیه کندتر شد، 2.8 درصد از درآمد خود را از دست داد.
- یاهو: یاهو نیز مانند بینگ زمانی که تنها 0.4 ثانیه کندتر بود، میزان ترافیکی که دریافت میکرد، 5 تا 9 درصد کمتر بود.
بنابراین اپلیکیشن شما به هر کسب و کاری که مربوط باشد، هر چه سریعتر باشد، درآمد بیشتری به ارمغان میآورد.
بهینهسازی عملکرد PHP
برای بهبود عملکرد اپلیکیشنهای PHP چندین روش وجود دارد که آنها را در ادامه معرفی میکنیم:
انتخاب نسخه صحیح
این نکته با معرفی نسخه 7 PHP که بهبود عملکرد قابلملاحظهای نسبت به نسخههای قدیمیتر آن ارائه میکند کاملاً بدیهی به نظر میرسد. ما در این نوشته قصد نداریم بین نسخههای مختلف PHP مقایسهای انجام دهیم چون مقالات زیادی به بررسی این موضوع پرداختهاند. با این وجود اگر به تصویر زیر توجه کنید، عملکرد نسخههای PHP که از سوی CMS-های مختلف اجرا میشود را مشاهده میکنید.
بهینهسازی ریز در PHP
بهینهسازیهای ریز به آن تغییرات جزئی در کد گفته میشود که موجب بهبود عملکرد اپلیکیشن میشوند. برای نمونه اگر قصد دارید از یک حلقه for استفاده کنید، همواره بهتر است که طول آن را از قبل محاسبه کنید. در تصویر زیر نتیجه اجرای یک حلقه for با 1000 کلید را میبینید که مقادیر 1 بایتی به آن داده شده است. میتوانید بهبود عملکرد را در زمان اجرایی مشاهده کنید:

با این که بهبودهای جزئی در مرحله بهینهسازی ریز صورت میگیرد؛ اما این بهینهسازی همچنان کافی نیست. شما میتوانید در وبسایت phpbench.com بینشهای جدیدی در مورد بهینهسازیهای ریز دریافت کنید.
XHProf برای پروفایل کردن کد PHP
پس از آن که مقدار محدود بهینهسازی ریز کد PHP را در بخش قبل دیدیم، اینک نوبت آن رسیده است که با استفاده از ابزاری به نام XHProf و بدون نیاز به تخمین زدن، دقیقاً تعیین کنیم کدام بخش از کد ما کُند است. پس از نصب و پیکربندی XHProf روی سرور میتوانید از راهنمای نصب آن که روی یوتوب ارائه شده است استفاده کنید. XHProf یک هدر و فوتر به همه اسکریپتهای PHP اضافه میکند و گزارشی در مورد همه تابعهای اجرایی، زمان اجرا، و تعداد فراخوانیهای هر تابع ارائه میکند.
در تصویر زیر نتیجه ایجاد پروفایل از یک صفحه محصولات را که با استفاده از فریمورک لاراول ساخته شده است، میبینید. این گزارش نشان میدهد که تابع ()getProductData به میزان 40 بار و با زمان اجرایی 5 ثانیه فراخوانی شده است.

بنابراین در نگاه نخست مشکل «N+1» را تشخص میدهیم که با رفع آن میتوانیم زمان بارگذاری صفحه را به میزان 5 ثانیه کاهش دهیم.
مشکل N+1 زمانی رخ میدهد که یک کوئری به پایگاه داده رابطهای برای بازیابی دادهها از دو جدول متفاوت ارائه میشود. برای نمونه تصور کنید برای همه محصولات کوئری میزنید تا نام و ID آنها را دریافت کنید. سپس برای هر محصول به جدول دیگری کوئری میزنید تا جزییاتی مانند رنگهای موجود یا موجودی انبارشان را دریافت کنید. به طور معمول این مشکل را میتوان با بازنویسی کوئری برای ارزیابی همه دادهها در یک یا به طور ماکزیمم دو کوئری، رفع کرد. این موضوع خارج از حیطه این مقاله است و در حوزه بهینهسازی کوئریهای پایگاه داده میگنجد.
کش کردن
پیادهسازی سازی یک لایه کش باعث میشود که فشار بارگذاری دادهها از پایگاه داده خارج شد و زمان بازیابی دادههایی که به فراوانی مورد نیاز هستند به میزان زیادی کاهش یابد. هر دو ابزار Memcache یا Redis به طور گستردهای برای کش کردن استفاده میشوند؛ اما Redis برخی مزیتهای رقابتی مانند همگامسازی دادهها روی دیسک دارد که باعث میشود در زمان راهاندازی مجدد سرور، دادهها از دست نروند و همچنین با امکان درونی تکرار master/slave میتوانیم به سادگی کلاستر redis را با افزایش رشد اپلیکیشن، گسترش دهیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزش های برنامه نویسی
- آموزش برنامه نویسی PHP
- مجموعه آموزش های طراحی و توسعه پروژه های وب
- برنامهنویسی PHP و هر آنچه برای شروع باید بدانید — آموزش جامع
- آموزش پروژه محور PHP — مجموعه مقالات جامع وبلاگ فرادرس
- آموزش فریمورک لاراول PHP Laravel برای ساخت فروشگاه اینترنتی
- آرایه های PHP — به زبان ساده
==