10 mẹo để có thể nâng cao hiệu năng trong project ruby on rails của bạn
Như các bạn đã biết thì hiệu năng là một điều rất quan trọng với các sản phẩm công nghệ nói chung và các project Ruby on Rails nói riêng đặc biệt là các sản phẩm lớn có khối lượng truy cập lớn liên tục thì chỉ với một số mẹo nhỏ thôi cũng đã khiếp cho sản phẩm của bạn đã có một sự thay đổi rõ rệt ...
Như các bạn đã biết thì hiệu năng là một điều rất quan trọng với các sản phẩm công nghệ nói chung và các project Ruby on Rails nói riêng đặc biệt là các sản phẩm lớn có khối lượng truy cập lớn liên tục thì chỉ với một số mẹo nhỏ thôi cũng đã khiếp cho sản phẩm của bạn đã có một sự thay đổi rõ rệt rồi. Trong bài viết này tôi sẽ giới thiệu cho các bạn các mẹo cơ bản để nâng cao hiệu năng hoạt động của Ruby on rails app.
Giới hạn một số dữ liệu trong controller.
Với một controller rất dễ để có thể kiểm thử và xử lý để có một hiệu năng tốt. Bởi vì các bước xử lý dữ liệu đều thông qua đây. Các bạn cần tinh giảm số lượng dữ liệu cần thiết để sử dụng, tránh lặp đi lặp lại những biến hay phần code không cần thiết - Don't repeat yourself (DRY) có như vậy thì sẽ tăng được hiệu năng đáng kể của sản phẩm. Và các bạn nên nhớ một điều trong MVC nói chung đó là "Thin controller fat model"
Chia nhỏ view thành các partial riêng
Với cách này, điều làm như thế này sẽ giúp cho bạn sẽ có thể quản lý source code tốt hơn, chia để trị. Những phần đặc thủ cho từng function sẽ được tách riêng ra, hay những phần được tại sử dụng nhiều lần (reuse) sẽ được tách ra và share cho nhiều phần khác của dự. Dễ đọc và dễ lưu và sử dụng cache hơn rất nhiều so với việc cho tất cả code vào 1 file view, rất khó maintain lần xử lý.
Form partial
<%= form_for(@post) do |f| %> <% if @post.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2> <ul> <% @post.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :title %><br /> <%= f.text_field :title %> </div> <div class="field"> <%= f.label :body %><br /> <%= f.text_area :body %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>
New view
<h1>New post</h1> <%= render 'form' %> <%= link_to 'Back', posts_path %>
Edit view
<h1>Editing post</h1> <%= render 'form' %> <%= link_to 'Back', posts_path %>
Các bạn có thể thấy rõ ràng là khi làm việc với trường hợp trên, vừa có thể reuse 1 form cho cả 2 trang new và edit, và chỉ với 1 công sửa bạn sẽ xử lý được cả 2 trang, giảm thời gian, bớt effort vào những công việc không cần thiết, và xử lý code sẽ dễ hơn rất nhiều nếu form của bạn có vấn đề
Lựa chọn Session storage cần thiết
Dựa trên nhu cầu của bạn, cần chọn session storage một cách cẩn thận, vì nếu không sử dụng cần thận sẽ dẫn đến tràn bộ nhớ và ảnh hưởng rất nhiều đến performance, đặc biệt là các thiết bị di động.
- CookieStore - lưu trữ mọi thứ trên client của bạn
- DRbStore - lưu trữ toàn bộ dữ liệu trên DRb server
- MemCacheStore - lưu trữ dữ liệu ở memcache
- ActiveRecordStore - lưu trữ dữ liệu trong database bằng cách sử dụng Active Record
DRY (Dont't repeat yourself)
Đây là điều phổ biết nhất mà các lập trình viên cần tránh. Đó là không lặp lại code quá nhiều. với những đoạn code lặp bạn có thể refactor, viết lại cho ngắn hơn phù hợp hơn với các câu điều kiện v..v.. hoặc là tại ra một file lưu trữ các common function hay sử dụng, để tránh lặp lại những điều bạn gặp phải
if(Player.find_by_id(1).name == "Tamim") return Player.find_by_id(1) else return nil end
Bạn nên viết lại là
player = Player.find_by_id(1) if(player.name == "Tamim") then player else nil end
Eager loading.
Chắc hẳn các bạn đã nghe về N+1 query performance problem. Và đặc biệt trong RoR project điều này rất được chú trọng và tránh mắc phải vì nó ảnh hưởng rất nhiều đến thời gian xử lý của hệ thống.
Chúng ta sẽ đến với 1 đoạn code để ra zip của user
users = User.all(:limit => 10) users.each do |user| puts user.address.zip end
Vậy là, 11 queríe đã được thực hiện. Và để giải quyết vấn đề này thì RoR có cung cấp một số hàm với mục đích tránh N+1 querries và để load các dữ liệu cần thiết trước khi trả về view, includes(), eager_load(), preload()
users = User.includes(:address).limit(10) users.each do |user| puts user.address.zip end
Ngoài ra bạn có thể sử dụng gem bullet để có thể phát hiện được N+1 query dễ dàng hơn
Indexing
Databáe indexing là một trong những cách đơn giản nhất để có thể nâng cao hiệu năng của database. Các câu lệnh insert sẽ chậm hơn nhưng sẽ tăng tốc việc fetching dữ liệu, đó là một điều nên làm thường xuyên đối với một web application
Tránh các câu lệnh mang thiên hướng động (Dynamism)
Mặc dù find_by hoặc find_all_by method sử dụng thật tuyện vời, nhưng chúng là nguyên nhân làm cho hệ thống bị chậm đi bởi vì với mỗi câu lệnh thì cần chạy qua các method_missiong và parse filename để chống lại việc list các cột trong database table.
Caching
Đây là cách "đúng chất Rails" nhất để tăng tốc rails application. Dưới đây là một số ví dụ về các loại caching
- Page Caching
- Action Caching
- Fragment Caching:
- SQL Caching
- Asset caching
Sử dụng CDN
CDN gọi tắt của content delivery network dùng thay thế cho việc bạn tải cả file js, css và lưu vào hệ thống. Thay vào đó, máy hệ thống của bạn sẽ tự kết nối với các library thì sẽ tăng tốc được hệ thống. Mặc dù có một nhược điểm nho nhỏ là sẽ hơi phụ thuộc vào nhà cung cấp dịch vụ.
Bạn có thể sử dụng CDN từ Amazon Cloudfront hoặc Rackspace cloud files
Image spriting
Ở trong các website, có một khoảng thời gian khá lớn để load các asset, đặc biệt là ảnh. Đây chính là một cách để minimize, sprite ảnh của bạn. Chúng sẽ làm giảm số lượng ảnh một cách đáng kể
Sử dụng Minify và Gzip stylesheet và javascripts
Điều cuối cùng, nhưng cũng rất quan trọng đó là phải làm giảm kích thước của các file stylesheét và javácript một cách đáng kể bằng Minifying. Chúng sẽ nâng cao hiệu năng rất là nhiều thông qua việc làm giảm thời gian request/response
Qua đây mình đã giới thiệu cho các bạn 10 cách để có thể làm tăng tốc độ RoR application nói chung và các sản phẩm phần miềm nói riêng. Trong bài viết tới, mình sẽ viết kỹ và phân tích rõ ràng về từng cách tăng tốc độ xử lý ra sao.