بالا بردن راندمان UpdatePanel هایی که دارای کنترل GridView هستند
  در این مقاله به معرفی رویداد های مهم کنترل PageRequestManager و تکنیکی جهت بالابردن راندمان و سرعت بروز رسانی UpdatePanel هایی که محتوی کنترل GridView و کنترل های مشابه می باشند، می پردازم.
   Ajax
   ۱۹۳۰۸
   دانلود
   مرتضی صحراگرد
   ۱۳۸۷/۸/۱۸
ارسال لینک صفحه برای دوستان ارسال لینک صفحه برای دوستان  اضافه کردن به علاقه مندیها اضافه کردن به علاقه مندیها   نسخه قابل چاپ نسخه قابل چاپ

 

در ادامه ی دو مقاله قبلی خود، در مورد بالا بردن راندمان و کارایی صفحات وب ASP.NET AJAX، در این مقاله یکی دیگر از تکنیک های جالب را مطرح می کنم.

قبل از شروع این مقاله، پیشنهاد می کنم که دومقاله قبلی را حتما مطالعه نمایید.

برای یادگیری این ترفند، ابتدا نیاز است که با رویدادهایی که هنگام استفاده از کنترل UpdatePanel مورد استفاده قرار می گیرد، آشنا شوید.

PageRequestManager :

PageRequestManager یک آبجک جاوا اسکریپت موجود در ASP.NET AJAX می باشد. وظیفه این آبجک مدیریت وظایف مربوط به UpdatePanel می باشد. به عنوان مثال، وقتی کنترلی در داخل یک UpdatePanel درخواست عمل Postback می کند، آبجک PageRequestManager وظیفه انجام این عمل را به عهده می گیرد و اطلاعاتی را در مورد وضعیت Postback انجام شده در اختیار برنامه نویس قرار می دهد که در ادامه این مقاله این اعمال را بررسی خواهیم نمود.

هنگامی که یک کنترل در داخل UpdatePanel درخواست عمل Postback می کند و یا به عبارت دیگر، کنترل UpdatePanel تریگر می شود، آبجکت PageRequestManager چند رویداد مهم سمت کلاینت (Client Side Event) را در اختیار برنامه نویس قرار می دهد که با استفاده از این رویداد ها می توان عمل Postback درخواست شده را مدیریت نمود.

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

فرض کنید که یک کنترل Button داخل UpdatePanel دارید که با کلیک شدن آن، زمان کلیک شدن در یک Label نمایش داده می شود.

هنگامی که کنترل Button کلیک شد، رویدادهای زیر قابل دسترس می باشند.

  1. initializeRequest
  2. beginRequest
  3. pageLoading
  4. pageLoaded
  5. endRequest

قبل از اینکه به معرفی هر کدام از رویداد ها بپردازم، نظر شما را به شکل زیر که ترتیب رویدادهای اتفاق افتاده را نشان می دهد، جلب می کنم.

اگر با دقت به شکل بالا نگاه کنید، متوجه خواهید شده که بعد از رویداد pageLoaded ، رویدادی به نام load نیز وجود دارد که من در بالا اسمی از آن نبردم.

رویداد load توسط کلاس Sys.Application ، صرف نظر از این که صفحه در حال لود اولیه یا Refresh یا  Asynchronous Postback و یا حتی Postback معمولی باشد اتفاق می افتد.

 یعنی اگر صفحه برای اولین بار در حال لود شدن باشد و یا اینکه در حال Refresh شدن باشد و یا اگر یک UpdatePanel درخواست Postback نموده باشد، و یا حتی یک Postback معمولی درحال انجام باشد،  این رویداد اتفاق می افتد.

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

اکنون به بررسی رویداد های ذکر شده در بالا و نحوه کاربرد آنها می پردازم. (در ادامه این مقاله، استفاده از این رویداد ها را در کاربرد ملاحظه می کنید، پس نگران نباشید و مطالب را به دقت دنبال کنید.)

initializeRequest :

هنگامی که کنترلی در داخل UpdatePanel درخواست عمل Postback می کند (مثلا یک Button کلیک شود) ، ابتدا این رویداد رخ می دهد. در این رویداد هنوز درخواست عمل Postback به سرور ارسال نشده است و حتی آماده ارسال هم نشده است.

این رویداد بهترین مکان برای اعمالی همچون Cancel نمودن این درخواست می باشد. مثلا ممکن است که صفحه در حال حاضر در حال انجام عمل Asynchronous Postback می باشد(مثلا این Button قبلا کلیک شده و نتیجه آن هنوز برنگشته ولی کاربر مجددا Button را کلیک نموده است!)

عکس این عمل هم قابل انجام است و شما می توانید در خواست قبلی را Cancel کنید (در حقیقت Abort کنید) و به این درخواست جدید اجازه ارسال به سرور و پردازش بدهید.

در ادامه مقاله، نحوه استفاده از این رویداد و نحوده انجام اعمال فوق را خواهید دید.

beginRequest :

اگر در رویداد initializeRequest ، درخواست عمل Postback را Cancel نکرده باشیم. این رویداد اتفاق می افتد. در این رویداد درخواست عمل Postback،  آماده برای ارسال به سمت سرور می باشد و دقیقا بعد از این رویداد است که درخواست به سرور ارسال می شود.

