首页 > 解决方案 > 我的索引页面加载缓慢。如何减少加载时间?

问题描述

我编写了一个简单的 Rails 应用程序,允许用户阅读和分享文章。加载索引页面需要相当长的时间(15 秒以上)。该应用程序使用主动存储来存储图像。您可以在下面的片段中看到相关逻辑:

文章型号:

class Article < ApplicationRecord
  belongs_to :user
  has_one_attached :image
  has_many :votes
  validates :title, presence: true, length: { maximum: 50 }
  validates :text, presence: true
  scope :news, -> { where(category: 'news') }
  scope :business, -> { where(category: 'business') }
  scope :ent, -> { where(category: 'entertainment') }
  scope :tech, -> { where(category: 'tech') }
  scope :sports, -> { where(category: 'sports') }
  scope :op, -> { where(category: 'opinion') }
end

文章控制者:

def index
  @articles = Article.all.with_attached_image
end

索引视图:

<div class="grid-container">
  <div class="main" style="background-image: url(<%= (url_for(@articles.last.image)) %>)">
  <div class="top-article" >
    <h2><%= @articles.last.title %></h2>
    <p><%= link_to "Read more..." %></p>
  </div>
  </div>
  <div class="sports" style="background-image: url(<%= (url_for(@articles.sports.last.image)) %>)">
    <h2><%= link_to "Sports", sports_path %></h2>
  </div>
  <div class="tech" style="background-image: url(<%= (url_for(@articles.tech.last.image)) %>)">
    <h2><%= link_to "Technology", tech_path %></h2>
  </div>
  <div class="opinion" style="background-image: url(<%= (url_for(@articles.op.last.image)) %>)">
    <h2><%= link_to "Opinion", opinion_path %></h2>
  </div>
  <div class="entertainment" style="background-image: url(<%= (url_for(@articles.ent.last.image)) %>)">
    <h2><%= link_to "Entertainment", entertainment_path %></h2>
  </div>
  <div class="business" style="background-image: url(<%= (url_for(@articles.business.last.image)) %>)">
    <h2><%= link_to "Business", business_path %></h2>
  </div>
  <div class="news" style="background-image: url(<%= (url_for(@articles.news.last.image)) %>)">
    <h2><%= link_to "News", news_path %></h2>
  </div>
</div>

索引页面加载时的服务器日志:

