Raccoon Tech Blog [株式会社ラクーン 技術戦略部ブログ]

株式会社ラクーン 技術戦略部より、tipsやノウハウなど技術的な話題を発信いたします。

ウェブ全般

法人インフォのAPIを触ってみた

法人インフォ

開発の松尾です。


2017/1/19に、経済産業省の「法人インフォメーション(法人インフォ)」というサービスが開始されました。政府が保有する400万件にのぼる法人情報を自由に検索できるという、なかなか画期的なサービスです。

WS000000

ラクーンではB2B向けのサービスを複数展開していることもあり数多くの企業情報を取り扱います、政府によって一元化された企業情報に自由にアクセスできるというのは、ラクーンの事業にとって様々なメリットがあります。

続きを読む

IE8でjQueryが重いなと思ったら、やるべき3つのこと

こんにちは。なべです。

入社半年の新人 ですが、このような場をいただきましたので、入社してすぐに取り組んだInternetExplorer(以下、IE) 8のjQueryのパフォーマンス対策について書いてみたいと思います。

なぜIE8か?

このブログにたどり着くような方はHTML5をいじってみたり、普段使用するブラウザもFirefoxやChromeという場合が多いと思います。
そんな中、この記事のタイトルを見て、なぜ今さらIE8・・・と思ったのではないでしょうか?

というわけで、まずは、なぜ今IE8のパフォーマンス対策なのかを説明したいと思います。
 
sd_brws_share
右のグラフは、スーパーデリバリーにおける訪問者のブラウザのシェアを簡略化したグラフです。
グラフにもあるようにIE8はスーパーデリバリーではおよそ15.4%のユーザーが利用しています。
※2013/07時点のデータです。

IE8が多い理由としては以下のことが考えられます。
・スーパーデリバリーはBtoBサイトで、出展企業様や小売店様が仕事ととして利用されるため、会社やお店などにある仕事用のPCから利用されている。
・その場合、やはりWindowsが多く、さらに購入時にプレインストールされているブラウザを利用するケースが多いためIEが多い。
・会社内のPCは家庭にくらべて新陳代謝が緩やかなので、数年内にリリースされたバージョンが混在する。(IE8,9,10がほぼ同じ割合)
ちなみにIE6もまだ1%強使われています。
 
その前提に立つと、今後、Windows XPのサポート切れに伴って企業内で利用するPCの買い替えが進み、Windows8のシェアが上がってくるにつれて、IE10のシェアが増えてくることが予想されますが、それまでしばらくはIE8は主要ブラウザとして扱う必要があります。

さて、IE8サポートの重要性がわかったところで本題に入りたいと思います。

問題

「IE8のjQueryのパフォーマンス対策」というのは、IE8でスーパーデリバリーの商品一覧ページを開くと、画面が利用できるようになるまでに時間がかかるという問題への対応でした。
プロファイラなどで調査した結果、原因は$(".hoge")のようにクラスをセレクタに指定してjQueryオブジェクトを操作している部分で処理が重くなり、時間がかかっていることがわかりました。

それはなぜでしょうか? 

この現象の説明の前に、jQueryの仕組みを少しお話しておきます。

jQueryはブラウザ間の違いを吸収して共通のインターフェースを提供してくれるJavaScriptのライブラリです。
jQueryはどのブラウザでも同じように利用することができますが、内部的にはブラウザによって処理を分岐し、微妙な違いを吸収して、ブラウザの機能を呼び出したり、jQueryで実装したりして、ドロドロした部分を隠し、我々に使いやすいようにしてくれています。

この実装の違いに落とし穴があります。
ブラウザの機能を使える場合には、ネイティブメソッドを呼び出すことができますが、jQueryで実装となった場合は、ブラウザ上で動くJavaScriptの処理になります。
当然JavaScriptよりもネイティブメソッドのほうが速いためここでパフォーマンスの差がでます。
よって、できるだけjQueryの独自実装部分に入らないように実装することがパフォーマンス向上の一つの施策になります。

さて、IE8の話に戻ります。
ここまでの説明で想像がついているかと思いますが、IE8でクラスをセレクタに指定した処理が重いのは、IE8まではクラスセレクタで要素を取得する機能がブラウザの機能として提供されていない(=ネイティブメソッドにない)ためです。
これはJavaScriptのコンソールなどで以下をそれぞれ打つと確認することができます。
document.getElementById("aaa")
document.getElementsByTagName("aaa")
document.getElementsByClassName("aaa")
よって、jQueryではIE8でクラスをセレクタに指定された場合、JavaScriptにより、対象となる全要素をループ処理で走査するため遅くなっています。

