Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GuruSP - Solucionando o problema de Uploads em...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Rafael Macedo
June 21, 2014
Programming
120
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
GuruSP - Solucionando o problema de Uploads em Apps no Heroku
Rafael Macedo
June 21, 2014
More Decks by Rafael Macedo
See All by Rafael Macedo
Modularização de código JS
macedorafael
0
250
TDC 2014 - Solucionando o problema de Uploads em Apps no Heroku
macedorafael
1
180
Aplicações Realtime com XMPP
macedorafael
3
230
Web in the cloud with ruby
macedorafael
2
400
Other Decks in Programming
See All in Programming
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
440
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
230
私のClaude Code活用法 (個人開発編) - PHPerKaigi mini #4(2026/08/24)
panda_program
1
210
Go 1.27からのGODEBUG / Go 1.27 リリースパーティ #go127party
mazrean
0
320
新卒PdEのリアル
ryu1013
1
420
AIの中の人になってみる
htkym
0
170
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
140
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
260
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
360
高専キャリア LT 発表内容
crysta1221
6
5.6k
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.4k
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
160
Featured
See All Featured
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
230
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
Google's AI Overviews - The New Search
badams
0
1.6k
Abbi's Birthday
coloredviolet
3
9.8k
Mind Mapping
helmedeiros
1
350
Designing Experiences People Love
moore
143
24k
Visualization
eitanlees
152
17k
AI: The stuff that nobody shows you
jnunemaker
PRO
9
970
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
370
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
The SEO identity crisis: Don't let AI make you average
varn
0
550
The agentic SEO stack - context over prompts
schlessera
0
900
Transcript
Solucionando o problema de Uploads em Apps no Heroku
@macedorafael http://github.com/macedo Rafael Macedo
@macedorafael http://github.com/macedo Macedo
backend…
…com chapéu de front
None
None
None
“O que pode dar errado num mero upload de uma
foto?”
None
30 segundos
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
None
…
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
heroku addons
None
Blitline
Blitline Transloadit
Blitline Transloadit Cloudinary
Blitline Transloadit Cloudinary ✔
http://cloudinary.com
None
None
upload
None
•JPG, PNG, GIF, BMP, ICO, TIFF and PDF
•JPG, PNG, GIF, BMP, ICO, TIFF and PDF •Secure HTTP
upload API
•JPG, PNG, GIF, BMP, ICO, TIFF and PDF •Secure HTTP
upload API •Upload from your server or directly from the browser
storage
None
•Cloud-based persistent storage
•Cloud-based persistent storage •Highly available redundant storage
•Cloud-based persistent storage •Highly available redundant storage •S3
delivery
None
•Fast delivery (CDN)
•Fast delivery (CDN) •Smart caching
image transformation/ manipulation
None
resize
resize filter
resize filter crop
resize filter crop rotate
resize filter crop rotate face detection
resize filter crop rotate face detection chained transformation …
{"public_id"=>"fe23qemppmcorq0grmfv", "version"=>1403326723, "signature"=>"4e1a7bb2e3f3eb05eed25eed10cb09807561a764", "width"=>533, "height"=>300,
"format"=>"jpg", "resource_type"=>"image", "created_at"=>"2014-‐06-‐21T04:58:43Z", "bytes"=>13895, "type"=>"upload", "etag"=>"30b1c1b426db36b8e8c12d15d629fdb5", "url"=>"http://res.cloudinary.com/hxjx3jqm7/image/upload/v1403326723/ fe23qemppmcorq0grmfv.jpg", "secure_url"=>"https://res.cloudinary.com/hxjx3jqm7/image/upload/v1403326723/ fe23qemppmcorq0grmfv.jpg"}
{"public_id"=>"fe23qemppmcorq0grmfv", "version"=>1403326723, "signature"=>"4e1a7bb2e3f3eb05eed25eed10cb09807561a764", "width"=>533, "height"=>300,
"format"=>"jpg", "resource_type"=>"image", "created_at"=>"2014-‐06-‐21T04:58:43Z", "bytes"=>13895, "type"=>"upload", "etag"=>"30b1c1b426db36b8e8c12d15d629fdb5", "url"=>"http://res.cloudinary.com/hxjx3jqm7/image/upload/v1403326723/ fe23qemppmcorq0grmfv.jpg", "secure_url"=>"https://res.cloudinary.com/hxjx3jqm7/image/upload/v1403326723/ fe23qemppmcorq0grmfv.jpg"}
http://res.cloudinary.com/hxjx3jqm7/image/ upload/v1403326723/ fe23qemppmcorq0grmfv.jpg
http://res.cloudinary.com/hxjx3jqm7/image/ upload/v1403326723/ fe23qemppmcorq0grmfv.jpg
http://res.cloudinary.com/hxjx3jqm7/image/ upload/v1403326723/ fe23qemppmcorq0grmfv.jpg http://res.cloudinary.com/hxjx3jqm7/image/ upload/w_160,h_160,c_thumb,g_face/ fe23qemppmcorq0grmfv.jpg
http://res.cloudinary.com/hxjx3jqm7/image/ upload/v1403326723/ fe23qemppmcorq0grmfv.jpg http://res.cloudinary.com/hxjx3jqm7/image/ upload/w_160,h_160,c_thumb,g_face/ fe23qemppmcorq0grmfv.jpg
None
gem 'cloudinary'
# config/cloudinary.yml development: cloud_name:
“sample” api_key: “912739217312873” api_secret: “a123=asdaszad34dsf”
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
width: 160, height: 160, crop: fill, effect: ”sepia” )
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
effect: )
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
width: 100, height: 150, effect: :pixelate)
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class Advertisement < ActiveRecord::Base ... mount_uploader
:image, ImageUploader ... end
= form_for(:advertisement) do |f| = f.hidden_field(:image_cache)
= f.file_field(:image)
None
# app/assets/javascripts/application.js //= require cloudinary
= form_for(:advertisement) do |f| ...
= cloudinary_js_config = f.cl_image_upload(:image) ..
= form_for(:advertisement) do |f| ...
= cloudinary_js_config = f.cl_image_upload(:image) ..
= form_for(:advertisement) do |f| ...
= cloudinary_js_config = f.cl_image_upload(:image) ..
None
$$$
None
10 GB Storage
10 GB Storage 40 GB Bandwidth
Cloudinary
$35
S3
$7
None
None
$7
$42
Conclusão
“O que pode dar errado num mero upload de uma
foto?”
Muita coisa!
None
Processamento background
Processamento background Direct Upload
None
OBRIGADO
OBRIGADO ?