Started GET "/" for ::1 at 2020-06-16 23:27:49 -0400
   (104.9ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by ArticlesController#index as HTML
  Rendering articles/index.html.erb within layouts/application
  Article Load (149.4ms)  SELECT "articles".* FROM "articles" ORDER BY "articles"."id" DESC LIMIT $1  [["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:2
  ActiveStorage::Attachment Load (102.9ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 8]]
  ↳ app/views/articles/index.html.erb:2
  ActiveStorage::Blob Load (33.3ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 7]]
  ↳ app/views/articles/index.html.erb:2
  CACHE Article Load (0.0ms)  SELECT "articles".* FROM "articles" ORDER BY "articles"."id" DESC LIMIT $1  [["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:4
  CACHE ActiveStorage::Attachment Load (0.0ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 8]]
  ↳ app/views/articles/index.html.erb:4
  CACHE ActiveStorage::Blob Load (0.0ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 7]]
  ↳ app/views/articles/index.html.erb:4
  Article Load (0.3ms)  SELECT "articles".* FROM "articles" WHERE "articles"."category" = $1 ORDER BY "articles"."id" DESC LIMIT $2  [["category", "sports"], ["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:8
  ActiveStorage::Attachment Load (0.5ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 6]]
  ↳ app/views/articles/index.html.erb:8
  ActiveStorage::Blob Load (0.3ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 5]]
  ↳ app/views/articles/index.html.erb:8
  Article Load (0.4ms)  SELECT "articles".* FROM "articles" WHERE "articles"."category" = $1 ORDER BY "articles"."id" DESC LIMIT $2  [["category", "tech"], ["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:11
  ActiveStorage::Attachment Load (0.4ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 5]]
  ↳ app/views/articles/index.html.erb:11
  ActiveStorage::Blob Load (0.3ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 4]]
  ↳ app/views/articles/index.html.erb:11
  Article Load (0.4ms)  SELECT "articles".* FROM "articles" WHERE "articles"."category" = $1 ORDER BY "articles"."id" DESC LIMIT $2  [["category", "opinion"], ["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:14
  ActiveStorage::Attachment Load (0.3ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 7]]
  ↳ app/views/articles/index.html.erb:14
  ActiveStorage::Blob Load (0.3ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 6]]
  ↳ app/views/articles/index.html.erb:14
  Article Load (0.4ms)  SELECT "articles".* FROM "articles" WHERE "articles"."category" = $1 ORDER BY "articles"."id" DESC LIMIT $2  [["category", "entertainment"], ["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:17
  ActiveStorage::Attachment Load (0.4ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 4]]
  ↳ app/views/articles/index.html.erb:17
  ActiveStorage::Blob Load (0.3ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 3]]
  ↳ app/views/articles/index.html.erb:17
  Article Load (0.4ms)  SELECT "articles".* FROM "articles" WHERE "articles"."category" = $1 ORDER BY "articles"."id" DESC LIMIT $2  [["category", "business"], ["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:20
  ActiveStorage::Attachment Load (0.3ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 3]]
  ↳ app/views/articles/index.html.erb:20
  ActiveStorage::Blob Load (0.3ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 2]]
  ↳ app/views/articles/index.html.erb:20
  Article Load (0.3ms)  SELECT "articles".* FROM "articles" WHERE "articles"."category" = $1 ORDER BY "articles"."id" DESC LIMIT $2  [["category", "news"], ["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:23
  CACHE ActiveStorage::Attachment Load (0.0ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 8]]
  ↳ app/views/articles/index.html.erb:23
  CACHE ActiveStorage::Blob Load (0.0ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 7]]
  ↳ app/views/articles/index.html.erb:23
  Rendered articles/index.html.erb within layouts/application (Duration: 1568.4ms | Allocations: 49895)
[Webpacker] Everything's up-to-date. Nothing to do
  Rendered layouts/_header.html.erb (Duration: 19.8ms | Allocations: 582)
  Rendered layouts/_footer.html.erb (Duration: 16.5ms | Allocations: 84)
Completed 200 OK in 3424ms (Views: 2653.2ms | ActiveRecord: 455.7ms | Allocations: 65918)


Started GET "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--9f55aa517ef06efb400772224b2ed1ad79fcdc67/national-cancer-institute-gyGyIEeikSw-unsplash.jpg" for ::1 at 2020-06-16 23:27:59 -0400
Started GET "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--6886238f7fdfe7b65d4b612dbce8e767e88f3624/sp.jpg" for ::1 at 2020-06-16 23:28:02 -0400
Processing by ActiveStorage::BlobsController#show as JPEG
  Parameters: {"signed_id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--9f55aa517ef06efb400772224b2ed1ad79fcdc67", "filename"=>"national-cancer-institute-gyGyIEeikSw-unsplash"}
Started GET "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--fa5b18519810daf31d7097e6dc74eb7ec9607911/op.jpg" for ::1 at 2020-06-16 23:28:02 -0400
Started GET "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--047030fb0bd8c1030a39a28c696411b61be3a8dc/te.jpg" for ::1 at 2020-06-16 23:28:02 -0400
Started GET "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f1f125e292037967cb5255b63a84839da9f3b280/ent.jpg" for ::1 at 2020-06-16 23:28:02 -0400
  ActiveStorage::Blob Load (1.1ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 7], ["LIMIT", 1]]
  Disk Storage (1631.0ms) Generated URL for file at key: gt9sqfytys98anvpa736qe55ib5q (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaM1E1YzNGbWVYUjVjems0WVc1MmNHRTNNelp4WlRVMWFXSTFjUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpQVlwcGJteHBibVU3SUdacGJHVnVZVzFsUFNKdVlYUnBiMjVoYkMxallXNWpaWEl0YVc1emRHbDBkWFJsTFdkNVIzbEpSV1ZwYTFOM0xYVnVjM0JzWVhOb0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYm1GMGFXOXVZV3d0WTJGdVkyVnlMV2x1YzNScGRIVjBaUzFuZVVkNVNVVmxhV3RUZHkxMWJuTndiR0Z6YUM1cWNHY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA0LjI1MVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--e66658d231f2906e19dd510a055afc09ef894546/national-cancer-institute-gyGyIEeikSw-unsplash.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22national-cancer-institute-gyGyIEeikSw-unsplash.jpg%22%3B+filename%2A%3DUTF-8%27%27national-cancer-institute-gyGyIEeikSw-unsplash.jpg)
