質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.36%

  • JavaScript

    11205questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • React.js

    376questions

    A JavaScript library for building user interfaces

  • Firebase

    197questions

    Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

javascriptで軽量化とは一般にどのような方法があり、どのような処理が重いのでしょうか?

解決済

回答 4

投稿 2017/11/24 10:19 ・編集 2017/11/25 03:07

  • 評価
  • クリップ 0
  • VIEW 229

MOTOMUR

score -31

現在こちらのサイトを自作しています。
<Github>

はじめに

(初期の質問文が修正依頼のようであるという誤解を多数いただいたので、質問内容を修正させていただきました。
不完全なところありましたらおしらせください。)
今回人生初の自作のサイトで、処理が重くなってしまい、軽量化が初めての経験だったため、前例を得るべく、勉強のために質問させていただきました。

何を求めているのか?

経験談を聞きたいのです。

>サイトを作成したことのある方に質問します。
今まで、サイト作成の途中で作っているサイトが重たくなってしまった経験がある方もいると思うのですが、その時の原因と対処をどのようにしましたでしょうか?

(プログラマとして歴が浅い時のミスによるものやプログラマとして成長した段階でもよくつまづいてしまうことなどの失敗談などによって、自分の今回のサイトの修正の参考になるだけでなく、
他の駆け出しの方の今後の重たくなった時の考える指針になればいいと思っています。)

自分はこれが初めてのコーディングであり、重くなったことの対処法や原因の例が足りなくアイディアが足りないため、質問させていただきました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • defghi1977

    2017/11/25 08:07

    とりあえず「動いている」ものが作れたのはあなたの実力なのだから, 卑屈になる必要はないよ. でも, アプリ軽量化のテーマはプログラミング界永遠のテーマであって, 一介の質問サイトで答えられる範疇のものではない. なので, 一冊関連する書籍を購入して熟読してみたら如何でしょう?絶対に役に立つから.

    キャンセル

  • 退会済みユーザー

    2017/11/26 09:40

    複数のユーザーから「問題・課題が含まれていない質問」という意見がありました
    teratailでは、漠然とした興味から票を募るような質問や、意見の主張をすることを目的とした投稿は推奨していません。
    「編集」ボタンから編集を行い、質問の意図や解決したい課題を明確に記述していただくと回答が得られやすくなります。

  • 退会済みユーザー

    2017/11/26 09:45

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 4

+9

ボトルネックを探してくれ、原因はどこかわからないから全部見てくれ、というのはクラウドソーシングへ依頼お願いします。

ご自分で原因を絞り込むのであれば、お使いのブラウザの開発者ツール等で「Performance」とか「Profile」とかいう項目があると思いますので、そちらで検証してください。

投稿 2017/11/24 10:58

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/25 02:22

    質問後今質問への反応を見にきたのですが、少数の批判があり面を食らってしまいました。汗

    ある程度の方々に不快な思いをさせたようですのでここで謝罪させていただきます。未熟者でして、どのような質問の仕方が適切かの判断に問題があったことはここで謝罪させていただきます。すいません。

    しかし、問題を丸投げするための意図があってこのような質問の形を取ってしまったわけではないので、今後は誤解のない質問を心がけたいと思います。
    今回の場合は、「サイトやgitを挙げてどこが重たいのでしょうか?」という質問の仕方が誤解を生んだのだと推測します。語彙力がない質問をしてしまった理由、経緯について私ごとですが弁解の機会をもらってもいいでしょうか?もちろん弁解がいらない方はブラウザバックお願いします。

    僕の経歴について、説明した方が今回のような状況に至った経緯がわかりやすいと思うので、説明させていただきます。自分は、プログラミングを志して早2ヶ月が経とうとしていますが、作成することのみを目標に勉強を疎かにしてきたため、専門的にプログラミングをしている方たちには到底追いつけないような未熟のプログラマになってしまっています。


    なので専門知識がない語彙力で質問を改めさせていただきますが、

    「javascriptで軽量化とは一般にどのような方法があり、どのような処理が重いのか」
    という質問の内容が私の意図した質問内容です。

    どのようにフレームワークを使うのかといった知識のみに特化し勉強してきましたし、英語もやや自信がなく、根本的な説明を見つけられなかったため、こちらに質問させていただきました。

    若輩者のわがままではありますが、こちらの経緯をご理解の上、ご好意で答えてくださる方がいれば幸いだと思います。

    もう一度質問内容を改めさせていただきますが、
    「javascriptで軽量化とは一般にどのような方法があり、一般にどのような処理が重いのでしょうか?」

    キャンセル

  • 2017/11/25 16:31

    自分勝手な言い分だなあ。
    批判してるのは少数ではないですよ。
    というか、ほとんどの人が批判すらせず無視しているんですよ。
    なぜあなたのスコアがマイナスなのかよく考えてみてはどうでしょうか。

    キャンセル

  • 2017/11/26 18:04

    批判よりも対案の方が前向きなんじゃないかな…。
    個人的にはstackoverflowでいう「範囲が広すぎる」が該当すると思いました。
    https://ja.stackoverflow.com/help/closed-questions

    キャンセル

  • 2017/11/27 09:24 編集

    私が追加で回答するまえにベストアンサーで解決されたようでよかったです。

    私が思うに、大量のマイナス評価はプログラミングや質問の「姿勢」の問題でしょう。例えば今回の件では「遅くなる原因がわからない」を聞くのではなく「遅い原因を調べる方法、コツ」を聞くと皆喜々として答えたでしょう。自分で解決するためのヒントの要求ではなく、他人に解決してもらうための要求だったことが多くの人の反感を買ったのだと思います。もちろんどうしても自分には解決できない問題にぶち当たったとき、答えを求めるのは悪いことではありません。私も何度もわからないことを聞きました。しかし、大抵疑問を言葉に変えて整理したら自己解決してしまったパターンでした。わからないことをまとめたとき、解決への糸口が見つかることがよくあります。わからないことがなんなのか、を突き詰めるということがエンジニアとしての成長の一歩です。がんばってください。

    キャンセル