ちなみに、このjQueryの検索ロジックのライブラリをSizzleといいます。
SizzleはjQueryの内部で使われていて、意識して利用することはほとんどないはずですが、github上で公開されているオープンソースのプロジェクトなので、より深く知りたい場合にはこちらをご覧ください。

対策

クラスセレクタを指定してjQueryオブジェクトを取得すると検索処理が実行されて重くなるわけですから、対策としては、クラスをセレクタに指定してノードを検索する処理をできるだけ避ける必要があります。
そこで、以下の3つの対策が考えられます。
     
1. そもそもクラスセレクタを使わない
2. クラスセレクタによる検索対象を減らす
3. クラスセレクタによる検索回数を減らす

それでは個々の対策を説明していきたいと思います。

1. そもそもクラスセレクタを使わない

クラスセレクタを使わずにID("#xxx")で指定できるところはIDで指定します。
IDを指定することにより、ネイティブメソッドでサポートされているgetElementByIdが使用されますので、これだけで速度は改善します。
注意しなければならないのは、IDはDocument上で一意でなければならない点です。
この制約が守れるのであれば、IDに置き換えるのが良いでしょう。

2. クラスセレクタによる検索対象を減らす

とはいえ、IDに単純に置き換えられるところばかりではありません。むしろ、少ないでしょう。
だからといって、
jQueryを使う上で、クラスを使って複数の要素をまとめて操作する機能を使わないというのは考えられません。
ですので、以降はクラスセレクタを使いつつ負荷を最小限にする手段をご紹介します。
 
まずはクラスセレクタで検索する対象を減らし、走査にかかる負荷を減らすことを考えます。
例えばbarクラスを操作したい場合、     
$(".bar")
と書くと、全ての要素が検索対象になってしまいます。
そこで、barクラスの前にかならずIDをもつ親要素があるならば、そこを基点にして     
$("#foo").find(".bar")
と指定します。こうすることで、ID(foo)の以下にある要素だけを検索対象にすることができます。
さらに必ず親要素がID:fooであることがわかっているなら、     
$("#foo").children(".bar")
と指定します。こうすることで、子要素だけに対象を絞り、孫要素より下の階層を検索対象から外すことができます。
ほかにも、next(兄弟要素の次)やsiblings(兄弟要素)、parent(親要素)など基点を中心に周辺を指定できますので活用すると良いと思います。

次に、タグ名を指定することでも負荷の軽減になります。
getElementsByTagNameもネイティブメソッドに存在するため、いきなりクラスを指定するよりも高速になります。    
$("div.bar")
と.いうようにタグと一緒にクラスを指定したり    
$("li").find(".bar")
のようにタグで親になる要素を絞ってから、その下のクラスを指定することで対象を絞ることができます。

このように、できるだけ検索対象の母数を絞ることで、負荷を軽減します。

3. クラスセレクタによる検索回数を減らす

つぎに、クラスセレクタによる重い検索処理を何度も実行して負荷が上がっている場合があります。
例えば以下のコードはどうでしょうか。
$(".bar").css("color","#fff");
$(".bar").css("border","thin solid #000")
$(".bar").width(100);
負荷の高い$(".bar")の検索を3度も実施しています。
この場合は検索をした結果を一度変数に格納し使いまわすことを考えます。
var bar=$(".bar");
bar.css("color","#fff");
bar.css("border","thin solid #000");
bar.width(100);
このように変更することで検索を1回にすることができます。

ちなみに、今回の例のように設定系の処理だけであれば、ドット(.)でつなげて以下のようにも書くことができます。       
$(".bar").css("color","#fff").css("border","thin solid #000").width(100);

以上が3つの対策になります。

まとめ

スーパーデリバリーでは、これら3つの対策をすることで「IE8でjQueryが重い」現象に対応し、パフォーマンス問題を改善することができました。
もし、いまお困りであれば試してみてください!
 
まとめのまとめとして、今回の対策からの学びを、本質的な観点からまとめたいと思います。

今回最も大きな原因は、IE8の機能不足によるものでした。
ただし、使用するライブラリや実行環境の問題というのは多くの場合制御不能なので、”特徴”と捉えてうまく付き合うしかありません。
今回の現象も、「重い」という問題になる前に特徴を把握して、対策をしておけば、顕在化することなく防げていたと思います。

ただ、そもそも、「対策」にあげている、2.検索対象を減らしたり、3.検索回数を減らすといった対策は、通常のプログラムを書く場合や、SQLを考える場合などでも考慮すべき点です。
ひと昔前はJavaScriptというとプログラミング言語というよりはHTMLの一部みたいに考えていた頃もありましたが、改めてプログラミング言語だということを意識して、設計・実装を行うことが必要です。
これらを意識していれば、もし仮に特徴を知らなかったとしても、パフォーマンスが問題にならなかったかもしれません。

