They are really complimentary. Etags/fresh_when etc. help you play nice with downstream caches (like your own Varnish/Squid instances or Rack::Cache or the Browser cache or ISP Proxy Servers…)
Page caching saves you from hitting your rails stack entirely because Apache/your webserver serve the file, so no DB lookups are done. But you have to deal with cache expiration to keep the cache fresh.
Using etags/conditional get, you don't save much processing time since you still need to to get all the records used on the page:
def show
@article = Article.find(params[:id])
@feature = Feature.current
fresh_when :etag => [@article, @feature]
end
in the case that the user has a current page, it saves you some rendering time and the bandwidth required to send down the page.