こんにちは、エムザス ITサービス部です。
kintoneカスタマイズで「処理が遅い…」と感じたことはありませんか?
この記事では、JavaScriptコードを少し工夫するだけでkintoneの動作を快適にする、3つの簡単な最適化テクニックをご紹介します。
- 非同期処理の高速化 :
Promise.all
で待ち時間を短縮 - データ検索の高速化:
Set
/Map
を活用 - 効率的なループ処理: 用途に合わせたメソッド選択
これらのテクニックで、よりサクサク動くkintoneを目指しましょう!
お知らせ①
🌟無料&登録不要でプラグインのお試しが可能!🌟
kintoneユーザーの皆さん!
エムザスのkintoneプラグインはもう試しましたか?🤔
エムザスでは以下のようなプラグインを開発しています!👇
デモ環境で、ほとんどの機能が今すぐお試しいただけます✨
さらに、お客様のドメインで無料で3ヶ月間、すべての機能を試すこともできます!🎉
それでは、本題に入ります!
1. 非同期処理の高速化: Promise.all
で待ち時間を短縮
kintone APIの呼び出しなど、時間がかかる非同期処理。これらを一つずつ順番に実行すると、全体の処理時間が長くなってしまいます。
問題点: 直列処理による遅延
// 【遅い例】複数のレコード情報を1件ずつ取得
const getRecordsSequentially = async (ids) => {
console.time('直列処理');
const records = [];
for (const id of ids) {
const resp = await kintone.api(kintone.api.url('/k/v1/record', true), 'GET', { app: kintone.app.getId(), id });
records.push(resp.record);
}
console.timeEnd('直列処理');
return records;
};
上記は、前のAPI呼び出しが終わるまで次が始まらないため、件数が多いと非常に時間がかかります。
改善策: Promise.all
で並列処理
Promise.all
を使うと、複数の非同期処理を同時に開始し、すべて完了するのを待つことができます。
// 【速い例】Promise.allで並列取得
const getRecordsInParallel = async (ids) => {
console.time('並列処理');
const promises = ids.map(id =>
kintone.api(kintone.api.url('/k/v1/record', true), 'GET', { app: kintone.app.getId(), id })
.then(resp => resp.record)
.catch(err => {
console.error(`ID: ${id} の取得失敗`, err);
return null; // 一部失敗しても他は続行
})
);
const records = (await Promise.all(promises)).filter(r => r !== null);
console.timeEnd('並列処理');
return records;
};
これにより、個々の処理時間がほぼ同じであれば、全体の処理時間は1件分程度に短縮される可能性があります。ただし、APIの同時実行数制限には注意しましょう。
2. データ検索の高速化: Set
/ Map
を活用
配列から特定の要素を探す場合、Array.prototype.includes
や find
は便利ですが、要素数が多いとパフォーマンスが低下します。
問題点: 配列での検索は遅い
// 【遅い例】配列のincludesで存在確認
const checkExistenceInArray = (items, lookups) => {
console.time('配列includes');
const found = [];
for (const item of items) {
if (lookups.includes(item.code.value)) { // lookupsが大きいと遅い
found.push(item);
}
}
console.timeEnd('配列includes');
return found;
};
改善策: Set
や Map
を使う
Set
(重複しない値の集合)やMap
(キーと値のペア)を使うと、値の存在確認や取得が非常に高速になります。
大量データの中から頻繁に検索を行う場合は、Set
や Map
への変換を検討しましょう。
// 【速い例】Setのhasで存在確認
const checkExistenceWithSet = (items, lookupArray) => {
console.time('Set has');
const lookupSet = new Set(lookupArray); // 事前にSetを生成
const found = [];
for (const item of items) {
if (lookupSet.has(item.code.value)) { // Set.hasは高速
found.push(item);
}
}
console.timeEnd('Set has');
return found;
};
// Mapの活用例: IDをキーにレコードを格納し、高速アクセス
// const recordMap = new Map(records.map(r => [r.$id.value, r]));
// const targetRecord = recordMap.get('123'); // ID '123'のレコードをO(1)で取得
3. 効率的なループ処理: 用途に合わせたメソッド選択
JavaScriptには様々なループ方法があります。kintoneで取得したレコード配列を処理する際、用途に応じて最適なものを選びましょう。
主なループ手法と使い分け
・ for…of ループ:
for (const record of event.records)
レコード配列の各要素をシンプルに処理したい場合。async/await との相性も良く、break/continue も使えます。読みやすさNo.1。
・ Array.prototype.forEach():
event.records.forEach(record => { /*処理*/ });
配列の全要素に同じ処理をしたいが、途中で中断する必要がない場合に簡潔。async/await は期待通りに動作しないので注意。
・ Array.prototype.map():
const names = event.records.map(record => record.名前.value);
元の配列から新しい配列を生成したい場合(例: 特定フィールド値のリスト作成)。元の配列は変更しません。
・ Array.prototype.filter():
const activeRecords = event.records.filter(record => record.ステータス.value === ‘有効’);
条件に合う要素だけで新しい配列を作りたい場合。
・ for ループ (C-style):
for (let i = 0; i < records.length; i++) { /* records[i]でアクセス */ }
インデックスが必要な場合や、パフォーマンスが極めて重要な特殊なケースで。
// kintoneイベントでのレコード処理例
const event = {
records: [
{ 'ステータス': { value: '処理中' }, '担当者': { value: '田中' } },
{ 'ステータス': { value: '完了' }, '担当者': { value: '佐藤' } },
{ 'ステータス': { value: '処理中' }, '担当者': { value: '鈴木' } },
]
};
// 【map】担当者リストを作成
const assignees = event.records.map(r => r.担当者.value);
console.log(assignees); // ['田中', '佐藤', '鈴木']
// 【filter】ステータスが「処理中」のレコードを抽出
const pendingRecords = event.records.filter(r => r.ステータス.value === '処理中');
console.log(pendingRecords.length); // 2
// 【for...of】各レコードを処理
for (const record of pendingRecords) {
console.log(`${record.担当者.value}さんのタスクは処理中です。`);
}
コードの意図が明確になるメソッドを選ぶのが基本です。多くの場合、for...of
や map
, filter
で十分なパフォーマンスが得られます。
おわりに
今回はkintoneカスタマイズを高速化するための3つのテクニック、非同期処理の並列化、Set
/ Map
による検索効率化、適切なループ手法の選択をご紹介しました。
小さな改善の積み重ねが、全体のパフォーマンス向上に繋がります。ただし、最適化でコードが複雑になりすぎないよう、可読性とのバランスも大切です。
ぜひ試してみてください!