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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Firebase

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

JavaScript

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

4回答

2860閲覧

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

MOTOMUR

総合スコア195

Firebase

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

JavaScript

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2017/11/24 01:19

編集2017/11/24 18:07

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

はじめに

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

何を求めているのか?

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

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi-sun

2017/11/24 02:31

適当に作ってたものを、何処が悪いのか検討もつかないからリファクタリングしてくださいってのがいい感じに闇が深いね。
defghi1977

2017/11/24 23:07

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

回答4

0

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

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

投稿2017/11/24 01:58

masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MOTOMUR

2017/11/24 17:22

質問後今質問への反応を見にきたのですが、少数の批判があり面を食らってしまいました。汗 ある程度の方々に不快な思いをさせたようですのでここで謝罪させていただきます。未熟者でして、どのような質問の仕方が適切かの判断に問題があったことはここで謝罪させていただきます。すいません。 しかし、問題を丸投げするための意図があってこのような質問の形を取ってしまったわけではないので、今後は誤解のない質問を心がけたいと思います。 今回の場合は、「サイトやgitを挙げてどこが重たいのでしょうか?」という質問の仕方が誤解を生んだのだと推測します。語彙力がない質問をしてしまった理由、経緯について私ごとですが弁解の機会をもらってもいいでしょうか?もちろん弁解がいらない方はブラウザバックお願いします。 僕の経歴について、説明した方が今回のような状況に至った経緯がわかりやすいと思うので、説明させていただきます。自分は、プログラミングを志して早2ヶ月が経とうとしていますが、作成することのみを目標に勉強を疎かにしてきたため、専門的にプログラミングをしている方たちには到底追いつけないような未熟のプログラマになってしまっています。 なので専門知識がない語彙力で質問を改めさせていただきますが、 「javascriptで軽量化とは一般にどのような方法があり、どのような処理が重いのか」 という質問の内容が私の意図した質問内容です。 どのようにフレームワークを使うのかといった知識のみに特化し勉強してきましたし、英語もやや自信がなく、根本的な説明を見つけられなかったため、こちらに質問させていただきました。 若輩者のわがままではありますが、こちらの経緯をご理解の上、ご好意で答えてくださる方がいれば幸いだと思います。 もう一度質問内容を改めさせていただきますが、 「javascriptで軽量化とは一般にどのような方法があり、一般にどのような処理が重いのでしょうか?」
ooeok

2017/11/25 07:31

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

2017/11/27 00:24 編集

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

0

軽量化の第一歩はボトルネックを死ぬ気で探すこと。
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つがあり、ユーザーの一覧を表示する時に都道府県名で表示したいケースを考える

JavaScript

1const users = [ 2 {name: "taro", pref: 1}, 3 {name: "juro", pref: 13}, 4 // ...こういうデータが100件 5]; 6const prefs = [ 7 {id: 1, name: "北海道"}, 8 {id: 13, name: "東京都"}, 9 // ...こういうデータが都道府県分 10]; 11let usersWithPref; 12 13// 100 * 50になるパターン 14usersWithPref = users.map(user => { 15 const pref = prefs.find(pref => user.pref === prefs.id); 16 return {...user, prefName: pref.name}; 17}); 18 19// 100 + 50になるパターン 20let prefById = {}; // わかりやすさ重視でreduceを使わない方法にした 21prefs.forEach(pref => prefById[pref.id] = pref.name); 22usersWithPref = users.map(user => { 23 const pref = prefById[user.pref]; 24 return {...user, prefName: pref.name}; 25});

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

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

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


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

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

JavaScript

11 === 1; 2"test" === "test"; 3true === true; 4[1, 2, 3] === [1, 2, 3]; 5{test: 1} === {test: 1}; 6(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の賢い部分的な再描画という特性は全く活かせない。

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

JavaScript

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

投稿2017/11/25 04:40

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

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

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 02:56

think49

総合スコア18156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

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

投稿2017/11/24 21:37

yoshinavi

総合スコア3521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問