[Javascript] Saasサービスにおけるonload対応

2016年8月18日

Javascript テクノロジー プログラミング

Saas(ASP)サービスにおいて、外部ドメイン(サイト)に置いてあるライブラリJSサービスを起動する場合、JavaScriptタグをHTMLソースに記述する方法でサービス導入を行いますが、この手のASPサービスでは、いくつも問題が発生するリスクがあります。 実際に僕もSaasサービス提供を10年ぐらい行なってきて、体験した事をまとめておきたいと思います。

Saasサービスの種類と利点

Saasサービスは、WEBページに機能追加を行うのが非常に用意に行うことができる便利なサービスとして、今現在でも成り立っている有用なビジネスです。 企業のWEBページでは、顧客に対しての情報提供や商品提供を目的にしている為、マーケティング機能などは二の次で追加開発を行う場合がほとんどです。 具体的には「EFO」のような、入力ページの利便性について、動的にメッセージを出したり、ページ遷移をした先で離脱を防止するような仕組みは、それだけで開発費が数百万円というレベルで膨らんできます。 Saasサービスを利用すると、月額数万円程度で利用できるため、数年ぐらいは、費用対効果よく運用できるので、新規サイト立ち上げの場合にSaasを導入して、効果を計測する会社さんが多いようです。 でも、その後、自社開発して、外部サービスを切ってしまう事もあるので、解約防止を一生懸命行わないといけないんですが・・・ こうしたサービスはEFOの他にも、アフェリエイトや、各種データ保持するサービスなどのように、多様性が出てきています。 きっと自社サービスをするよりは、Saasとして利用した方が、移り変わりの早いスマートフォンなどの対応などは、サービス会社にまかせておいたほうが無難でしょうね。

サービスの裏にある問題

世の中で一番埋め込まれているASPサービスは、おそらく「GoogleAnalytics」ではないかと思いますが、一般企業であれば、だいたい、どこのWEBページでも、GAタグが入っているのを見ることができます。 これは、WEBページのソースコードを見ると誰でも確認できるので分かりやすいですよね。 そして、GAはSCRIPTタグと起動や設定などをガッツリ記述して行うのですが、不具合が起きても、ほぼ無料で利用しているため、よほどの不具合でないかぎり、設置している企業側に責任があるという認識です。 実際にあまり問題が出たことがないので、さほど気にしている企業もないようです。

一般的なSaasサービスの構成

多くのSaasサービスは、そのWEBページが起動した後で実行される事が多いため、WEBページのすべての要素が呼び込まれた事の後で起動できるように「onload」イベントと連動してサービス起動するケースが多いようです。 ※もちろん、onloadイベントに依存せずに起動できるサービスもありますが、WEBページないの特定要素を判定するような場合はonloadは必要ですね。

onload問題

onloadイベントに依存するとどのような問題は発生するんでしょう?
・WEBページの後に読み込まれるため、サービスの起動が遅くなる。 ・document.write関数を利用するとWEBページ事態を上書きしてりまうリスクが発生する。 ・他社のタグマネージャーを利用している場合、onloadイベントを利用できなくなるケースがある。
10年ぐらい前であれば、Saasサービスの数も少なく、JavaScriptもサービスとしてはまだ市民権を得ていないぐらいの環境だったのに対して、今現在では、jQueryが当たり前のように利用され、ECMAscriptのバージョンもアップし、JavaScriptを使って高度なWEBページを簡単に作れるフレームワークも多数出てきています。 そんな中、Saasサービスは、色々なコンフリクトの危険も出てきているという事なんですね。

対応するべき内容

リスクは承知の上だが、Saasサービスはやはり便利なため、利用する企業も多い、Saasサービスの為に自社WEBページの仕様をローレベルにする会社も少なくないようです。 そんな中、Saasサービスはいつまでもonloadイベントにしがみついていてはダメで、「readyState」でdocument.bodyやサービス事態のscriptタグの読み込み完了を確認して、既に完了していると判断されるのであれば、即座にサービスを起動するような処理を冒頭に書くことで、読み込みタイミングが測れないタグマネージャーなどにも対応することができるようになるはずです。 簡単なソースコードを用意しておいたので、是非Saas提供する側の人は活用してください。

ソースコード

//読み込み完了フラグ var loaded = false; //スクリプト追加 var script = doc.createElement("script"); script.type = "text/javascript"; script.src = "http://hoge.com/service.js"; //onload処理 script.onload = function() { if (!loaded) { loaded = true; //サービス起動 proc(); $$capFunc.pazzLoaded(element); } }; //readystate処理 script.onreadystatechange = function() { if (!loaded) { switch (script.readyState) { case "loaded": case "complete": loaded = true; //サービス起動 proc(); break; } } }; //headタグに追記 var head = doc.getElementsByTagName("head")[0] || doc.documentElement; head.appendChild(script);

解説

このソースコードは、webページに貼られたサービス用のscriptタグから読み込まれるJSファイルに記述して、別のライブラリモジュールを読み込む処理や、サービス開始の関数を実行するタイミングを処理するプログラムになっている。

loadedフラグ

まず冒頭の「var loaded=false;」により、loaded変数がfalseの場合を読みこまれていないという判定を行うことにしている。 読み込み完了の時にtrueを書き込んでいるのは、意味が無い処理にも見られるが、他にもいくつかの読み込みを行う場合に変数名を変えて便利に使えるはずである。

onreadystatechange

「onreadystatechange」はあまり使われないイベントだが、非常に便利に使えるので、これを気に覚えてもらいたい。 何故ならonload処理のみで実行する場合、フラグを利用して読み込み完了を行なってもいいが、読み込みが完了した後でscriptが貼り付けられるような設置をされた場合に、onloadイベントは実行されないのである。 なので、上記のソースコード以外でもイベント関数外に読み込まれたらすぐにいま現状のreadystateの値を取得して、その後、イベントやonchangeを利用して、値の確認をする必要がある。 readystateはIE6でも使えるぐらい古いブラウザ対応ができるので、今現在のブラウザではほぼ問題なく使える値だ。 こうしたブラウザの値をちゃんと利用して堅牢なシステムを構築しなくてはいけないね。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。