また、パフォーマンスの改善の効果の他に、検索回数を減らすために要素の取得処理をまとめ、複数箇所に分散させないことで、修正箇所が絞られ、スクリプト言語にありがちなスペル違いや修正漏れを防ぐことができ、メンテナンス性も改善できます。

日頃からシンプルで保守性の高いコードを心がけたいですね!
Don't repeat yourself!

最後に

スーパーデリバリーのTOPページを2013年7月3日にリニューアルしています。
デザイナーとプログラマのこだわりがぎっしり詰まったNewTOPページをぜひご覧ください
担当したログイン後のスライドショーはスーパーデリバリーの会員様だけにしかお見せできないのが少し残念ですが、、、


 

仕事内容のご紹介 ~デザイン制作部編

こんにちは。
11月に新設されましたデザイン制作部(旧:技術戦略部 WEBマスターチーム)のみながわです。

これまでTECH BLOGでは、技術戦略部のメンバーがエンジニアならではの情報を発信してきましたが、
今回はテクニカルな内容から少し離れ、デザイン制作部の仕事内容を紹介させていただきます。


◆デザイン制作部とは?
 
目的に応じて、何を、どこに、どのように配置するべきかを考え、ページデザインと
HTML/CSSコーディングを行う部門です。

・わかりやすさ、使いやすさ(ユーザビリティー、アクセシビリティ)の追求
・ページから与えられる印象の形成
・サイト内のデザイン統一
・コーディング品質の向上

を担っています。


◆作業フロー
 
1.要望があがる
  要望箱という社内掲示板に、他の部署や同じ部署のメンバーから実現したいことが書かれます。
  具体的な実現手段が指定されているケースもあれば、大雑把に目的だけが示されている場合も
  あります。

写真1(要望)

2.実現手段をすり合わせる
  社内会議やメール、要望箱掲示板などを通して、どのような画面が必要なのかを依頼者と、
  制作担当者とですり合わせます。

3.実施判断
  依頼内容に応じて、ドメイン責任者による承認ステップを踏みます。
  また法務に抵触する内容がないか、法務担当への確認も、このタイミングで行います。

4.制作
  印刷物のデザインやバナー、新規ページ、メールフォームなど対応内容は様々。
  コーディングはHTMLファイルで行うこともあれば、JSPファイルで行うこともあります。
  メールフォームを作る際は、社内に用意されている、汎用的に使えるメールフォームの
  システムを使い、複雑な仕様でなければ、開発者なしで制作できるようになっています。
  【使用するソフト】
  IllustratorCS5、PhotoshopCS5、Dreamweaver、Eclipse、サクラエディタ、WinMerge など
  
5.最終チェック
  デザインはそれぞれの好みに左右されることが多いため、
  サイト全体から見たそのページの印象、統一感などを含め、第三者目線での判断を入れます。
  これは各ドメインの最終チェック者が担当します。
  
6.依頼者確認
  できあがったものを依頼者に確認してもらいます。
  
7.QA
  部内で品質をチェックをします。
  QA担当者は、制作物に問題がないかを専用のチェックシートに沿って確認します。
  【確認ポイント】
  ・ページ内容
  ・フォーム等の挙動
  ・ブラウザ互換
  ・HTMLバリデーション
  ・JavaScriptの動作
                                  など
  メンバーごとに固有のローカルIPでページを確認できるようになっており、Hostsファイルを
  書き換えて確認しています。
  システムが絡む案件の場合は、技術戦略部と協力し、品質を担保することもあります。
  
8.本番アップ~反映確認


◆活用しているツールなど
 
部内Wiki
   作業の引継ぎや共有がスムーズに行えるよう、作業マニュアルをWikiで管理しています。

UIガイドライン
  デザイン統一化のためにドメインごとにUIガイドラインを用意しています。
  HTMLファイルで作成しており、ソースのコピペができるようになっているため、作業の効率化
  にも役立っています。

写真2(ガイドライン)
  
 Windows Virtual PC
  ブラウザ互換のチェックをするために利用しています。

Google Analytics
  制作したページの効果を検証したり、改善提案を行う際の調査に活用しています。

Firefox各種アドオン
  「FireBug」・・・Webデバッグツール
  「Html Validator」・・・表示中のページにHTMLのエラーがないかを検証する
  「SwitchHosts」・・・hostsの切り替えを行う
  「Popup ALT Attributes」・・・Firefox上からaltの内容を確認する
  「ColorZilla」・・・表示しているページ内から色情報を取得する
  「Firesizer」・・・ウィンドウの表示サイズの切り替えを行う

