狠狠撸

狠狠撸Share a Scribd company logo
パフォーマンスの良いGASの書き方 Best Practice
パフォーマンスの良いGASの書き方 Best Practice
しょっちゅう
「XXXってサイトにある、
このサンプルコードを
コピーして使ってるのだけど、
うちの会社のデータ件数だと
タイムアウトしちゃうんです。
どうにか助けて下さい」
って言われて、毎回同じ内容で返答していて、
流石に疲れてきたので
ちゃんとパフォーマンスの話をするからお前ら聞
いてろ下さい
パフォーマンスの良いGASの書き方 Best Practice
パフォーマンスの良いGASの書き方 Best Practice
何やってる?
パフォーマンスの良いGASの書き方 Best Practice
@soundTricker318
http://goo.gl/ZpUOs
http://www.bfts.co.jp
パフォーマンスの良いGASの書き方 Best Practice
Contents
うそ…
私のスクリプト
遅すぎ?
パフォーマンス
の良い書き方 まとめ
Start End
う
そ
?
?
?
私
の
ス
ク
リ
プ
ト
遅
す
ぎ
?
?
?
?
http://www.pakutaso.com/
公式ドキュメントにも
有りますが…
? GASは書き方によって非常にパフォーマンスが変
わります。
うそ…私の…
质问
GASを使ったことがある人?
质问
GASでサンプルコードを
コピーして
使ったことがある人?
质问
GASでサンプルコードを
コピーして
社内のシステムとして
使っている人?
质问
GASでサンプルコードを
コピーして
社内のシステムとして
使ってタイムアウトした人?
质问
? 巷のサンプルコードは比較的パフォーマンスが
悪いコードを書いている
– 公式ドキュメントに書いてある書き方を守ってな
いことが多い
? https://developers.google.com/apps-
script/best_practices?hl=ja
– 多分読みやすくするためにそうしているのだと思い
ます。
サンプルコード…
? パフォーマンスが悪いコードを使うと…
–処理が終わらなくてタイムアウトする
–なんかGASで作るの嫌になる
–GAS遅い…と言いふらすようになる
–困る
サンプルコード
パ
フ
ォ
ー
マ
ン
ス
の
良
いス
ク
リ
プ
ト
で
い
い
感
じ
に
http://www.pakutaso.com/
パフォーマンスの良い
スクリプトの書き方
パフォーマンスの良いGASの書き方 Best Practice
パフォーマンスの良いGASの書き方 Best Practice
パフォーマンスの良いGASの書き方 Best Practice
? Spreadsheetに色つける処理
–データは100×100セル
–セルに「hoge」と書いてあったら黄色に
–ないなら無職
今回の処理
以下のコードをSpreadsheet上のGASで実行すれば作れます。
今回の処理
var arr = ["hoge", "fuga", "foo", "bar" , "bus", "あいうえお", "かきくけこ"];
function make() {
var grid = [];
var header = [];
for (var c = 0; c < 100; c++) {
header.push(c + 1);
}
grid.push(header);
for (var r = 1; r < 101; r++) {
var row = [];
for (var c = 0; c < 100; c++) {
row.push(arr[Math.floor(Math.random() * arr.length)]);
}
grid.push(row);
}
SpreadsheetApp.getActiveSheet().getRange(1, 1, 101, 100).clear().setValues(grid);
}
パフォーマンスの良いGASの書き方 Best Practice
function badCode() {
var spreadsheet =
SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqS
ZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0");
for(var row = 2; row <= 101; row++) {
for(var col = 1; col <= 100; col++) {
var value = spreadsheet.getSheetByName("シート1").getRange(row, col).getValue();
if (value == "hoge") {
spreadsheet.getSheetByName("シート1").getRange(row, col).setBackground("yellow");
}
}
}
}
悪いコード
パフォーマンスの良いGASの書き方 Best Practice
function goodCode() {
var spreadsheet = SpreadsheetApp.openById("1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o");
var backgrounds = [];
var sheet = spreadsheet.getSheetByName("シート1");
var targetRange = sheet.getRange(2, 1, 100, 100);
var values = targetRange.getValues();
for(var rowIndex = 0; rowIndex < values.length; rowIndex++) {
var row = values[rowIndex];
var backgroundRow = [];
for(var colIndex = 0; colIndex < row.length; colIndex++) {
var value = row[colIndex];
if (value == "hoge") {
backgroundRow.push("yellow");
} else {
backgroundRow.push("");
}
}
backgrounds.push(backgroundRow);
}
targetRange.setBackgrounds(backgrounds);
}
良いコード
①悪い部分を知る
? 遅い理由を知らないとどこを直してよいかわか
りません
– 実行トランスクリプトを使ってどこに時間がかかっ
ているか確認する
①悪い部分を知る
①悪い部分を知る
②無駄なAPIアクセス
を減らす
? GASのService呼び出しは全てネットワーク経由で行
われるため、時間がかかります。
少しでも無駄な呼び出しはしないようにします。
②減らす
ネットワーク経由
function badCode() {
var spreadsheet =
SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqS
ZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0");
for(var row = 2; row <= 101; row++) {
for(var col = 1; col <= 100; col++) {
var value = spreadsheet.getSheetByName("シート1").getRange(row, col).getValue();
if (value == "hoge") {
spreadsheet.getSheetByName("シート1").getRange(row, col).setBackground("yellow");
}
}
}
}
②減らす
function badCode() {
var spreadsheet =
SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-
LEEqQK2n4yQO-o/edit#gid=0");
var sheet = spreadsheet.getSheetByName("シート1");
for(var row = 2; row <= 101; row++) {
for(var col = 1; col <= 100; col++) {
var range = sheet.getRange(row, col);
var value = range.getValue();
if (value == "hoge") {
range.setBackground("yellow");
}
}
}
}
②減らす
③なるべく1度にする
? ②同じ原理でより呼び出し回数を減らすために
getValues,setBackgrounds等のBatch Operationを
利用します。
③1度にする
通常のgetValue()
getValue()
1セルで1回アクセス = 100×100回アクセス
? ②同じ原理でより呼び出し回数を減らすために
getValues,setBackgrounds等のBatch Operationを
利用します。
③1度にする
getValues()
getValues)
100×100セルを1回アクセス = 1回アクセス
function badCode() {
var spreadsheet =
SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-
LEEqQK2n4yQO-o/edit#gid=0");
var sheet = spreadsheet.getSheetByName("シート1");
for(var row = 2; row <= 101; row++) {
for(var col = 1; col <= 100; col++) {
var range = sheet.getRange(row, col);
var value = range.getValue();
if (value == "hoge") {
range.setBackground("yellow");
}
}
}
}
③1度にする
function badCode() {
var spreadsheet = SpreadsheetApp
.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0");
var backgrounds = [];
var sheet = spreadsheet.getSheetByName("シート1");
var targetRange = sheet.getRange(2, 1, 100, 100);
var values = targetRange.getValues();
for(var rowIndex = 0; rowIndex < values.length; rowIndex++) {
var row = values[rowIndex];
var backgroundRow = [];
for(var colIndex = 0; colIndex < row.length; colIndex++) {
var value = range.getValue();
if (value == "hoge") {
backgrounds.push("yellow");
} else {
backgrounds.push(“");
}
}
backgrounds.push(backgroundRow);
}
targetRange.setBackgrounds(backgrounds);
}
③1度にする
? 大体のスクリプトはこの②、③を実施すればかなりパ
フォーマンスが良くなります。
④ 我に返る
? 今回の処理はGASでやる必要がありません。
Sheetsの標準機能でやれることはそっちでやりましょ
う
– 今回のはセルの条件付き書式でできます。
– 新しいSpreadsheetはかなり細かい書式が使えるので
確認して下さい。
④我に返る
パフォーマンスの良いGASの書き方 Best Practice
辞辫别苍叠测滨诲と辞辫别苍叠测鲍谤濒
? Spreadsheet,Forms自体などを取得する際に利用す
る辞辫别苍叠测滨诲と辞辫别苍叠测鲍谤濒というメソッドが有ります。
? これらは比較的openByIdの方が速い
– IDはURL中のなんかよくわかない文字の部分がだいたいそれ
openByIdとUrl
https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-
o/edit#gid=0
UiApp
? UiAppを利用するときはなるべくClientHandler等ク
ライアントサイドで動くイベントハンドラを活用する
– UiAppのイベントハンドラは上記以外は全てサーバコールに
なりおっそい
– 適切にClientHandlerを利用するとかなりUXがよくなる
UiApp
HtmlService
? HtmlServiceのパフォーマンスを良くする書き方の話も公式
ページに乗っている
HtmlService
? 基本的には
– データの取得は非同期に行う
? doGet内などHtmlService呼び出し前に行わない
– <html>,<head>,<body>タグなどは利用しない
? cajaにより自動的に<caja-v-html>に変えられるので意味が無い
? 変えられる分時間がかかるので使わない
– Javascriptは最後に読み込む
? <script>タグはファイルの一番末尾に書いておく
? そのほうが画面が表示されてからクライアントサイドのJavascriptが実行される
HtmlService
? 大橋の感覚として
– 外部のJSやCSSは使わない方が良い
? 使う場合は<script src=/slideshow/gas-best-practice/37555762/“xxx”>とはせず、<script>ここにコピペ</script>して、埋
め込んでしまう。
? cajaはGoogle経由で外部JS、CSSを取得するので遅い
– 画面遷移はJavascriptを使って一部分だけ切り替える
? doGetを毎回すると遅い
? SPA(Single Page Application)の様にJSで画面を切り替えたほうが速い
? というより画面切り替えはしないほうが良い
HtmlService
どうしても遅い
? どうしても遅い時は…
– UrlFetchAppを利用してGoogle APIを直接呼び出す。
– 直接呼び出すと、欲しいデータが1回の操作で取得できる場
合がある
? CalendarAppやDriveAppなどでよくある
? fieldsパラメータを利用すると不要なデータを取得しない
ためネットワーク的にも良い
どうしても遅い
? どうしても遅い時は…
– 本当にリアルタイム(わざわざ人が待って)でやる必
要があるか考える
? Triggerを利用して遅延実行 & 通知でも良いのではない
か?
? 朝一回実行すれば大丈夫なんじゃないか?
? 実行タイミングは定期的でも良いのじゃないか?
どうしても遅い
? どうしても遅い時は…
– ちゃんとGASで作って良いのか考える
– 金で解決できるのならGAEやGCPを使ったほうが良
い
– SpreadsheetをDBとして使っている場合もそう
? 大量のデータなら場合によってはFusion Table
もっと多いならBigQueryを検討
どうしても遅い
パフォーマンスの良いGASの書き方 Best Practice
まとめ
GASで
困ったら
#gasja
Google Apps API Japan
http://goo.gl/FcU0C
@soundTricker318
http://goo.gl/ZpUOs
会社: http://goo.gl/CfVPf
個人: http://goo.gl/kVTv3
パフォーマンスの良いGASの書き方 Best Practice
パフォーマンスの良いGASの書き方 Best Practice
パフォーマンスの良いGASの書き方 Best Practice

More Related Content

パフォーマンスの良いGASの書き方 Best Practice

Editor's Notes

  • #30: https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0
  • #32: https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0
  • #49: https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0
  • #62: https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0