Bài 9: Performance Optimization và Caching
Tầm quan trọng của Optimization
Tối ưu hóa hiệu suất là một phần quan trọng trong việc phát triển ứng dụng Rails, đặc biệt khi ứng dụng phát triển và số lượng người dùng tăng lên.
Database Optimization
Indexing
Indexing là một trong những cách hiệu quả nhất để cải thiện hiệu suất truy vấn.
class AddIndexToUsersEmail < ActiveRecord::Migration[6.1]
def change
add_index :users, :email
end
end
Query Optimization
Sử dụng các phương pháp như eager loading để tránh N+1 queries:
# Thay vì
@posts = Post.all
@posts.each do |post|
puts post.user.name
end
# Sử dụng
@posts = Post.includes(:user)
@posts.each do |post|
puts post.user.name
end
Explain Queries
Sử dụng explain
để phân tích và tối ưu các truy vấn phức tạp:
User.where(status: 'active').explain
Caching Strategies
Rails cung cấp nhiều cách để implement caching.
Page Caching
Page caching lưu trữ toàn bộ output của một request.
class WelcomeController < ApplicationController
caches_page :index
def index
# ...
end
end
Action Caching
Action caching tương tự như page caching nhưng vẫn chạy qua before filters.
class ProductsController < ApplicationController
caches_action :index, :show
def index
@products = Product.all
end
end
Fragment Caching
Fragment caching cho phép bạn cache một phần của view.
<% cache @product do %>
<h1><%= @product.name %></h1>
<p><%= @product.description %></p>
<% end %>
Russian Doll Caching
Russian Doll Caching là kỹ thuật nested fragment caching.
<% cache @post do %>
<%= @post.title %>
<% @post.comments.each do |comment| %>
<% cache comment do %>
<%= comment.body %>
<% end %>
<% end %>
<% end %>
Low-Level Caching
Sử dụng Rails.cache để lưu trữ bất kỳ dữ liệu nào.
Rails.cache.fetch("user_#{user.id}", expires_in: 12.hours) do
user.calculate_expensive_stat
end
Background Jobs
Sử dụng background jobs để xử lý các tác vụ nặng và không đồng bộ.
class HardWorker
include Sidekiq::Worker
def perform(user_id)
user = User.find(user_id)
user.process_large_data
end
end
HardWorker.perform_async(user.id)
Rack Mini Profiler
Rack Mini Profiler là một gem hữu ích để phân tích hiệu suất ứng dụng Rails.
# Gemfile
gem 'rack-mini-profiler'
Bullet
Bullet giúp phát hiện và sửa các N+1 queries.
# Gemfile
gem 'bullet', group: 'development'
# config/environments/development.rb
config.after_initialize do
Bullet.enable = true
Bullet.alert = true
Bullet.bullet_logger = true
Bullet.console = true
end
Memcached hoặc Redis
Sử dụng Memcached hoặc Redis làm backend cho caching để cải thiện hiệu suất.
# config/environments/production.rb
config.cache_store = :mem_cache_store
# hoặc
config.cache_store = :redis_cache_store, { url: ENV['REDIS_URL'] }
Asset Pipeline Optimization
Tối ưu hóa Asset Pipeline để giảm thời gian tải trang.
# config/environments/production.rb
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = false
Content Delivery Network (CDN)
Sử dụng CDN để phân phối assets nhanh hơn.
# config/environments/production.rb
config.action_controller.asset_host = 'http://assets.example.com'
Database Connection Pooling
Cấu hình connection pooling để quản lý kết nối database hiệu quả.
# config/database.yml
production:
adapter: postgresql
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
Query Caching
Rails tự động cache các truy vấn trong một request.
User.where(name: 'John').to_a
# Truy vấn database lần đầu
User.where(name: 'John').to_a
# Sử dụng cache, không truy vấn database
Monitoring và Profiling
Sử dụng các công cụ như New Relic hoặc Scout để monitor và profile ứng dụng trong production.
Best Practices
- Luôn đo lường trước và sau khi tối ưu.
- Tập trung vào các bottlenecks lớn nhất trước.
- Cẩn thận với premature optimization.
- Sử dụng các công cụ profiling để xác định vấn đề thực sự.
- Cân nhắc giữa performance và maintainability của code.
Kết luận
Tối ưu hóa hiệu suất là một quá trình liên tục trong phát triển ứng dụng Rails. Bằng cách áp dụng các kỹ thuật caching, tối ưu hóa database, và sử dụng các công cụ phù hợp, bạn có thể cải thiện đáng kể hiệu suất của ứng dụng.
Trong thực tế, việc tối ưu hóa đòi hỏi sự cân bằng giữa hiệu suất, tính bảo trì, và thời gian phát triển. Điều quan trọng là phải hiểu rõ về ứng dụng của bạn, các patterns sử dụng, và nhu cầu của người dùng để áp dụng các kỹ thuật tối ưu hóa một cách hiệu quả nhất.
Trong bài cuối cùng, chúng ta sẽ tìm hiểu về Deployment và Best Practices trong Rails, khám phá cách đưa ứng dụng Rails của bạn lên production một cách an toàn và hiệu quả.