※スペースの都合上、詳細は割愛させていただきました。
   「活用しているツールなど」については、後日また改めてご紹介いたします!


◆まとめ

ラクーンでは企画~リリースまでにいくつものチェックがあります。
そのために、案件の対応に時間がかかってしまうこともありますが、
「品質を最優先して案件に臨める環境」が整っていると感じています。

以上、「デザイン制作部の仕事内容について」でした。

写真3(デザイン制作部)
 新しい仲間を募集中です☆

Google Analytics (other)対策

こんにちは!名前だけ編集長をやっている羽山です。

弊社では無料で利用できるアクセス解析ツールのGoogle Analyticsを利用しています。
今回は大規模サイトで問題になる(other)について一般的な対策から裏技的な方法までご紹介します。

(other)とは
Google Analyticsが一意のURLとして1日に認識できるのは50,000URLまでです。それを超えた場合、ページビューの低いURLから優先的に(other)というURLに変化してしまいます。
5万と聞くと十分な数に思えますが、弊社の運営するスーパーデリバリーでは30万点超の商品があり、それに商品一覧のページが加わると果てしない数のURLになります。 

弊社で実施している3つの対策
1. 50,000URLに収まるようにフィルタ設定してプロファイルを分割する
Analyticsのヘルプにも記載してある最も一般的な対策です。
ヘルプによると高トラフィックのページビューをフィルタで削除することによって50,000URLに抑えなさい。となっています。

完全に分離されたいくつかのセグメントがあるならば、それぞれプロファイルを作成してAnalyticsが公式にオススメする方法に従えば問題ありません。しかしそういったセグメントがないのなら情報が各プロファイルに分離してしまうので全体のセッション数やページビューなどをつかみづらくなります。

そこで弊社ではいくつかのページを同一のページとして書き換えることによってURL数を減らしています。
この方法ではセッション数やページビューには影響が出ないため、対象のURL自体を解析したい場合以外は特に意識せずに利用できるというメリットがあります。

スーパーデリバリーの例では商品詳細ページのURLが多数を占めていました。
そこでプロファイルを3つに分けるという対策をとっています。
  • (a) フィルタなしプロファイル
  • (b) 商品詳細ページのURLをすべて1つのURLにまとめたプロファイル
  • (c) 商品詳細ページ以外のURLをすべて削除したプロファイル
(b)の設定は下記のようになっています。
カスタムフィルタ、詳細
フィールド A -> 引用 A: リクエストURI, ^/p/r/pd_p/[0-9]+/
フィールド B -> 引用 B: -
出力先 -> 構成: リクエストURI, /p/r/pd_p/0000000/
出力フィールドを上書き: はい
この例では下記のようにURLが変化します。

(置き換え前)
http://www.superdelivery.com/p/r/pd_p/1234567/

(置き換え後)
http://www.superdelivery.com/p/r/pd_p/0000000/
 
通常の解析では(b)のプロファイルを利用して、商品詳細を解析したい場合は(c)を使います。
(a)はこの後に出てくるアドバンスセグメントを利用した方法やReporting APIを利用してデータを抽出する場合に利用しています。


2. 直近の数値を見る
実は50,000URLの制限は前々日以前のデータにのみ適用されます。
例えば今日が7月30日だとして、7月29日のデータを閲覧する場合は50,000URLを超えたデータを閲覧可能です。ただし、直近のデータの閲覧については保証されていない場合もある点は注意が必要です。


3. アドバンスセグメントを利用する
Analyticsの内部データとしては50,000URLに制限せずに保持されています。
50,000URLに制限されるのはAnalytics側である程度集計されたパターンの解析を行う場合に適用されます。
その枠を超えて動的な解析が必要な操作を行うと元データから解析されるため、50,000URLを超えたデータを閲覧できます。

早速試してみます。
下記のようなアドバンスセグメントを作成します。
名前: すべて
一致, ページ, 正規表現一致として、テキストボックスに . (ドット) 一文字を入力
すべてのページに一致する条件なので、セッションは一切絞り込まれない素通しのアドバンスセグメントです。

作成したら早速そのアドバンスセグメントを適用してデータを見ると (other) がなくなり、すべてのデータが表示されます。ただし、アドバンスセグメントではデータの件数によってはサンプリングされることがあるので、その場合は期間を短くするか[データ精度を優先]する設定に変更して下さい。


弊社では上記3つの方法を組み合わせて50,000URLの制限とうまく付き合っています。
他にもPreminumを利用するという方法もありますが、それなりに高価なので現時点では採用していません。

以上、今回はAnalyticsの話題でした。また次回よろしくお願いします!
記事検索