checkベストアンサー

+7

 一般的な高速化(軽量化)の手法

JavaScriptの高速化(軽量化)の手法は多岐にわたる為、一般的に「これだけやればOK」な解はありません。
大雑把にいえば、次の2つに大別されます。

  • スペックを上げる
  • 無駄をなくす

ここから更に細かく分別していくと、書ききれない量になるので、「もう少し具体的なところまで切り分けて下さい」と多くの方から指摘されているのだと思います。
いくつか例を挙げると、次のようになります。

  • クライアントPCのスペックを上げる(スペックを上げる)
  • サーバマシンのスペックを上げる(スペックを上げる)
  • 回線速度を増強する(スペックを上げる)
  • html/css/jsファイルを圧縮(minified)する
  • HTTPサーバ(Apache等)のgzip圧縮を使う
  • jsファイルのHTTPリクエスト数を減らす(jsファイルを一つにまとめる)
  • script[defer], script[async]
  • script要素を </body> 手前に置く(レンダリング停止の影響範囲を下げる)
  • ビルトイン関数を含めたアルゴリズム、コード上のアルゴリズムを書きだして、アルゴリズム上の無駄をなくす
  • リフロー/リペイント回数を減らす(アルゴリズム上の無駄をなくす)
  • スコープチェーンを辿る回数を減らす(アルゴリズム上の無駄をなくす)
  • プロトタイプチェーンを辿る回数を減らす(アルゴリズム上の無駄をなくす)
  • 同一プロパティの参照回数を減らす(アルゴリズム上の無駄をなくす)
  • 無駄にクロージャを生産しない(アルゴリズム上の無駄をなくす)
  • 無駄に形式変換しない(アルゴリズム上の無駄をなくす)
  • 無駄に同一オブジェクトを何度も生産しない(アルゴリズム上の無駄をなくす)
  • 実装(ブラウザ)の最適化に合わせる

上から3つ目までが「スペックを上げる」、4つ目以降が「無駄をなくす」です。

 抽象的な高速化系の質問

経験上、高速化系統の質問は、質問が抽象的であるほどに不毛な結果に終わる傾向があります。
初心者は「難しすぎて分かりません」と答え、熟練者は「Aは高速ですが、保守性が悪いのでBを採用しますね」のように高速化以外の判断基準で切り捨てられることが多いです。
高速化は突き詰めると、密結合になる為、保守性を重視する人には敬遠される傾向にあります。
例えば、下記スレッドですが、

私は高速化を極限まで追求した為、限界まで密結合し、最大限の結果を得られました(著しく速くなりました)。
蜜結合とは、つまり、「関数 createSquareAa()」は単一の関数であり、複数の関数では構成されていません。
(対する疎結合では、処理が分割されている都合上、アルゴリズム上の無駄をなくすのにも限界があります。)
このコードを「可読性が悪い」が評価する人がいれば、「これぐらいなら読める」と評価する人もいるでしょう。
その人にとって「最低限これぐらいの規模なら読める」という処理上の「最小限の単位」が異なる為、人によって蜜結合/疎結合のバランスの度合いも変わってきます。
高速化と保守性はトレードオフの関係にあるので、絶対的な基準を作るのは難しいと私は思います。

なので、高速化系の質問であっても、それ以外のコーディング上のポリシーを質問文に添えてほしいと良く思います。
熟練者であるほど、拘りがあるので、ポリシーが書かれているだけで無駄に回答せずにすみます。
(関係ない話ですが、qiitaでの「jQuery vs 仮想DOM」の質問への回答も未だに悩んでます。高速化以外での拘りが相当あるような気がします。)

Re: MOTOMUR さん

投稿 2017/11/25 11:56

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+7