Redirected to http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaM1E1YzNGbWVYUjVjems0WVc1MmNHRTNNelp4WlRVMWFXSTFjUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpQVlwcGJteHBibVU3SUdacGJHVnVZVzFsUFNKdVlYUnBiMjVoYkMxallXNWpaWEl0YVc1emRHbDBkWFJsTFdkNVIzbEpSV1ZwYTFOM0xYVnVjM0JzWVhOb0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYm1GMGFXOXVZV3d0WTJGdVkyVnlMV2x1YzNScGRIVjBaUzFuZVVkNVNVVmxhV3RUZHkxMWJuTndiR0Z6YUM1cWNHY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA0LjI1MVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--e66658d231f2906e19dd510a055afc09ef894546/national-cancer-institute-gyGyIEeikSw-unsplash.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22national-cancer-institute-gyGyIEeikSw-unsplash.jpg%22%3B+filename%2A%3DUTF-8%27%27national-cancer-institute-gyGyIEeikSw-unsplash.jpg
Completed 302 Found in 1642ms (ActiveRecord: 1.1ms | Allocations: 185017)


Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaM1E1YzNGbWVYUjVjems0WVc1MmNHRTNNelp4WlRVMWFXSTFjUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpQVlwcGJteHBibVU3SUdacGJHVnVZVzFsUFNKdVlYUnBiMjVoYkMxallXNWpaWEl0YVc1emRHbDBkWFJsTFdkNVIzbEpSV1ZwYTFOM0xYVnVjM0JzWVhOb0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYm1GMGFXOXVZV3d0WTJGdVkyVnlMV2x1YzNScGRIVjBaUzFuZVVkNVNVVmxhV3RUZHkxMWJuTndiR0Z6YUM1cWNHY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA0LjI1MVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--e66658d231f2906e19dd510a055afc09ef894546/national-cancer-institute-gyGyIEeikSw-unsplash.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22national-cancer-institute-gyGyIEeikSw-unsplash.jpg%22%3B+filename%2A%3DUTF-8%27%27national-cancer-institute-gyGyIEeikSw-unsplash.jpg" for ::1 at 2020-06-16 23:28:04 -0400
Processing by ActiveStorage::DiskController#show as JPEG
  Parameters: {"content_type"=>"image/jpeg", "disposition"=>"inline; filename=\"national-cancer-institute-gyGyIEeikSw-unsplash.jpg\"; filename*=UTF-8''national-cancer-institute-gyGyIEeikSw-unsplash.jpg", "encoded_key"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaM1E1YzNGbWVYUjVjems0WVc1MmNHRTNNelp4WlRVMWFXSTFjUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpQVlwcGJteHBibVU3SUdacGJHVnVZVzFsUFNKdVlYUnBiMjVoYkMxallXNWpaWEl0YVc1emRHbDBkWFJsTFdkNVIzbEpSV1ZwYTFOM0xYVnVjM0JzWVhOb0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYm1GMGFXOXVZV3d0WTJGdVkyVnlMV2x1YzNScGRIVjBaUzFuZVVkNVNVVmxhV3RUZHkxMWJuTndiR0Z6YUM1cWNHY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA0LjI1MVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--e66658d231f2906e19dd510a055afc09ef894546", "filename"=>"national-cancer-institute-gyGyIEeikSw-unsplash"}
Completed 200 OK in 1ms (ActiveRecord: 0.0ms | Allocations: 446)


Processing by ActiveStorage::BlobsController#show as JPEG
  Parameters: {"signed_id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--6886238f7fdfe7b65d4b612dbce8e767e88f3624", "filename"=>"sp"}
Processing by ActiveStorage::BlobsController#show as JPEG
  Parameters: {"signed_id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--047030fb0bd8c1030a39a28c696411b61be3a8dc", "filename"=>"te"}
  ActiveStorage::Blob Load (17.7ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 5], ["LIMIT", 1]]
Processing by ActiveStorage::BlobsController#show as JPEG
  Disk Storage (0.9ms) Generated URL for file at key: g2ke90st65tcfuhjieyucs2tre09 (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaekpyWlRrd2MzUTJOWFJqWm5Wb2FtbGxlWFZqY3pKMGNtVXdPUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5Od0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYzNBdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA0Ljk5NVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--c41100ca601a8bc409e555e7a5434206a3c308b6/sp.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22sp.jpg%22%3B+filename%2A%3DUTF-8%27%27sp.jpg)
