Top Banner
パパパパパパパパパパ GAS パパパパ
70

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

Dec 13, 2014

Download

Technology

Atmosphere Tokyo 2014 Sandbox Session.
gcp ja night × TokyoGAS Day2 GAS Session.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: パフォーマンスの良いGASの書き方 Best Practice

パフォーマンスの良い

GASの書き方

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

サブタイトル

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

しょっちゅう「 XXX ってサイトにある、

このサンプルコードを

コピーして使ってるのだけど、うちの会社のデータ件数だと

タイムアウトしちゃうんです。

どうにか助けて下さい」って言われて、毎回同じ内容で返答していて、流石に疲れてきたので

ちゃんとパフォーマンスの話をするからお前ら聞いてろ下さい

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

誰?

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

大橋啓介と

申します

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

何やってる?

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

@soundTricker318http://goo.gl/ZpUOs

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

http://www.bfts.co.jp

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

話す事

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

Contents

うそ…私のスクリプ

ト遅すぎ?

パフォーマンスの良い書き

方まとめ

Start End

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

うそ・・・

私のスクリプト

遅すぎ・・・?

http://www.pakutaso.com/

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

公式ドキュメントにも有りますが…

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

• GAS は書き方によって非常にパフォーマンスが変わります。

うそ…私の…

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

質問

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

GAS を使ったことがある人?

質問

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

GAS でサンプルコードをコピーして使ったことがある人?

質問

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

GAS でサンプルコードをコピーして社内のシステムとして使っている人?

質問

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

GAS でサンプルコードをコピーして社内のシステムとして使ってタイムアウトした人?

質問

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

• 巷のサンプルコードは比較的パフォーマンスが悪いコードを書いている–公式ドキュメントに書いてある書き方を守ってな

いことが多い• https://developers.google.com/apps-script/

best_practices?hl=ja

–多分読みやすくするためにそうしているのだと思います。

サンプルコード…

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

• パフォーマンスが悪いコードを使うと…–処理が終わらなくてタイムアウトする

–なんか GAS で作るの嫌になる

–GAS 遅い…と言いふらすようになる

–困る

サンプルコード

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

パフォーマンスの

良いスクリプトで

いい感じに

http://www.pakutaso.com/

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

パフォーマンスの良いスクリプトの書き方

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

実際に

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

書きながら

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

説明します。

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

• Spreadsheet に色つける処理–データは 100×100 セル

–セルに「 hoge 」と書いてあったら黄色に

–ないなら無職

今回の処理

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

以下のコードを 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);}

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

悪いコード

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

function badCode() { var spreadsheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-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"); } } }}

悪いコード

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

良いコード

Page 32: パフォーマンスの良い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);}

良いコード

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

① 悪い部分を知る

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

• 遅い理由を知らないとどこを直してよいかわかりません–実行トランスクリプトを使ってどこに時間がか

かっているか確認する

① 悪い部分を知る

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

① 悪い部分を知る

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

② 無駄な API アクセスを減らす

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

• GAS の Service 呼び出しは全てネットワーク経由で行われるため、時間がかかります。少しでも無駄な呼び出しはしないようにします。

② 減らす

ネットワーク経由

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

function badCode() { var spreadsheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-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"); } } }}

② 減らす

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

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"); } } }}

② 減らす

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

③ なるべく 1 度にする

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

• ② 同じ原理でより呼び出し回数を減らすためにgetValues,setBackgrounds 等の Batch Operationを利用します。

③1 度にする

通常の getValue()

getValue()

1 セルで 1 回アクセス = 100×100 回アクセス

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

• ② 同じ原理でより呼び出し回数を減らすためにgetValues,setBackgrounds 等の Batch Operationを利用します。

③1 度にする

getValues()

getValues)

100×100 セルを 1 回アクセス = 1 回アクセス

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

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 度にする

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

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 度にする

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

• 大体のスクリプトはこの ②、③を実施すればかなりパフォーマンスが良くなります。

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

④ 我に返る

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

• 今回の処理は GAS でやる必要がありません。Sheets の標準機能でやれることはそっちでやりましょう– 今回のはセルの条件付き書式でできます。

– 新しい Spreadsheet はかなり細かい書式が使えるので確認して下さい。

④ 我に返る

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

番外編

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

openById と openByUrl

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

• Spreadsheet,Forms 自体などを取得する際に利用する openById と openByUrl というメソッドが有ります。

• これらは比較的 openById の方が速い– ID は URL 中のなんかよくわかない文字の部分がだいたい

それ

openById と Url

https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0

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

UiApp

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

• UiApp を利用するときはなるべく ClientHandler 等クライアントサイドで動くイベントハンドラを活用する– UiApp のイベントハンドラは上記以外は全てサーバコール

になりおっそい

– 適切に ClientHandler を利用するとかなり UX がよくなる

UiApp

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

HtmlService

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

• HtmlService のパフォーマンスを良くする書き方の話も公式ページに乗っている

HtmlService

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

• 基本的には– データの取得は非同期に行う

• doGet 内など HtmlService 呼び出し前に行わない

– <html>,<head>,<body> タグなどは利用しない• caja により自動的に <caja-v-html> に変えられるので意味が無い

• 変えられる分時間がかかるので使わない

– Javascript は最後に読み込む• <script> タグはファイルの一番末尾に書いておく

• そのほうが画面が表示されてからクライアントサイドの Javascript が実行される

HtmlService

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

• 大橋の感覚として– 外部の JS や CSS は使わない方が良い

• 使う場合は <script src=“xxx”> とはせず、 <script> ここにコピペ </script> して、埋め込んでしまう。

• caja は Google 経由で外部 JS 、 CSS を取得するので遅い

– 画面遷移は Javascript を使って一部分だけ切り替える• doGet を毎回すると遅い

• SPA(Single Page Application) の様に JS で画面を切り替えたほうが速い

• というより画面切り替えはしないほうが良い

HtmlService

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

どうしても遅い

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

• どうしても遅い時は…– UrlFetchApp を利用して Google API を直接呼び出す。

– 直接呼び出すと、欲しいデータが 1 回の操作で取得できる場合がある• CalendarApp や DriveApp などでよくある

• fields パラメータを利用すると不要なデータを取得しないためネットワーク的にも良い

どうしても遅い

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

• どうしても遅い時は…

–本当にリアルタイム ( わざわざ人が待って ) でやる必要があるか考える• Trigger を利用して遅延実行 & 通知でも良いのではない

か?

• 朝一回実行すれば大 丈夫なんじゃないか?

• 実行タイミングは定期的でも良いのじゃないか?

どうしても遅い

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

• どうしても遅い時は…

–ちゃんと GAS で作って良いのか考える

–金で解決できるのなら GAE や GCP を使ったほうが良い

– Spreadsheet を DB として使っている場合もそう• 大 量のデータなら場合によっては Fusion Table

もっと多いなら BigQuery を検討

どうしても遅い

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

なんでも

GAS症候群に

注意!

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

まとめ

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

GAS で困ったら

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

#gasja

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

Google Apps API Japanhttp://goo.gl/FcU0C

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

@soundTricker318http://goo.gl/ZpUOs

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

会社 : http://goo.gl/CfVPf

個人 : http://goo.gl/kVTv3

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

解決できない

かもです

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

一緒に

悩めます多分キリッ

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

End