Kawa.netブログ(川崎有亮)

アクセスカウンタ

help リーダーに追加 RSS [JSON] コイツ、速いぞ! きっとFirefoxのXMLパーサが遅いんだ。

<<   作成日時 : 2006/05/01 01:47   >>

トラックバック 2 / コメント 4

ajax のデモも兼ねて、うちのサイトのトップページの右側のサイドバーにいろいろと
情報を載せていたら、5項目でXMLファイルの合計容量が190KB近くになっていた。
プレーンなデータしか記述できない XML は安全で、再利用性も高そうな気がするし、
Animation.CubeのようにクライアントPCの潤沢なCPU資源を浪費する
富豪プログラミングが許容される時代だと思って、好き勝手やっていたけど、
さすがにトップページの表示が遅いのは快適じゃない。
 
いくら ajax で async モードを使っていても、Firefox の XML パーサは遅くて、
しかも XML のパース処理中は他の処理がロックしてしまう。ロックは避けたい。
 
JSON::Syck モジュールで、サーバ側で予め JSON ファイルに変換したものを
利用するように変更してみた。
RSS ファイルと同じデータ構造なら、既存プログラムの変更も少なくて済む。
トップページの表示は10件までなので、JSON 版ではアイテム数も制限して、
URL・ページタイトル・更新日時以外の不要な情報も削除しちゃう。
 
すると、XML=190KB → JSON=14KB に減った!

・サイト全体の更新情報
      46221 http://www.kawa.net/index.rdf
      2100 http://www.kawa.net/rss/index.json

・はてなブックマークから注目エントリー10件
      47176 http://www.kawa.net/rss/hatena-bookmark.rss
      1786 http://www.kawa.net/rss/hatena-bookmark.json

・del.icio.us で最近見てきたページ10件
      16005 http://www.kawa.net/rss/recent-delicious.rss
      1913 http://www.kawa.net/rss/recent-delicious.json

・flickr にアップロードした写真10枚(うち最新9枚だけ表示)
      21152 http://www.kawa.net/rss/recent-flickr.rss
      3243 http://www.kawa.net/rss/recent-flickr.json

・ajaxcom の新着コメント
      18252 http://www.kawa.net/service/com/ajaxcom-data/recent.xml
      2939 http://www.kawa.net/service/com/ajaxcom-data/recent.json

・ajaxtb の新着トラックバック
      39112 http://www.kawa.net/service/tb/ajaxtb-data/recent.xml
      2341 http://www.kawa.net/service/tb/ajaxtb-data/recent.json

XML ファイルは冗長だとよく言うけれど、10倍とは。
実際には、アイテム件数制限や要素削除の効果が大きいから
アイテム件数制限や要素削除したバージョンの XML ファイルも作成して
比較してあげた方が公平だけど、ともかく、各 JavaScript 側も JSON 版に
切替えたら XML パーサのロックもなくなり、表示も速く快適になった。

こうも違うと、改めて XML で比較する気がしないです〜♪
XML に固執していた僕が青かった。素直に JSON を使おう。

※IE7β2、Firefox、Opera、Safari、OmniWeb で動作確認済。

rss2json.pl


クライアント側 JavaScript では、XML.ParseXML を利用しています。
サーバ側 Perl では、XML::FeedPP を使って JSON に変換しました。
参考に、RSS→JSON 変換のスクリプトを置いておきます。

#!/usr/bin/perl
# rss2json.pl
# Copyright 2006 Yusuke Kawasaki http://www.kawa.net/

# JSON または JSON::Syck のどちらかが必須。
# use JSON;
    use JSON::Syck;
    use XML::FeedPP;

# JSON出力するアイテム数と拡張要素

    my $MAX_ITEM = 10;
    my $ITEM_KEYS = [qw( media:thumbnail@url media:thumbnail@width media:thumbnail@height )];

# RSSファイル名(またはURL)と、出力するJSONファイル名

    my $file = shift @ARGV;
    my $out = shift @ARGV;
    unless ( defined $out ) {
        $out = $file;
        $out =~ s/\.[^\.]+$/.json/g;
    }

# XML::FeedPP モジュールでRSS/RDF/Atomファイルを展開する(形式問わず)

    my $feed = XML::FeedPP->new($file);
    $feed->normalize();
    $feed->limit_item( $MAX_ITEM );

# チャンネル情報を取り出す

    my $channel = {};
    $channel->{title} = $feed->title();
    $channel->{link} = $feed->link();
    $channel->{pubDate} = $feed->pubDate();

# アイテム情報を取り出す

    my $list = [];
    foreach my $item ( $feed->get_item() ) {
        my $hash = {
            title => $item->title(),
            link => $item->link(),
            pubDate => $item->pubDate(),
            author => $item->author(),
        };
        foreach my $key ( @$ITEM_KEYS ) {
            my $val = $item->get($key) or next;
            $hash->{$key} = $val;
        }
        push( @$list, $hash );
    }
    $channel->{item} = $list;

