Help us understand the problem. What is going on with this article?

JavaScript/jQuery の処理の実施タイミングの切り分けを示す例を書いてみた

More than 1 year has passed since last update.

突っ込みどころ満載な内容ですが・・・。

処理実施のタイミングが気になった。

(jQueryを含む)JavaScriptを使ったコードはよく、$(document).ready(function({ (中略) }); みたいな中に記載して、ページを操作しても良いレンダリング終了後に有効化させるケースが多いですが・・・。処理の中には、レンダリング中に実施してもよいものもあると思って。

JSで処理する内容を、適した時期ごとに分けてみた。

  1. DBからデータ取得など、レンダリングとは直接関係ない処理。
  2. タグ埋め込みなど、終わったときに実施する処理。
  3. バリデーションなど、操作・変化を検知したときに行う処理。
  4. 時刻表示など、ページ表示中定期的に動く処理。

1のようなタイプの処理は、先にAjaxで取得のリクエストを送信、非同期にデータを受け取り、レンダリング終了後に所定の位置に埋め込むような使い方もできるかな?と思ったり。

単純化したコードを書いてみて 動かしてみた。

事象を単純化し以下のファイルを用意する。

  1. レンダリングされたページ代わりのHTMLファイル
  2. カプセル化したい処理をまとめたクラスを記載したJSファイル
  3. 2の中にあるクラスを呼び出す記載をしたJSファイル

ソース

ページのHTML
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" src="read1.js"></script>
<script type="text/javascript" src="read2.js"></script>
</head>
<body>
<h1>実際の運用環境ではもっと多いHTMLコードがあるので、レンダリングに時間がかかる</h1>
</body>
</html>

1に相当する。こんな感じのHTMLをレンダリングすることは多々あるはず。

read1.js(クラスが書いてあるほう)
console.log("read read1.js");

console.log("/*クラスとして作りたいもの*/");

var someClass = function(msg="someClass"){


    console.log("/*someClassのコンストラクタが処理される*/");
    var instance_var = "instance param";
    console.log("new Instance "+msg);

    this.readInstansVar = function(){
    console.log("read method");
        return instance_var;
    }

    $(document).ready(function(){
        console.log("Rendering is end");
    });

}

2に相当する。コンストラクタに相当するもの、クラスメソッドに相当するもの、
HTMLレンダリング実施後に行う処理に分けた。

read2.js(クラスを呼び出すほう)
console.log("read read2.js");


console.log("/*先に、レンダリング終了時に処理する内容を記載する。*/");

$(document).ready(function(){
    console.log("Docuent Ready at read2");
});
console.log("/*インスタンスを生成して、処理する*/");

var ins = new someClass("read2");
var ret = ins.readInstansVar();
console.log(ret);

3に相当する。わざと2のスクリプトファイルインスタンス生成より前に、レンダリング終了後に実施する処理を先に書いている。

実施結果

console.log
read1.js:2 read read1.js
read1.js:4 /*クラスとして作りたいもの*/
read2.js:2 read read2.js
read2.js:5 /*先に、レンダリング終了時に処理する内容を記載する。*/
read2.js:10 /*インスタンスを生成して、処理する*/
read1.js:9 /*someClassのコンストラクタが処理される*/
read1.js:11 new Instance read2
read1.js:14 read method
read2.js:14 instance param
read2.js:8 Docuent Ready at read2
read1.js:19 Rendering is end

処理を追っていくと

  1. 「先」のファイルの地の部分が実行される。
  2. 「後」の地の部分が実行され、先の方のクラスのインスタンスを生成する。
  3. 「後」インスタンス生成と同時に、「先」のコンストラクタが実行される。
  4. 「先」メソッドを呼び出し、回答を取得する。
  5. レンダリングが終了し、「後」、「先」の順に(document).readyの中身を実施する。

といった流れ。

考察~レンダリング終了前後が重要?

  1. レンダリングが終わる前に、データ取得のAjaxなどを呼び出す。
  2. レンダリング終了時に、1.の結果を取得する・・・が、まだ取得できていなかったり、エラーが発生したときのことも考慮すること。

参考

JavaScriptの同期、非同期、コールバック、プロミス辺りを整理してみる
https://qiita.com/YoshikiNakamura/items/732ded26c85a7f771a27

m-shin1
フリーランス サーバサイドの処理をメインにやってます。 Ruby、PHP、JSなどを使ってます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした