In the Ruby on Rails guide to the Asset Pipeline, it says
Any assets under public will be served as static files by the
application or web server. You should use app/assets for files that
must undergo some pre-processing before they are served.
http://guides.rubyonrails.org/asset_pipeline.html
To me, this says that images should be kept in the public directory as they can be served statically by my web server and require no pre-processing.
Are there advantages to putting your images in assets/?
Asset precompile appends unique hash value to image filenames, which allows users to get latest version of it despite of cache or expire settings on the server. This is useful when you want to change images in website design.
You don't want to use /assets/images for images what are unlikely to change (like user uploads).
Because it would harm the versatility of the asset pipeline.
With images being served via the asset pipeline, if you change the asset pipeline (for instance, have it upload files to S3) you would have to then sync your images via some other task.
There may be other, deeper reasons, but that is what would give me pause.
EDIT:
Side note: In production thanks to assets:precompile everything from /assets/ will be served from public.
Related
I understand that, when pushing to production, Rails generates digests for assets, so that application.js will become application-2695540c610db8087315134277d8afe6.js. The digest/fingerprint is added to a manifest file so that Rails can keep track of them.
My question is: what happens if you request an asset with a different digest?
Please note that our app is set up so that Rails serves all assets, which then get cached by our CDN (which fronts all requests). From our observations, assets requested with the correct digest are served immediately, while others take time, which have us think that they might be compiled live.
The digests help with caching issues. If a user has already requested the previous digested asset then it will be cached on their machine. If for some reason the page tries to call that version of the asset then the user will be served the cached version. Otherwise if the asset is not cached on the users machine and the page tries to fetch it, the asset would be unreadable as it no longer exists.
The whole point of pre-compiled assets is that they are just files in the file system. If you are not deleting your old assets (ie, by creating a new directory for each deploy), they are still there, and the requests for them will succeed.
If you delete your old assets, then the server will respond with a 404 unless you have config.assets.compile turned on in production. Then you would be compiling assets on request, which is not how the asset pipeline is meant to work. That setting should be off in production, and you should be relying on statically compiled assets.
Typically your public folder, where your compiled assets reside, should be shared across all of your deploys, via symlink for example, so that pages requesting older assets are able to find them.
The Rails guide here says
"Any assets under public will be served as static files by the
application or web server when config.serve_static_files is set to
true. You should use app/assets for files that must undergo some
pre-processing before they are served."
I'm using Rails 4.2.4. There is no public/assets folder. This leaves me wondering a few things:
What is meant by "use app/assets for files that must undergo some pre-processing before they are served?"
What is meant by pre-processing?
How is a static asset different from other assets, and what are the performance benefits of using one pipeline over the other?
Do I even need to worry about this if 4.2.4 has no public/assets folder?
Assets like javascript/css etc. need to be pre-processed - eg. minified, hashed for cache busting, passed through transpilers (like coffeescript) etc. Such assets should be kept in app/assets folder.
I believe 1 already answers that.
Passing each asset through transpilers/minifiers etc. as described in 1 during production will be very expensive and wasteful - because these assets don't change dynamically we can just do them once during pre-compilation and let static file server or cdn handle their delivery.
When you precompile your assets in deployment, the compiled files will be generated into the public/assets folder.
I recommend reading this article, which explains asset pipeline in much detail.
In a Rails 3.2 app I'm using asset_sync to host my assets on S3, and Cloudfront to distribute these assets, accessible via 4 CNAME'd URLs. It has been a good way of increasing the app's performance and reducing load on the server.
I'm now beginning to explore offline capabilities and HTML5 cache manifest. Obviously the cache manifest can be used to serve the static assets to repeat visitors.
I have two questions:
Can these two approaches be used together? i.e., the first time a
user visits the app, assets are downloaded from the cloudfront CDN.
Thereafter, assets are served from the cache manifest. There appear
to be conflicting reports across the internet as to whether the
manifest file and assets need to be on the same sub-domain. My app
is at http://app.example.com, whereas my assets are at
http://asset0.example.com, http://asset1.example.com, etc.
Secondly, how should I handle the unique ID applied to assets? For
example, assets have names such as
http://asset1.example.com/assets/application-hdggajdjd7672h12bsud8.js.
Do I need to handle these random strings to ensure assets are
properly cached, or are these strings created when updates are
pushed to the server and assets precompiled, hence will remain
static unless changes are made to the files.
I have a rails 4 app on heroku, and I want to embed some of my image assets in a static website that I'm making.
The problem is that rails adds a digest to the asset path.
<img src="http://myapp.herokuapp.com/assets/tools/my-image-43b65377b7644fae3f34d288f3235b80.png"/>
This makes it very hard for me to hotlink to my assets, because their digests may change over time.
Is there anyway to embed my images without having to insert this digest? I know that rails 3.1 allowed you to do so.
In rails-4, non digested assets are not generated anymore.
If you want to hotlink assets, place a copy of image you'll use in public/. To avoid duplication, you can use a symlink pointing to the proper location in app/assets/images/.
It's worth noting that rails does a very good job at caching images in browser, and it is usually recommended to add far future timeout for assets caching in front server. So you should probably avoid to hotlink images that are prone to change often.
I have an app that serves web image assets from both locations. I have watched the two railscasts on this topic but what are the REAL advantages of serving images this way. I see the timestamp on the file; does this cause problems with working with a CDN like cloudfront? Or a reverse proxy such as Varnish? Are there any performance metrics for serving from /public vs /app/assets using Nginx?
In short, I understand advantages of CSS and Javascript but am not sure if it justifies moving the images from /public to /app/assets. What is the most compelling reason to do so? And are there any significant downsides esp as it relates to a CDN?
thx
The asset pipeline will ad a digest (digital signature) to the images which is very helpful for cache busting. If you do eventually choose to use a CDN, having all your static assets in the assets folder makes it convenient.