# JSON 形式に変換する

    my $tree = { rss => { channel => $channel }};
    my $text = JSON::Syck::Dump( $tree );
# my $text = objToJson( $tree );
    $text .= "\n";

# 前回の出力ファイルがあれば、内容を読み込む

    open( IN, $out ) and do {
        local $/ = undef;
        my $prev = <IN>;
        close( IN );
        if ( $prev eq $text ) {
            print STDERR "Nothing changed.\n";
            exit 0;
        }
    };

# 新しい内容で書き出す

    open( OUT, "> $out" ) or die "$! - $out\n";
    print OUT $text;
    close( OUT );

# 終了〜♪

    print STDERR "$out updated.\n";


使い方は、以下の通り。

perl ./rss2json.pl index.rss
perl ./rss2json.pl http://www.kawa.net/index.rdf hoge.json
第1形式は、ローカルの index.rss を読み取って index.json を作成します。
第2形式は、サーバ上の index.rdf を読み取って hoge.json を作成します。
フィードは RSS・RDF・Atom どれでもOKです。

////

え? やっぱり Plagger でも同じこと(RSS→JSON変換)できるの?

設定テーマ

関連テーマ 一覧

月別リンク

トラックバック(2件)

タイトル (本文) ブログ名/日時
[JSON] xml2json.pl - XMLファイルをJSONに変換するスクリプト
↓は RSS/RDF/Atom 専用のためアイテム件数制限や要素制限の処理が入っていたので、 スクリプトが少し長くなってしまっていたけど、フィードに限らず汎用化して 単に XML ファイルを JSON 変換するだけなら、もっと単純になると思った。 ...続きを見る
ゆうすけブログ
2006/05/01 13:42
rss2json:RSS(XML)からJSONに変換する方法まとめ(てかYahoo!Pipesでいい...
いまさらかもしれないけどね。 ■Perlな方法  ・[JSON] コイツ、速いぞ... ...続きを見る
creazy photograph
2007/12/17 02:11

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(4件)

内 容 ニックネーム/日時

※ http://test1.mydns.jp/chktest.htm

jklParseXMLのページにも書込んでたのですが、「JSON」の記述はこちらだった事を思い出したので、こちらにも書込ませて頂こうと思いました(すいません)

動作はこういう感じです
yahoo news
http://test1.mydns.jp/chktest.htm?url=http://headlines.yahoo.co.jp/rss/fsi.xml
auction
http://test1.mydns.jp/chktest.htm?url=http://api.auctions.yahoo.co.jp/AuctionWebService/V1/CategoryLeaf?appid=YahooDemo&category=42223

なかみはこうです
http://test1.mydns.jp/chktest_.htm


http://groups.yahoo.co.jp/group/YJDN/message/63
JSONでRSSリーダつくってみました(...
2007/01/21 12:17
.pmで、今度は「webとオークション両方検索」


するというものをちょっと作ってみました。


http://test1.mydns.jp/test3/dvdrecorder.htm

   「DV-DH500Wでテスト」

というボタンを押すと、web上のデータの表示のされかたがわかるかと思います。

あとこちらは「株価コード」でyahooマップ(と企業情報)を表示させるというものです。
http://www.test1.mydns.jp/yapi/zz.html?9955

(ここにも載せましたが。http://groups.yahoo.co.jp/group/YJDN/messages/79?expand=1 )
先日1/21にひきつづきJSON(とTr...
2007/02/04 22:57
”操作中止”、になるばあいがあるような気がするんですが。
( http://messages.yahoo.co.jp/bbs?.mm=FN&action=m&board=1009474&tid=a5bca5sa5ja5s&sid=1009474&mid=5041&thr=5041&cur=5041 )
グーグルマップは。。。jsonは使ってなかったですかね?先日02/04のyahooマップのほうにjsonも使ってたものですからつい(すいません)
googleMapで<b>タグを使うと
2007/02/16 13:06
ヤフー株式掲示板9474ゼンリンのNo5041あたりの書込みのurlでした。先程載せてたのは。

(A) http://test1.mydns.jp/gmap?test (/index.html?test、と実際は続いている。)
(B) http://test1.mydns.jp/gmap/test.htm?test
この2つは、それぞれの、21行めあたりの最後のほうに、上は<b>というタグをつかっており下のはそのタグを
  つかってないだけで、それ以外は、”全くおんなじ内容のhtmlファイル”、のはずなのですが

上のhtmlファイルのほうだけかならず「操作中止」となって終了してしまうようなのです。
urlがとちゅうまでしか書かれていません...
2007/02/16 13:09

コメントする help

ニックネーム
本 文

EDGE Now!