Redirected to http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaekpyWlRrd2MzUTJOWFJqWm5Wb2FtbGxlWFZqY3pKMGNtVXdPUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5Od0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYzNBdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA0Ljk5NVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--c41100ca601a8bc409e555e7a5434206a3c308b6/sp.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22sp.jpg%22%3B+filename%2A%3DUTF-8%27%27sp.jpg
  Parameters: {"signed_id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--fa5b18519810daf31d7097e6dc74eb7ec9607911", "filename"=>"op"}
  ActiveStorage::Blob Load (6.8ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 4], ["LIMIT", 1]]
Completed 302 Found in 105ms (ActiveRecord: 18.0ms | Allocations: 8147)


Processing by ActiveStorage::BlobsController#show as JPEG
  Disk Storage (0.9ms) Generated URL for file at key: xa40a03mddiw90t5g0zgcu3hlezc (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhlR0UwTUdFd00yMWtaR2wzT1RCME5XY3dlbWRqZFROb2JHVjZZd1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5SbExtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuZEdVdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA1LjAwNVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--02b924846cb3a78119fce46d0cc6b8e79d028559/te.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22te.jpg%22%3B+filename%2A%3DUTF-8%27%27te.jpg)
  Parameters: {"signed_id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f1f125e292037967cb5255b63a84839da9f3b280", "filename"=>"ent"}
Redirected to http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhlR0UwTUdFd00yMWtaR2wzT1RCME5XY3dlbWRqZFROb2JHVjZZd1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5SbExtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuZEdVdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA1LjAwNVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--02b924846cb3a78119fce46d0cc6b8e79d028559/te.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22te.jpg%22%3B+filename%2A%3DUTF-8%27%27te.jpg
Completed 302 Found in 36ms (ActiveRecord: 13.0ms | Allocations: 8653)


  ActiveStorage::Blob Load (1.9ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 6], ["LIMIT", 1]]
  Disk Storage (0.7ms) Generated URL for file at key: u2ibz9joa1bggou2g0dv5uc6itpy (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhkVEpwWW5vNWFtOWhNV0puWjI5MU1tY3daSFkxZFdNMmFYUndlUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW05d0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYjNBdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA1LjAyMloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--2a52ba2e0974eabcb0333eee93bf86e62aa072bb/op.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22op.jpg%22%3B+filename%2A%3DUTF-8%27%27op.jpg)
