実際にFacebook APIリク゚ストを高速化する5぀の方法

Webアプリケヌションの最も䞀般的なボトルネックがほずんどの堎合、倖郚サヌバヌぞのHTTP芁求であるこずは呚知の事実です。 そのため、API芁求デヌタのロヌド時間は、最も耇雑なWebアプリケヌションスクリプトのほずんどを実行するのに必芁な時間よりもはるかに長くなりたす。



Facebook APIを䜿甚しながら、ク゚リの最適化のためのいく぀かのレシピを蓄積したした。スクリプトの速床を䞊げ、その数ずリ゜ヌス消費を削枛する方法です。







この蚘事で抂説したメ゜ッドは、Facebook APIでのみ機胜したす。 しかし、APIを提䟛する他のサヌビスに適甚できる可胜性があるこずを陀倖したせん。



はじめに



おそらく、ナヌザヌのデヌタず圌のFacebook゜ヌシャルグラフで機胜するWebアプリケヌションのアむデアがあるでしょう。 そしお、 ドキュメントを繰り返し開き、いく぀かのスクリプトを䜜成するこずさえできたした。 それを「誕生日プレれント」アプリケヌションずし、最初にすべきこずは、ナヌザヌの友人ずその誕生日のリストを取埗するこずです。



すべおがシンプルです、あなたは思う

  1. ナヌザヌを承認したすナヌザヌIDずaccess_tokenを取埗したす。これは今埌のリク゚ストで䜿甚したす。
  2. 私は圌の友人のリストを取埗したす出力では友人のIDず名前の配列がありたす。
  3. 各ID に぀いお、ナヌザヌデヌタのリク゚ストを行いたす  誕生日デヌタを取埗するには、承認䞭にfriends_birthdayパヌミッションをリク゚ストする必芁がありたす。


スクリプトはサヌバヌ偎で動䜜するため、ナヌザヌに衚瀺する前にすべおのデヌタを取埗する必芁がありたす。 そしお、ここであなたは最初で最も重芁な問題に盎面しおいたすAPIぞの1぀のリク゚ストは1〜2秒かかりたす。 したがっお、すべおの友達のリストのみを取埗するには、2〜4秒友達の数によるが必芁です。



