Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
JavaScriptの便利な構文に潜む罠
Search
kentaro ishida
October 10, 2025
Programming
25
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JavaScriptの便利な構文に潜む罠
kentaro ishida
October 10, 2025
More Decks by kentaro ishida
See All by kentaro ishida
UXから考えるクライアントサイドのパフォーマンス監視設計
ishida2002
0
44
Storybookのインタラクションテストで UIの仕様をテストする
ishida2002
0
36
Renovateを(できるだけ)ノールックマージする
ishida2002
0
20
Other Decks in Programming
See All in Programming
IBM Bob でAI駆動開発『QC-Playbook』
ichirokano2
0
110
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
180
npm との違いを手がかりにGo の依存管理を理解したい
optim
0
300
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
380
PumaからFalconに移行したRailsアプリケーションでの実践
falcon8823
0
170
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.9k
JIS keyboard support in Omarchy
lef237
0
110
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
150
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
1k
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
170
Simple Storage Service(S3) is not simple
iwatsukayura
0
290
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
750
Featured
See All Featured
ラッコキーワード サービス紹介資料
rakko
1
5.3M
Crafting Experiences
bethany
1
380
We Are The Robots
honzajavorek
0
400
Building the Perfect Custom Keyboard
takai
2
910
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
1
280
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
430
Between Models and Reality
mayunak
4
500
Test your architecture with Archunit
thirion
2
2.4k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
340
Building Flexible Design Systems
yeseniaperezcruz
330
41k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3.1k
Transcript
JavaScriptの便利な構文に潜む罠 石田 健太郎 2025年10月10日
自己紹介 石田 健太郎(いしだ けんたろう) 株式会社kubell 新卒2年目のフロントエンドエンジニア 「Chatwork」のブラウザ版・デスクトップ版の開発 を担当 学生時代は競技プログラミングをやってました パフォーマンス改善とかが好きです
今日はパフォーマンス改善について話します
便利構文と罠
スプレッド構文、使ってますか?
スプレッド構文 配列やオブジェクトを展開する構文 Object.assign() や Array.prototype.concat() 相当の処理を簡潔に記述できる const obj = {
a: 'foo' }; const newObj = { ...obj, b: 'bar' }; console.log(newObj); // { a: "foo", b: "bar" } const arr = [1, 2, 3]; const newArr = [...arr, 4, 5]; console.log(newArr); // [1, 2, 3, 4, 5]
便利ですねー
さて、こんなコードがあります
問題のコード よくあるAPIからのレスポンスを整形しているコード 別にいいんじゃないの? const rooms = Object.entries(response.room_dat).reduce( (accumulator, [roomId, room])
=> { // 処理 return { ...accumulator, [roomId]: formattedRoom }; }, {}, );
スプレッド構文についてもう少し深掘り
スプレッド構文 スプレッド構文は1段階のシャローコピーを生成する ネストしたオブジェクトでなければ書き換えても影響が無いので便利 const obj = { a: 'foo', b:
{ c: 'bar' } }; const newObj = { ...obj }; newObj.a = 123; newObj.b.c = 456; console.log(obj.a); // foo console.log(obj.b.c); // 456
ここに落とし穴
スプレッド構文の落とし穴 コピーを生成するということは、コピーする要素数に応じた処理が必要になる オーダー記法で O(N) と表記される const obj = { a:
'foo', b: { c: 'bar' } }; const newObj = { ...obj }; // obj の要素数に応じた処理が必要 newObj.a = 123; newObj.b.c = 456; console.log(obj.a); // foo console.log(obj.b.c); // 456
問題のコード(再掲)
問題のコード reduce の中で accumulator をスプレッド構文で展開している const rooms = Object.entries(response.room_dat).reduce( (accumulator,
[roomId, room]) => { // 処理 return { ...accumulator, [roomId]: formattedRoom }; // ここが問題 }, {}, );
何が問題なのか reduce が進むにつれて展開されるオブジェクトが増えていく N個の要素を処理するには 0 + 1 + 2 ...
N-3 + N-2 + N-1 個分のオブジェクトが展 開される オーダー記法にすると O(N^2) 理論上要素数の二乗に比例する処理が必要 手元の環境では1万を超えると顕著に重くなり、10万を超えたあたりで分単位の時間が かかるようになった {}; // 1回目のreduceで展開されるaccumulator { 1: 'foo' }; // 2回目のreduceで展開されるaccumulator { 1: 'foo', 2: 'bar' }; // 3回目のreduceで展開されるaccumulator { 1: 'foo', 2: 'bar', 3: 'buz' }; // 4回目のreduceで展開されるaccumulator { 1: 'foo', 2: 'bar', 3: 'buz', 4: 'qux' }; // 5回目のreduceで展開されるaccumulator
改善しよう
改善しよう 基本的にどの言語も key-value 形式のデータ構造の操作は O(1) 単純に accumulator に代入する処理に変えることで O(N^2) から
O(N) に改善 reduce 内で accumulator に破壊的な操作をした場合、第二引数で渡した初期値が影響 を受ける 今回は初期値が空オブジェクトなので問題なし 変更を加えたくない場合は引数に渡す時点でスプレッド構文で展開すればOK const rooms = Object.entries(response.room_dat).reduce( (accumulator, [roomId, room]) => { // 処理 accumulator[roomId] = formattedRoom; return accumulator; }, {}, );
まとめ
まとめ スプレッド構文は展開する要素数に応じた処理が必要 reduce 等の O(N) の処理の中で使用すると、 O(N^2) になってしまうことがある forループや map
, forEach 等の配列の高階関数も注意 単に要素の追加や上書き処理にスプレッド構文を使用している場合は、一時変数を直接 上書きするように変更すれば改善できる
None