2月 03 2009

OpenSocialガジェット開発で注意すべきキャッシュ機能

Published by Eiji at 0:03:19 under OpenSocial

先日の記事でShindigが持つOpenSocialアーキテクチャの強力なキャッシュ機能について触れました。Shindigには大きく4種類のキャッシュが存在しています。

  • ガジェットXMLのキャッシュ
  • makeRequestでアクセスされる外部APIのキャッシュ
  • featureを固めたJavaScriptのキャッシュ
  • JavaScript、CSS、imgなどHTMLからリンクされたリソースのキャッシュ

ガジェットXMLのキャッシュ

OpenSocialガジェットを開発し始めて最初につまずくのがこのガジェットXMLのキャッシュでしょう。ガジェットXML上で変更を行っても、それが実際のガジェット表示上に反映されない場合は、まずガジェットXMLがキャッシュされていることを疑いましょう。

ガジェットXML上でJavaScriptコードを修正しつつサンドボックス環境で動作確認しながら開発したい場合は、URLのquery部分にnocache=1を加えることで、キャッシュが無効化されます。これで開発がだいぶ楽になるはずです。(コンテナによってはURLの末尾が途中からhash(#以降)になっている場合があるので、気をつけてください。)

なお、iGoogleのサンドボックスではMy Gadgetsでキャッシュを無効にできたり、hi5ではサンドボックスなら特に何もしなくてもキャッシュが無効だったりといった特徴もあります。

makeRequestでアクセスされる外部APIのキャッシュ

makeRequestを使って外部のリソースにGETでアクセスした場合、これもキャッシュされます。例えばRSSを取得するような場合、更新頻度の低いものであれば相手方サーバーの負荷を少しでも軽減することができます。

これを回避したい場合は、makeRequestのopt_paramsにgadgets.io.ProxyUrlRequestParamters.REFRESH_INTERVALというパラメータを追加し、0に設定してください。これで、キャッシュされなくなります。

featureを固めたJavaScriptのキャッシュ

OpenSocialでは、ガジェットXMLにRequire@featureを加えることで、様々な機能が利用できるという仕様があります。このfeatureは、ガジェット内に表示されるHTMLにJavaScriptを追加することで機能を実現していますが、Shindigではここでも軽量化/効率化を図っています。featureのJavaScriptは、レンダリング時に難読化した上で全てをひとつに繋げて、キャッシュされます。

一般ユーザー/ガジェットディベロッパーがこれを意識する必要はほぼありませんが、頭の片隅にいれておきましょう。

JavaScript、CSS、imgなどHTMLからリンクされたリソースのキャッシュ

コンテナによっては(orkut, iGoogle, hi5等、今のところJava版のShindigを使っているサービス)、ガジェットXML内で指定された外部のJavaScript、CSS、imgが、レンダリング時にキャッシュされます。レンダリングされたガジェットのHTMLを見ると、キャッシュされた外部リソースのURLのpath部分の最後にconcatが付いていることから、キャッシュされていることが分かると思います。

この機能はContent Rewriteと呼ばれるのですが、OpenSocialバージョン0.9からは正式な機能として取り込まれますが、現段階ではShindig Java版独自の機能です。0.9では、ガジェットXMLの設定でどのファイルタイプをリライトするのか、JavaScriptなら圧縮するか、キャッシュする場合の有効期限はどれくらいか、などを指定できるようになります。

さて、このキャッシュは実運用時に各ファイルの置かれているサーバーの負荷を軽くすることが目的ですが、開発時にはコードの修正が即座に反映されず、効率を下げてしまうこともあるでしょう。これを回避するには、下記をXMLに追加します。

<Optional feature="content-rewrite>
  <Param name="include-tabs" />
</Optional>

コンテナによってはサポートしない場合がありますので注意してください。

ところで、PHP版 Shindigの場合はこの機能がありません。つまり、もしガジェットが例えば、あなたのサーバーに用意したファイルを指しているとしたら、ガジェットのレンダリングの度にリクエストが発生するため、開発には便利な反面、本番環境で大量にアクセスが来た場合サーバーに負荷がかかってしまいます。これを回避するため、キャッシュ機能をうまく利用する、というテクニックもあります。

http://opensocial-container/gadgets/proxy?url=http://devlog.agektmr.com/image.gifのように、ドメインに”/gadgets/proxy?url=”を付けて、意図的にShindigのプロキシを入れてしまいましょう。(concatと異なり、難読化や圧縮はされません。)

追記(2009/2/3)

上記に関して、コメント欄でmainyaさんから、getProxyUrlを使ったやり方を教えていただきました。

var params = {'REFRESH_INTERVAL' : 3600*24*7};
var url = 'http://example.com/img/logo.jpg';
try{
  url = gadgets.io.getProxyUrl(url, params);
}catch(e){}

このやり方でURLを取得すれば、コンテナに依存しない方法でキャッシュを意図的に効かせた参照を行うことができるようになります。(MySpaceでは使えないのでtry/catchした方がよいそうです)

 

Comments add to hatena hatena.comment (8) add to del.icio.us (0) add to livedoor.clip (2) add to Yahoo!Bookmark (0) Total: 10

  • 最後のproxyのURLはコンテナごとに異なるのと、locked-domain機能によってコンテナのサブドメインはガジェットURLごとに違うの場合があるため、gadgets.io.getProxyUrlで取得した方がいいと思います。
    ただ、myspaceではgadgets.io.getProxyUrlが動かないのでtry-catchで囲む必要がありますが。。。

    var params = {"REFRESH_INTERVAL" : 3600*24*7};
    var url = "http://example.com/img/logo.jpg";
    try{
    url = gadgets.io.getProxyUrl(url, params);
    }catch(e){}
  • そうですね。確かにProxyURLを使ったやり方の方が汎用性が上がってスマートです。
    Gadget API Japanグループで伊藤さんがJSを読み込むサンプルコードを紹介されてました。
    http://groups.google.co.jp/group/Google-Gadgets...

    <script type="text/javascript">
    var url = gadgets.io.getProxyUrl('http://std-ig.googlecode.com/svn/
    trunk/std-ig.js');
    document.open();
    document.write('<scr'+'ipt src="' + url + '"></scr' + 'ipt>');
    document.close();
    </script>

    後ほど追記しておきます。
blog comments powered by Disqus