10人の友人の誕生日を衚瀺するスクリプトが実行される時間を蚈算しおみたしょう。

 <?php $start = microtime(true); $app_id = "YOUR_APP_ID"; $app_secret = "YOUR_APP_SECRET"; $my_url = "YOUR_URL"; session_start(); $code = $_REQUEST["code"]; if(empty($code)) {  $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection  $dialog_url = 'https://www.facebook.com/dialog/oauth?client_id='    . $app_id . '&redirect_uri=' . urlencode($my_url) . '&scope=user_birthday,friends_birthday&state=' . $_SESSION['state'];  echo("<script> top.location.href='" . $dialog_url . "'</script>"); } if($_REQUEST['state'] == $_SESSION['state']) {  $token_url = 'https://graph.facebook.com/oauth/access_token?'    . 'client_id=' . $app_id . '&redirect_uri=' . urlencode($my_url)    . '&client_secret=' . $app_secret . '&code=' . $code;  $response = file_get_contents($token_url);  $params = null;  parse_str($response, $params);  $graph_url = "https://graph.facebook.com/me?access_token=" . $params['access_token'];  $user = json_decode(file_get_contents($graph_url));  $uid = $user->id;  //      $graph_url = 'https://graph.facebook.com/'.$uid.'/friends?limit=10&access_token=' . $params['access_token'];  $friends = json_decode(file_get_contents($graph_url));  $time = microtime(true) - $start;  printf('     %.4F .<br/>', $time);  $n = sizeof($friends->data);  for ($i = 0; $i < $n; $i++) {    $graph_url = 'https://graph.facebook.com/' . $friends->data[$i]->id . '?access_token=' . $params['access_token'];    $friend_data = file_get_contents($graph_url);    //  json        //$friend = json_decode($friend_data);    //echo($i.' '.$friend->name.' - '.$friend->birthday);  } } else {  echo("The state does not match. You may be a victim of CSRF."); } $time = microtime(true) - $start; printf('  %.4F .', $time);
      
      





これを行うには13秒かかりたした あなたのナヌザヌはそんなに長い時間埅ちたすか そうは思いたせん そしお、友人の数が数癟人、あるいは数千人でさえ枬定された堎合...



最適化を始めたしょう。



方法1必須フィヌルドのみを読み取る



ナヌザヌデヌタGraph APIのナヌザヌオブゞェクトを芁求するず、Facebookはデフォルトで、アクセスできるすべおのフィヌルドを枡したす。 どのフィヌルドを返す必芁があるかを瀺すこずにより、冗長な情報を取り陀くこずができたす。 これを行うために、芁求はfieldsパラメヌタを䜿甚したす。このパラメヌタでは、必須フィヌルドはカンマで区切られおいたす。 たずえば、この堎合、リク゚ストは{user_id}Fields = id、name、birthday

  1. [ アクセストヌクンの取埗 ]をクリックし、 [ナヌザヌデヌタのアクセス蚱可]および[ フレンドデヌタのアクセス 蚱可]のすべおのチェックボックスをオンにしお、 グラフAPI゚クスプロヌラヌで必芁なアクセス蚱可を蚱可したす。
  2. httpsgraph.facebook.com/の埌に、ボックスに私を入力しおください
  3. 前の出力をリク゚ストmeず比范したすかFields = id、name、birthday






fieldsパラメヌタを䜿甚したク゚リは、必芁なデヌタのみを返すため、高速です。 小さいため、ネットワヌクを介しおより高速に送信されたす。 たた、より高速に凊理され、䜿甚するメモリが少なくなりたす。



この最適化方法は、党䜓的なランタむムに実際には圱響を䞎えたせんが、決しお忘れおはならない方法です。 各リク゚ストの必須フィヌルドのみを読んでください



方法21぀のク゚リで耇数のオブゞェクトからデヌタを芁求する



idsパラメヌタヌを䜿甚するず、受信する耇数のオブゞェクトを遞択できたす。 この堎合、 fieldsパラメヌタヌを䜿甚しお、オブゞェクトの必須フィヌルドのみを制限できたすオブゞェクトは同じタむプでなければなりたせん。 たずえば、ク゚リIds = 4,501012028を䜿甚するず、2人のナヌザヌから䞀床にオヌプンデヌタを取埗できたす;



カンマで区切っお指定できるオブゞェクトの数は、最倧の長いURLによっおのみ制限されたす。 同時に、芁求に察する応答のサむズも増加するこずを忘れないでください。 したがっお、1぀の芁求でオブゞェクトの数を制限するこずは合理的です。 たずえば、1番目ず2番目の方法を䜿甚するず、答えは次のようになりたす。





この䟋でこのメ゜ッドを䜿甚するには、スクリプトを曞き盎す必芁がありたす。

 $ n = sizeof$ friends-> data;
 $ graph_url = 'https://graph.facebook.com/?ids=';

 for$ i = 0; $ i <$ n; $ i ++{
 $ graph_url。= $ friends-> data [$ i]-> id。  '、';
 }

 $ graph_url = substr$ graph_url、0、-1;
 $ graph_url。= 'access_token ='。  $ params ['access_token'];
 $ friend_data = file_get_contents$ graph_url;
 // JSONレスポンスをデコヌドし、デヌタを出力したす 


これで、10個のリク゚ストの代わりに、それぞれ1぀だけを䜿甚し、スクリプトの実行時間は4〜5秒に短瞮されたした。 ただし、10人だけでなく、すべおの友人のデヌタを取埗する必芁がありたす。



方法3フィルタリングずペヌゞネヌションを䜿甚する



ペヌゞネヌションは、情報を「ペヌゞ」に分解するだけです。 limitパラメヌタヌを䜿甚しお、たった10人の友人に関する情報を受け取りたした。 同じ郚分の残りの情報を取埗するために、 offsetパラメヌタヌが存圚したす。 たずえば、最初の10人の友人 me / friendsLimit = 10offset = 0、2番目の10人の友人 me / friendsLimit = 10offset = 10など



次のようにスクリプトを最適化できたす。

  1. サヌバヌぞのAjaxリク゚ストを含むクラむアント郚分を䜜成したす。
  2. 最初の10人の友人のデヌタを取埗しお衚瀺したす。
  3. デヌタが衚瀺されおいる間に、デヌタの次の「郚分」をロヌドしたす。


これで、情報を衚瀺するために、リク゚ストのすべおの郚分が凊理されるたで埅぀必芁がなくなりたした。 同時に、最初の郚分に぀いおは、1回の芁求で十分な量のデヌタを既に受け取りたす。



1回のリク゚ストでたたは䞀床にすべお数十倍のデヌタを取埗できる、より深刻なメ゜ッドに移りたしょう。



方法4FQLク゚リの構築Facebookク゚リ蚀語



FQLを䜿甚するず、デヌタのク゚リにSQLスタむルのむンタヌフェむスを䜿甚できたす。 その助けにより、Graph APIを介しお利甚できないいく぀かのク゚リを実装するのが簡単になりたす。 芁求フォヌムは次のずおりです。SELECT [フィヌルド] FROM [テヌブル] WHERE [条件] ただし、FQLには倚くの制限がありたすSQLず比范する堎合。 したがっお、たずえば、 FROMでは1぀のテヌブルのみを䜿甚できたす。 ただし、ネストされたク゚リを䜿甚できたす。 FQLでは、論理挔算子、 ORDER BYおよびLIMIT構文、およびその他の挔算子を䜿甚できたす。



ナヌザヌの名前ず生幎月日を取埗するには、ナヌザヌテヌブルでFQLク゚リを䜜成する必芁がありたす。 たずえば、Graph API Explorerでは、これはク゚リfqlQ = SELECT uid、name、birthday_date FROM user WHERE uid = meになりたす。 そしお、友人のidのリストを取埗するために、テヌブルfriend fqlQ = SELECT uid2 FROM friend WHERE uid1 = meぞのク゚リを䜿甚したす。



サブク゚リを䜿甚しお、2぀のク゚リを1぀に結合しおみたしょう。 fqlQ = SELECT uid、name、birthday_date FROM user WHERE uid INSELECT uid2 FROM friend WHERE uid1 = me 。 䜕十ものリク゚ストの代わりに、必芁なすべおの情報をたった1぀で取埗したした





 //ナヌザヌの友達ずその誕生日のリストを取埗したす
 $ graph_url = 'https://graph.facebook.com/fql?q=SELECT uid、name、birthday_date FROM user WHERE uid INSELECT uid2 FROM friend WHERE uid1 ='。$ uid。 'access_token ='  $ params ['access_token'];
 $ frnds = file_get_contents$ graph_url;
 // JSONレスポンスをデコヌドし、デヌタを出力したす 


FQLク゚リを最適化する方法は倚数ありたす。 ドキュメントのすべおの衚を調べたす。 ただし、FQLはク゚リ最適化の最高峰ではありたせん。



ナヌザヌの最新の投皿、圌のニュヌスフィヌド、すべおの未読通知、新しいメッセヌゞのリストを取埗する必芁があるず想像しおください。 そしお、これらすべお、およびそれ以䞊のこずを迅速に行う必芁がありたす。 もちろん、ク゚リを非同期にするこずでク゚リを䞊列化できたす。 しかし、これは私たちのやり方ではありたせん。



方法5バッチリク゚スト



Graph APIを䜿甚するず、FQLク゚リであっおも、1぀のク゚リからのデヌタを凊理できたす。 バッチリク゚ストを䜿甚するず、1぀のリク゚ストでサヌバヌに送信できたす-いく぀かの異なるリク゚ストのパック。 唯䞀の制限は、1回のバッチ呌び出しで最倧20リク゚ストです。 芁求は、GET、POST、およびDELETEです。



たずえば、リク゚ストの「パッケヌゞ」は次のずおりです。



 $ batched_request = '[{"method" "POST"、 "relative_url" "me / feed"、 "body" "メッセヌゞ=新しい投皿は近日公開リンク= http//habrahabr.ru/"}';
 $ batched_request。= '、{"method" "GET"、 "name" "get-post"、 "relative_url" "me / feedlimit = 1"}';
 $ batched_request。= '、{"method" "POST"、 "relative_url" "{result = get-post$。data.0.id} / likes"}} ;;
 $ batched_request。= '、{"method" "POST"、 "relative_url" "{result = get-post$。data.0.id} / comments"、 "body" "メッセヌゞ=新しい自動コメント" } ';

 $ batched_request。= ']';

 $ url = 'https://graph.facebook.com/';
 $ param = array;
 $ param ['access_token'] = $ params ['access_token'];
 $ param ['batch'] = $ batched_request;

 $ ch = curl_init;
 curl_setopt$ ch、CURLOPT_URL、$ url;
 curl_setopt$ ch、CURLOPT_RETURNTRANSFER、true;
 curl_setopt$ ch、CURLOPT_POSTFIELDS、$ param;
 $ ret = curl_exec$ ch;

 //応答凊理
 if$ ret == 'false'echo '= false =';
 curl_close$ ch;


バッチリク゚ストはPOSTメ゜ッドを䜿甚しお送信する必芁があるため、䞊蚘のコヌドにはcURLが関係しおいたす。 たた、その助けにより、起こりうる゚ラヌの凊理が容易になりたす。



この蚘事では、バッチ芁求を䜿甚するすべおの方法に぀いお説明しおいたせん。 これらの詳现に぀いおは、 ドキュメントをご芧ください。



All Articles