Redirected to http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhkVEpwWW5vNWFtOWhNV0puWjI5MU1tY3daSFkxZFdNMmFYUndlUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW05d0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYjNBdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA1LjAyMloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--2a52ba2e0974eabcb0333eee93bf86e62aa072bb/op.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22op.jpg%22%3B+filename%2A%3DUTF-8%27%27op.jpg
Completed 302 Found in 29ms (ActiveRecord: 4.9ms | Allocations: 6248)


Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaekpyWlRrd2MzUTJOWFJqWm5Wb2FtbGxlWFZqY3pKMGNtVXdPUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5Od0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYzNBdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA0Ljk5NVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--c41100ca601a8bc409e555e7a5434206a3c308b6/sp.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22sp.jpg%22%3B+filename%2A%3DUTF-8%27%27sp.jpg" for ::1 at 2020-06-16 23:28:05 -0400
Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhlR0UwTUdFd00yMWtaR2wzT1RCME5XY3dlbWRqZFROb2JHVjZZd1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5SbExtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuZEdVdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA1LjAwNVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--02b924846cb3a78119fce46d0cc6b8e79d028559/te.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22te.jpg%22%3B+filename%2A%3DUTF-8%27%27te.jpg" for ::1 at 2020-06-16 23:28:05 -0400
Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhkVEpwWW5vNWFtOWhNV0puWjI5MU1tY3daSFkxZFdNMmFYUndlUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW05d0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYjNBdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA1LjAyMloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--2a52ba2e0974eabcb0333eee93bf86e62aa072bb/op.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22op.jpg%22%3B+filename%2A%3DUTF-8%27%27op.jpg" for ::1 at 2020-06-16 23:28:05 -0400
Processing by ActiveStorage::DiskController#show as JPEG
  Parameters: {"content_type"=>"image/jpeg", "disposition"=>"inline; filename=\"sp.jpg\"; filename*=UTF-8''sp.jpg", "encoded_key"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaekpyWlRrd2MzUTJOWFJqWm5Wb2FtbGxlWFZqY3pKMGNtVXdPUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5Od0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYzNBdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA0Ljk5NVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--c41100ca601a8bc409e555e7a5434206a3c308b6", "filename"=>"sp"}
Completed 200 OK in 2ms (ActiveRecord: 0.0ms | Allocations: 419)


Processing by ActiveStorage::DiskController#show as JPEG
Processing by ActiveStorage::DiskController#show as JPEG
  Parameters: {"content_type"=>"image/jpeg", "disposition"=>"inline; filename=\"te.jpg\"; filename*=UTF-8''te.jpg", "encoded_key"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhlR0UwTUdFd00yMWtaR2wzT1RCME5XY3dlbWRqZFROb2JHVjZZd1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5SbExtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuZEdVdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA1LjAwNVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--02b924846cb3a78119fce46d0cc6b8e79d028559", "filename"=>"te"}
  Parameters: {"content_type"=>"image/jpeg", "disposition"=>"inline; filename=\"op.jpg\"; filename*=UTF-8''op.jpg", "encoded_key"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhkVEpwWW5vNWFtOWhNV0puWjI5MU1tY3daSFkxZFdNMmFYUndlUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpTjJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW05d0xtcHdaeUk3SUdacGJHVnVZVzFsS2oxVlZFWXRPQ2NuYjNBdWFuQm5CanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lQYVcxaFoyVXZhbkJsWndZN0JsUT0iLCJleHAiOiIyMDIwLTA2LTE3VDAzOjMzOjA1LjAyMloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--2a52ba2e0974eabcb0333eee93bf86e62aa072bb", "filename"=>"op"}
Completed 200 OK in 1ms (ActiveRecord: 0.0ms | Allocations: 385)


Completed 200 OK in 3ms (ActiveRecord: 0.0ms | Allocations: 720)


  ActiveStorage::Blob Load (16.7ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  Disk Storage (0.8ms) Generated URL for file at key: io5qey217t7eumab7ly2dw81y9cd (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhhVzgxY1dWNU1qRTNkRGRsZFcxaFlqZHNlVEprZHpneGVUbGpaQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpT1dsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1WdWRDNXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSjJWdWRDNXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWQT09IiwiZXhwIjoiMjAyMC0wNi0xN1QwMzozMzowNS4wNjJaIiwicHVyIjoiYmxvYl9rZXkifX0=--f265e894e1b5b0f8d7ab481c2c9a13058bba98c5/ent.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22ent.jpg%22%3B+filename%2A%3DUTF-8%27%27ent.jpg)
Redirected to http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhhVzgxY1dWNU1qRTNkRGRsZFcxaFlqZHNlVEprZHpneGVUbGpaQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpT1dsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1WdWRDNXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSjJWdWRDNXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWQT09IiwiZXhwIjoiMjAyMC0wNi0xN1QwMzozMzowNS4wNjJaIiwicHVyIjoiYmxvYl9rZXkifX0=--f265e894e1b5b0f8d7ab481c2c9a13058bba98c5/ent.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22ent.jpg%22%3B+filename%2A%3DUTF-8%27%27ent.jpg
Completed 302 Found in 55ms (ActiveRecord: 42.7ms | Allocations: 11728)


Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhhVzgxY1dWNU1qRTNkRGRsZFcxaFlqZHNlVEprZHpneGVUbGpaQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpT1dsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1WdWRDNXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSjJWdWRDNXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWQT09IiwiZXhwIjoiMjAyMC0wNi0xN1QwMzozMzowNS4wNjJaIiwicHVyIjoiYmxvYl9rZXkifX0=--f265e894e1b5b0f8d7ab481c2c9a13058bba98c5/ent.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22ent.jpg%22%3B+filename%2A%3DUTF-8%27%27ent.jpg" for ::1 at 2020-06-16 23:28:05 -0400
Processing by ActiveStorage::DiskController#show as JPEG
  Parameters: {"content_type"=>"image/jpeg", "disposition"=>"inline; filename=\"ent.jpg\"; filename*=UTF-8''ent.jpg", "encoded_key"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhhVzgxY1dWNU1qRTNkRGRsZFcxaFlqZHNlVEprZHpneGVUbGpaQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpT1dsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1WdWRDNXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSjJWdWRDNXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWQT09IiwiZXhwIjoiMjAyMC0wNi0xN1QwMzozMzowNS4wNjJaIiwicHVyIjoiYmxvYl9rZXkifX0=--f265e894e1b5b0f8d7ab481c2c9a13058bba98c5", "filename"=>"ent"}
Completed 200 OK in 2ms (ActiveRecord: 0.0ms | Allocations: 381)


Started GET "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--544bef348f3d127d4acd0aa7ab89130d259f66d7/bus.jpg" for ::1 at 2020-06-16 23:28:06 -0400
Processing by ActiveStorage::BlobsController#show as JPEG
  Parameters: {"signed_id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--544bef348f3d127d4acd0aa7ab89130d259f66d7", "filename"=>"bus"}
  ActiveStorage::Blob Load (187.2ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
  Disk Storage (19.4ms) Generated URL for file at key: lvy6kstuagdd15xon9wh9mm4usgt (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhiSFo1Tm10emRIVmhaMlJrTVRWNGIyNDVkMmc1YlcwMGRYTm5kQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpT1dsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1KMWN5NXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSjJKMWN5NXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWQT09IiwiZXhwIjoiMjAyMC0wNi0xN1QwMzozMzowNi43MDhaIiwicHVyIjoiYmxvYl9rZXkifX0=--3ed8fff7c6cfe9eb65e3f4a2dc12ef4154a6b6c6/bus.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22bus.jpg%22%3B+filename%2A%3DUTF-8%27%27bus.jpg)
Redirected to http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhiSFo1Tm10emRIVmhaMlJrTVRWNGIyNDVkMmc1YlcwMGRYTm5kQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpT1dsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1KMWN5NXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSjJKMWN5NXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWQT09IiwiZXhwIjoiMjAyMC0wNi0xN1QwMzozMzowNi43MDhaIiwicHVyIjoiYmxvYl9rZXkifX0=--3ed8fff7c6cfe9eb65e3f4a2dc12ef4154a6b6c6/bus.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22bus.jpg%22%3B+filename%2A%3DUTF-8%27%27bus.jpg
Completed 302 Found in 270ms (ActiveRecord: 187.2ms | Allocations: 1878)


Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhiSFo1Tm10emRIVmhaMlJrTVRWNGIyNDVkMmc1YlcwMGRYTm5kQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpT1dsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1KMWN5NXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSjJKMWN5NXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWQT09IiwiZXhwIjoiMjAyMC0wNi0xN1QwMzozMzowNi43MDhaIiwicHVyIjoiYmxvYl9rZXkifX0=--3ed8fff7c6cfe9eb65e3f4a2dc12ef4154a6b6c6/bus.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22bus.jpg%22%3B+filename%2A%3DUTF-8%27%27bus.jpg" for ::1 at 2020-06-16 23:28:06 -0400
Processing by ActiveStorage::DiskController#show as JPEG
  Parameters: {"content_type"=>"image/jpeg", "disposition"=>"inline; filename=\"bus.jpg\"; filename*=UTF-8''bus.jpg", "encoded_key"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhiSFo1Tm10emRIVmhaMlJrTVRWNGIyNDVkMmc1YlcwMGRYTm5kQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpT1dsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1KMWN5NXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSjJKMWN5NXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWQT09IiwiZXhwIjoiMjAyMC0wNi0xN1QwMzozMzowNi43MDhaIiwicHVyIjoiYmxvYl9rZXkifX0=--3ed8fff7c6cfe9eb65e3f4a2dc12ef4154a6b6c6", "filename"=>"bus"}
Completed 200 OK in 5818ms (ActiveRecord: 0.0ms | Allocations: 405)

如何减少此页面的加载时间?

标签: ruby-on-rails

解决方案


Rails 日志是一个非常有用但经常被忽视的东西。一开始它可能看起来像胡言乱语,所以让我们看一下它的减速;在Processing by ArticlesController#index as HTML它开始呈现您的索引页面之后。

它做的第一件事:

Article Load (149.4ms)  SELECT "articles".* FROM "articles" ORDER BY "articles"."id" DESC LIMIT $1  [["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:2

向您展示正在调用的数据库查询(获取最后一篇文章)、需要多长时间(149 毫秒)以及由于您在 index.html.erb 的第 2 行上的代码而需要它。而且,在第 2 行你有@articles.last.image- 这导致了数据库查询。

149 毫秒,没什么大不了的……坚持我,这是一段旅程。

它做的下一件事是另外 2 个 DB 查询,也是由第 2 行引起的

ActiveStorage::Attachment Load (102.9ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 8]]
  ↳ app/views/articles/index.html.erb:2
ActiveStorage::Blob Load (33.3ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 7]]
  ↳ app/views/articles/index.html.erb:2

这一次,它正在获取图像资源,这又需要 102 毫秒 + 33 毫秒。但是,您的控制器用于Model.with_attached_image预加载图像,不是吗?好吧,显然那是行不通的。看看https://jasoncharnes.com/eager-loading-querying-against-activestorage-attachments/以获得一个很好的预加载指南。

我想你.all放错地方了。您应该使用Model.with_attached_image.all而不是Model.all.with_attached_image.

但是,还有更多...

接下来,视图中的第 4 行需要 3 个 DB 查询:

CACHE Article Load (0.0ms)  SELECT "articles".* FROM "articles" ORDER BY "articles"."id" DESC LIMIT $1  [["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:4
  CACHE ActiveStorage::Attachment Load (0.0ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 8]]
  ↳ app/views/articles/index.html.erb:4
  CACHE ActiveStorage::Blob Load (0.0ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 7]]
  ↳ app/views/articles/index.html.erb:4

但是,请注意这些都需要 0.0ms 并被缓存。那是因为第 2 行引起的先前查询已经从数据库中获取了该数据。出色的!

在开发过程中,请留意日志中的此类详细信息。请注意,当行以 CACHE 开头时,这很好。

然后,您有 15 个由第 8、11、14、17 和 20 行引起的未缓存数据库查询,您使用类别范围获取数据,而无需预加载图像数据 ( @articles.business.last.image)。因此,每个范围调用都会进行 3 个数据库查询。

Article Load (0.3ms)  SELECT "articles".* FROM "articles" WHERE "articles"."category" = $1 ORDER BY "articles"."id" DESC LIMIT $2  [["category", "sports"], ["LIMIT", 1]]
  ↳ app/views/articles/index.html.erb:8

  ActiveStorage::Attachment Load (0.5ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Article"], ["name", "image"], ["record_id", 6]]
  ↳ app/views/articles/index.html.erb:8

  ActiveStorage::Blob Load (0.3ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 5]]
  ↳ app/views/articles/index.html.erb:8

希望这已经向您展示了如何在日志中发现时间的去向。

要开始修复它,请从小处着手。拨打电话获取上一篇文章数据和图片

控制器

@latest_article = Articles.with_attached_image.last

看法

<div class="main" style="background-image: url(<%= (url_for(@latest_article.image)) %>)">
  <div class="top-article" >
    <h2><%= @latest_article.title %></h2>
    <p><%= link_to "Read more..." %></p>
  </div>
</div>

这应该使第 2 行和第 4 行的 3 个 DB 查询减少到 1 个查询。检查日志,看看它是如何改变的。

接下来是范围查询。

您可以在控制器中创建对每个类别的显式调用,并在每个类别中预取图像数据:

@tech_article = Article.with_attached_image.where(category: 'tech').last
@news_article = Article.with_attached_image.where(category: 'news').last
# and so on...

这样一来,每个类别都会有一个 DB 调用 - 少于 15 个

但我注意到您只显示这些图像,而不是标题。这只是为了简洁起见吗?

理想情况下,您希望将这一切归结为只有 1 个 DB 查询;但这需要一个嵌套的 SQL 查询;这甚至可以保证自己的问题。

生产部署注意事项

在生产环境中,对图像的所有 GET 调用都将比在开发环境中加载快得多。也许将它在线放到一个隐藏的页面上,这样您就可以看到它在生产中的表现 - 一旦您将数据库查询减少到 1 或 2

在开发中,您从单个服务器线程提供所有服务;所以一切都一个接一个地发生。在生产环境中,对图像的请求(日志中的所有 GET 请求,除了索引的第一个 GET 请求)将同时进行。这将对您看到的 15 秒加载时间产生巨大影响。


推荐阅读