軽量化の第一歩はボトルネックを死ぬ気で探すこと。
console.timeとconsole.timeEndを埋め込みまくったり、
短いコードを100万回走らせたりしてみて記録をとりつつ覚えよう。

まず、整数の変数を宣言する時は$a = $b|0;のように縦棒0を付けた方が若干速いとか、
インクリメント($i++)より足したほうが速い($i += 1;)とか、
細々したテクニックは全体何十秒もかかるようなクソコードの前では全く意味がない。
ボトルネックを全て潰し終わった後に、全体10msで終わる処理を9.9msにしたい時にチューニングの時に初めて威力を発揮するから今回は採用すべきではないね。

以下は鉄則

  • ループ回数は最小限
  • DOMはできれば触るな、避けて通れないなら最小限
  • 重い計算は何度もせずに変数に一時保存

Reactに限っては以下も追加

  • JSの比較の仕様を覚える

以下1つずつ解説


ループ回数は最小限というのは特に配列操作で一番大事な鉄則
例えば100個の配列と50個の配列を普通に掛け算すれば100*50=5000回の演算になるけど、
少しの工夫で100+50=150回の演算に出来る。

例として、ユーザー一覧配列では県コード、県一覧配列の2つがあり、ユーザーの一覧を表示する時に都道府県名で表示したいケースを考える

const users = [
  {name: "taro", pref: 1},
  {name: "juro", pref: 13},
  // ...こういうデータが100件
];
const prefs = [
  {id: 1, name: "北海道"},
  {id: 13, name: "東京都"},
  // ...こういうデータが都道府県分
];
let usersWithPref;

// 100 * 50になるパターン
usersWithPref = users.map(user => {
  const pref = prefs.find(pref => user.pref === prefs.id);
  return {...user, prefName: pref.name};
});

// 100 + 50になるパターン
let prefById = {}; // わかりやすさ重視でreduceを使わない方法にした
prefs.forEach(pref => prefById[pref.id] = pref.name);
usersWithPref = users.map(user => {
  const pref = prefById[user.pref];
  return {...user, prefName: pref.name};
});

実際にはArray.findは条件に合致した要素を発見次第探索を打ち切るので、
1ユーザー平均20回程度の確認で終了すると思われるが、もし複雑な計算をした結果得られる情報を元に比較検証しなければならないとしたら大惨事だ。
最初のキャッシュを47ループ分のコストを使って作っておいたお陰で、userが都道府県名を取り出すコストはほぼ0になり、約2000回の計算はわずか150回に……この差は結構でかい。

2つ目のDOMを触るなっていうのは、単純にGUIへのレンダリングはコストがデカいから。
ループ文で少しずつ変更するんじゃなくて、全てのデータが揃ってから一撃で変えた方が良い。

3ツ目の変数へのキャッシュも分かりやすいと思うので割愛。


Reactは賢く値が変更されたか変更されていないかで再描画をするしないを決める。
値が変更されたって何が基準?基準は===
(仕様をちゃんと見たわけではないけど、そのように見える)

JavaScriptはプリミティブ型とそれ以外では===で比較した時の結果が違う。
ちょっと下記のコードをコンソール開いて打ち込んでみよう。
そして、思った通りの結果になるか確かめて欲しい。

1 === 1;
"test" === "test";
true === true;
[1, 2, 3] === [1, 2, 3];
{test: 1} === {test: 1};
(it => it + 1) === (it => it + 1);

例えばPHPでは[1, 2, 3] === [1, 2, 3]はtrueと評価されるが、JSではfalseになってしまう。
JSの世界ではFunctionやArray、Objectといったものは、
作成される度に見えない管理IDが割り振られ、比較すると管理IDを基準に同一の存在か否かでtrue/falseが決定される。

ReactではPropの値が変わらなければ再描画はされない。
しかしJSの比較演算子の仕様の問題で、毎回Propの中でオブジェクトや配列を生成していると、同じものとみなされる事はない。
常に再描画でDOM作り直しになる可能性があり、それが全てのコンポーネントで発生していれば、Reactの賢い部分的な再描画という特性は全く活かせない。

このように同じものとして認識してほしければ変数等に代入して束縛しておこう。

var a = {test: 1};
a === a; // true

投稿 2017/11/25 13:40

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

「このようなコードで、このように表現したいけど表現できない。何故なのか?」
と言うような時の場であるので、質問者さんの悩みも分かりますが、ここでは無い気がします。

自分なりに思うのは「無駄な記述(コード等)をしない」だと思います。「A」を表現するのに10のコードで書いたものを7や8、あるいは5で納めることでしょうか。(圧縮等は前提です。)

何が必要で何が不要なのかを選択するには質問者さんの知識・経験等が不可欠となり、それを得るのがこれからの課題だと思います。頑張ってください。

投稿 2017/11/25 06:37

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • JavaScript

    11205questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • React.js

    376questions

    A JavaScript library for building user interfaces

  • Firebase

    197questions

    Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。