という名の、posteiro による投稿テスト。
ドライブがてら「百間滝(ひゃっけんだき)」へ行ってきた。初。
さてオリジナルの 4000x2000(6MB) の画像を UP したら数分経っても終わらなかったので、どこがやねんがダメそう。GitHub の制限ではなさそうだけど。
解像度はそのままに圧縮して 450KB に変換したら数秒で UP できた。
滝の他には体力が回復しそうな泉があったりした。
道路から滝まではけっこうな悪路(人の手は入っている)であり、膝が悪い人には全くおすすめできない。 帰り(登り)は酸欠になりそうだった。
一応観光地に数えられる程度には名の知れたスポットだが、平日なので人は居らず。足を踏み外して転げ落ちた日には Apple Watch の救助機能に頼るしかない状況だった(Watch 持ってないけど)。
ということで、posteiro による投稿ではファイルサイズの大きな画像は無料ぽいことが分かった。
GitHub REST API では画像送信が base64 でしかできないみたいなので高速化はムリそう。
スマホの Chrome で GitHub の Web ページから 6MB の画像を upload して push しても数秒で完了するから、私の実装がヘボいのか GitHub サイトに何か special なことがあるのか。。。
原因が判った。
GitHub REST API ではファイルアップロードは BASE64 で行うが、Javascript で File → BASE64 文字列への変換を行うのは https://stackoverflow.com/a/52311051 で紹介されているような readAsDataURL の結果から dataURL の接頭辞を replace で削除する、という方法が一般的だ(特に非node、ブラウザでは)。
で、この replace が遅い遅い。 6MB の画像であれば、readAsDataURL の結果文字列長は100万文字ほどにもなるので遅いのは当然だ。
幸い接頭辞はシンプルなので replace するまでもなく、substring で読み飛ばせばよい。
const fileToBase64 = (file: File): Promise<string> => {
return new Promise<string>((resolve, reject) => {
const reader = new FileReader();
console.log('readAsDataURL start', new Date().getTime());
reader.readAsDataURL(file);
reader.onload = (r) => {
console.log('readAsDataURL end', new Date().getTime());
console.log('replace start', new Date().getTime());
// const base64str = (r.target?.result as string).replace(/data:.*\/.*;base64,/, '');
c
const prefix = `data:${file.type}:base64,`;
const base64str = (r.target?.result as string).substring(prefix.length);
console.log('replace end', new Date().getTime());
resolve(base64str);
};
reader.onerror = (e) => reject(e);
});
};
このようなコードにすることで、6MB の画像ファイルでも数秒でアップロードできるようになった。