Làm sao cải thiện tốc độ JSON Generation trong Rails

Hiện nay, chúng ta biết một số cách để tạo đối tượng trong JSON

  • Dùng to_json()
  • RABL
  • Active model serialisers
  • JBuilder

1. JBuilder

json.extract! message, :id, :content, :chat_id
json.user do
   json.cache!(["user_", message.user_id]) do
      json.partial! 'users/user', user: message.user
      end
end

2. RABL

So với những phương pháp khác thì RABL như kiểu ở 1 đẳng cấp khác, cú pháp quá cũ kỹ, lỗi thời, nói chung là khá tệ. Bây giờ hầu như cũng chả ai dùng nữa, chủ yếu là tìm hiểu cho biết thôi.

collection :@messages
attributes :id, :content, :chat_id
child(:user) { attributes :name }
node(:read) { |message| message.read_by?(@user) }

3. ActiveModel::Serializer

Active model serializers được tạo ra với mục đích tạo ra JSON như là 1 class Ruby, mà không cần bất cứ 1 cú pháp bổ trợ nào khác. Điều này sẽ giúp cho lập trình viên có thể kết hợp nhiều DSL(Domain Specific Language) khác nhau một cách dễ dàng hơn

4. Giải pháp cho vấn đề hiệu suất khi hoạt động với JSON

Tạo 1 bài test đơn giản: 1000 messages Cú pháp JSON:

{
id: 1,
content: "Lorem",
chat_id: 1,
created_at: "2014-06-18T21:47:49.363Z",
kind: 0,
formatted_content: "<span>Lorem</span>",
user: {
   id: 1,
   name: "John Smith",
   image: "https://lh6.googleusercontent.com/photo.jpg"
},
files: [ ],
links: [ ]
}

to_json: 0.2 ms JBuilder: 129.0 ms JBuilder with OJ: 88.0 ms

So sánh là khập khiễng, nhưng khách quan mà nói, JBuilder vẫn là 1 trong những phương pháp quen thuộc và dễ dùng nhất. Cái giá cho việc dễ dùng là tốc độ, to_json mặc dù không rõ ràng nhưng lại là phương pháp nhanh nhất Sử dụng JBuilder mà không có các setting khác sẽ ngốn mất gần 600ms Cho nên nếu như bạn là kiểu người chỉ muốn làm cái gì đó mà bạn thật sự hiểu rõ ràng, hoặc giả đã quá quen thuộc với JBuilder hay là vì yêu cầu dự án mà phải sử dụng nó, mình có một số phương pháp tối ưu hóa cho bạn:

  • Sử dụng một số gems: oj, oj_mimic_json, multi_json. Thêm phần MultiJson.use( : oj ) vào, điều này sẽ giúp bạn tăng chút tốc độ
  • Không sử dụng partial, vì nó sẽ làm chậm JBuilder(mình đang làm 1 dự án và thấy rõ vụ này). Vấn đề này ai cũng thấy rõ, nhưng vẫn đang được bỏ ngỏ lâu nay, không dễ gì để giải quyết
  • Sử dụng cache trong JBuilder

5. Kết luận

Với sự hỗ trợ ngày càng nhiều của Rails, mình khuyến khích mọi người chuyển dần từ thói quen sử dụng JBuilder sang dùng to_json() chỉ vì dễ hiểu hay quen tay, vì nó thật sự nhanh, dễ dùng, và tối ưu hóa hơn. Nhưng nếu như buộc phải sử dụng JBuilder thì hãy luôn tìm cách tối ưu hóa nó, vì mặc định nó chậm như thế nào thì bạn cũng thấy rõ ở trên rồi đấy. Chúc mọi người làm việc tốt với Rails nói chung và JSON nói riêng Nguồn: Grigorii Liubachev Blog