نکته:

اگر با عملکرد کنترل UpdateProgress آشنا باشید، باید بدانید که در این رویداد است که این کنترل نمایش داده می شود. اگر با عملکرد این کنترل آشنا نیستید، پیشنهاد می کنم که این مقاله را مطالعه نمایید.

pageLoading :

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

در این مقاله از این رویداد استفاده جالبی می کنیم.

pageLoaded :

این رویداد مشابه رویداد pageLoading می باشد با این تفاوت که این رویداد پس از بروزرسانی محتویات جدید UpdatePanel اتفاق می افتد.

endRequest :

صرف نظر از اینکه خطایی در انجام عمل Postback صورت گرفته باشد یا خیر، این رویداد همواره اتفاق می افتد.

نکات :

  • به این دلیل است که Error Handling را همواره در این رویداد انجام می دهند.

  • کنترل UpdateProgress در این رویداد مخفی می شود.

در قطعه کد زیر، نحوه استفاده از رویدادهای فوق را مشاهده می نمایید.


<script language="javascript" type="text/javascript">
   var prm=Sys.WebForms.PageRequestManager.getInstance();
   prm.add_initializeRequest(onInitializeRequest);
   prm.add_beginRequest(onBeginRequest);
   prm.add_pageLoading(onPageLoading);
   prm.add_pageLoaded(onPageLoaded);
   prm.add_endRequest(onEndRequest);
   function onInitializeRequest(sender,args)
   {
      // if you want to abort the previous postback and continue new request
      //use the following code
      //if(prm.get_isInAsyncPostBack())
      //{
         // prm.abortPostBack();
      //}

      // if you want to cancel the new request and continue previous postback
      //use the following code
      //if(prm.get_isInAsyncPostBack())
      //{
         // args.set_cancel(true);
      //}

      alert(
'initializeRequest');
   }

   function onBeginRequest(sender,args)
   {
      alert(
'beginRequest');
   }

   function onPageLoading(sender,args)
   {
      alert(
'pageLoading');
   }

   function onPageLoaded(sender,args)
   {
      alert(
'pageLoaded');
   }

   function onEndRequest(sender,args)
   {
      alert(
'endRequest');
   }


</script>

همانطور که ملاحظه می کنید در ابتدا با استفاده از Sys.WebForms.PageRequestManager.getInstance به آبجک PageRequestManager دسترسی پیدا کرده ایم و سپس رویدادهای مورد نظر خود را رجیستر نموده ایم.

قبل از ادامه مقاله، لطفا قطعه کد فوق را اجرا نمایید و عملکرد آن را مشاهده کنید. (قطعه کد کامل این مقاله از لینک بالای صفحه قابل دریافت می باشد.)

خوب، اکنون می رویم به سراغ هدف اصلی این مقاله یعنی بالا بردن راندمان UpdatePanel هایی که دارای کنترل GridView هستند.

هنگامی که UpdatePanel در حال بروز رسانی است، ASP.NET AJAX تمام اشیاء DOM موجود در UpdatePanel را Dispose نموده و سپس این کنترل را بروز رسانی می نماید.

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

اکنون فرض کنید که یک کنترل GridView (یا کنترل های مشابه) داخل UpdatePanel وجود دارد و دارای عناصر زیادی می باشد. هنگام انجام عمل Paging و یا هر گونه بروز رسانی دیگر UpdatePanel ، ابتدا تمام اشیاء DOM موجود در GridView باید Dispose شوند و سپس عمل بروزرسانی UpdatePanel انجام شود که این عمل طبیعتا مدتی زمان می برد.

 یکی از راه های بالا بردن سرعت بروز رسانی UpdatePanel ، در حقیقت دور زدن (Bypass) این عمل می باشد.

برای دور زدن این عمل ما باید در رویداد pageLoading یعنی دقیقا قبل از اینکه عمل بروز رسانی UpdatePanel انجام شود، محتویات داخل GridView را خالی کنیم.

این عمل به شکل زیر انجام می شود.


<script language="javascript" type="text/javascript">
   var prm=Sys.WebForms.PageRequestManager.getInstance();
   prm.add_pageLoading(onPageLoading);
   function onPageLoading(sender,args)
   {
      var gv=$get('<%= GridView1.ClientID %>');
      gv.parentNode.removeChild(gv);
   }
</script>

با استفاده قطعه کد بالا در حقیقت عمل Dispose شدن اشیاء را دور زده ایم و این کار انجام نمی شود و در نتیجه مدت زمانی قابل توجهی را صرفه جویی نموده ایم.

نکته:

اگر داخل UpdatePanel از کنترل هایی استفاده نموده اید که توسط کامپوننت های ASP.NET AJAX و یا behaviorها (شامل Extender ها) مورد استفاده قرار گرفته اند، تکنیک ذکر شده قابل استفاده نمی باشد. مثلا اگر داخل GridView از modalpopupextender استفاده نموده اید، این تکنیک برای شما کارایی نخواهد داشت.

همانطور که قبلا اشاره کردم، سعی کنید حتما خصوصیت EnableViewState کنترل GridView را برابر false قرار دهید.

مقالات مرتبط :

قطعه کد کامل انجام شده در این مقاله از لینک بالای صفحه قابل دریافت می باشد.