Walka o milisekundy: eID i ajax call

Walka o milisekundy to cykl mini hack'ów, dzięki którym uda się nam "wyrwać" cenne ułamki sekund podczas parsowania strony.  W tym przypadku zajmiemy się eID i wywołaniami typu AJAX.

Podczas wdrażania kolejnych projektów, z góry planujemy użycie wtyczki evo_nginx_boost wszędzie gdzie to możliwe. Tak staramy się tworzyć całą funkcjonalność, aby działy serwisu o największym obciążaniu wykorzystywały ajaxa tak często jak to możliwe. Dobrze przygotowany kod z użyciem ajax'a pozwoli nam na ominięcie uruchamiania całego TYPO3 i minimalizacje czasów parsowania.

Idealnym przykładem może być podstrona w społeczności ze zdjęciem użytkownika. Wyobraźmy sobie, że link do zdjęcia został opublikowany w popularnym portalu. Ilość wejść na podstronę jest tak duża, że nawet 300 ms generacji strony może być za dużo. Wariant, który rozpatruję, zakłada, że strona jest ładowania z memcache za pomocą evo_nginx_boost a wszystkie dodatkowe wywołania jak: ilość wyświetleń, głosowania, komentowanie etc, wykonujemy przy użyciu eID i ajax'a.

Przy dużej ilości wtyczek które mamy zainstalowane, każde wywołanie eID powoduje wykonanie skryptów zawartych w plikach temp_CACHED_*_ext_localconf.php i temp_CACHED_*_ext_tables.php a następnie załadowanie do pamięci niezbędnej konfiguracji. Czasy które my uzyskiwaliśmy w naszym przypadku były na poziomie 50ms co można było odczuć podczas np głosowania. Przy bardzo dużym obciążeniu serwera, potrafiły sięgnąć nawet 100ms.

Rozwiązanie jest pozornie dość proste ale wymaga dużo pracy podczas obsługi wywołań za pomocą eID. Zacznijmy od zmian, które zmniejszą czasy do 1-3ms. We wszystkich wtyczkach w plikach ext_tables.php i ext_localconf.php należy dodać warunek if (!isset($_GET['eID'])), przykład z mm_forum:

zaznacz
  1.  
  2. //ext_tables.php
  3. if (!defined('TYPO3_MODE')) die('Access denied.');
  4. if(!isset($_GET['eID'])) { /* * Extend fe_user table */
  5. $tempColumns = array(
  6.  'tx_mmforum_avatar' => array(
  7.  'exclude' => 1,
  8.  'label' => 'LLL:EXT:mm_forum/locallang_db.php:fe_users.tx_mmforum_avatar',
  9.  'config' => array(
  10.  'type' => 'group',
  11.  'internal_type' => 'file',
  12.  'allowed' => 'gif,png,jpeg,jpg',
  13.  'max_size' => 300,
  14.  'uploadfolder' => 'uploads/tx_mmforum',
  15.  'show_thumbs' => 1,
  16.  'size' => 1,
  17.  'minitems' => 0,
  18.  'maxitems' => 1,
  19.  )
  20.  ),
  21. //cut
  22. }
  23. // eID cond
  24.  

Następnie wewnątrz kodu, który będzie obsługiwał wywołania typu ajax, musimy załadować wszystko to co jest nam niezbędne do wykonania prawidłowego zapytania do bazy. Przykład takiego kodu:

zaznacz
  1.  
  2. //example of eID and ajax
  3. if (!defined ('PATH_typo3conf')) die ('Could not access this script directly!');
  4. class tx_counter_ajax {
  5.  function __construct() {
  6.  tslib_eidtools::connectDB();
  7.  }
  8.  function increaseCounter($sourceTable, $uid) {
  9.  if (in_array($sourceTable, array('tx_multimedia_images', 'tx_multimedia_movies')))
  10.  $GLOBALS['TYPO3_DB']->sql_query('UPDATE '.$sourceTable.' SET views_counter=views_counter+1 WHERE uid='.intval($uid)); return $GLOBALS['TYPO3_DB']->sql_affected_rows();
  11.  }
  12. }
  13. if ($_GET['action']=='increaseCounter' && !empty($_GET['source']) && intval($_GET['uid'])>0) {
  14.  $ajaxObj = new tx_counter_ajax();
  15.  if ($ajaxObj->increaseCounter($_GET['source'], $_GET['uid']))
  16.  echo 'OK';
  17.  else echo 'ERR';
  18. } else
  19.  echo 'ERR';
  20.  

Teraz możemy spokojnie obserwować jak obciążenie naszego serwera zaczyna spadać, a prędkość działania naszej strony zauważalnie wzrasta :)

blog comments powered by Disqus