Hỏi cách tăng tốc cho response flask

Chào mọi người, mình đang làm 1 app bằng Flask và React JS. Mình đang gặp vấn đề là request mất quá nhiều thời gian để phản hồi (gần 1 phút lận). Reponse này 20.4MB. Khó khăn là mình không được dùng phân trang nữa nên lên đây xin được nhờ mọi người chỉ giáo.
Mình xin chân thành cảm ơn.

Update:
Q: Tại sao có trường hợp ngớ ngẩn này ?
A: Do ban đầu mình không nghĩ là có quá nhiều dữ liệu như vậy nên design đã ‘tạch’. Tới giờ khi deploy lên product thì mình mới thấy mình sai từ đầu. Đây là bài học đắt giá của mình phân tích quá kém.

Q: Cái quái gì mà tận 20MB, rồi có khi nào lớn hơn không vậy ?
A: Nôm na là như tụi mình đang làm 1 app giống như quản lý nhà sách chẳng hạn. Người dùng họ muốn là hiển thị dạng cây, mà thốn cái là họ muốn show lên hết như thế này.

|-Nhà xuất bản
|--Loại sách
|----Tác giả
|------Sách 

Vâng, vấn đề chính là ở đây, hiện tại có hơn 100 nhà xuất bản, mỗi nhà xuất bản có nhiều loại sách, mà mỗi loại sách thì có nhiều tác giả và tương sự mỗi ông tác giả ôm cả đống sách. Đầu tiên mình làm là khi nhấp vô nhà xuất bản nào đó, nó sẽ call API để load các loại sách đó và tương tự với các level khác. ̶N̶̶h̶̶ư̶̶n̶̶g̶ ̶k̶̶h̶̶á̶̶c̶̶h̶ ̶h̶̶à̶̶n̶̶g̶ ̶c̶̶h̶̶ả̶ ̶h̶̶i̶̶ể̶̶u̶ ̶s̶̶a̶̶o̶ ̶h̶̶ọ̶ ̶k̶̶h̶̶ô̶̶n̶̶g̶ ̶c̶̶h̶̶ị̶̶u̶ ̶h̶̶ọ̶ ̶m̶̶u̶̶ố̶̶n̶ ̶s̶̶h̶̶o̶̶w̶ ̶l̶̶ê̶̶n̶ ̶h̶̶ế̶̶t̶ ̶m̶̶ớ̶̶i̶ ̶c̶̶h̶̶ị̶̶u̶ Do mỗi lần click vô nó call API load rõ lâu, người dùng không thích như vậy.

Mình nói là mình “đã tối ưu hóa json hết cỡ” là vì mình đã bỏ toàn bộ các trường không cần thiết rồi nhưng nó vẫn bự. Hiện tại thì ứng dụng chạy cũng ổn rồi, nhưng mà bị cái thời gian load trang này thốn quá, đầu tiên nó load cả mấy phút, ngồi cố lắm mới được như thế này, nhưng vẫn chưa được ngon lắm. Hiện tại mình đang muốn khách hàng có cái dùng trước, vẫn còn 1 chút thời gian nên mình muốn tối ưu hóa thêm phần này.

Q: Rồi thế sao không phân trang đi cho khỏe, chi mà cực vậy ?
A: Căn bản là mình không có được trực tiếp làm database, chỉ được dùng API của bên nào đó thiết kế trước thôi để hành sự thôi, mà mỗi lần nó query cũng tốn khá khá thời gian. Ví dụ khách hàng họ muốn thêm cái cuốn sách nào đó, dùng API gọi xem đã có cuốn sách đó chưa nó cũng tốn khá nhiều thời gian nên khách hàng không thích lắm, họ muốn “kích là chạy”, nên mình đang dùng giải pháp là load lên hết rồi store vào trong redux, cần dùng gì lôi ra dùng nên không có phân trang được. Mình đang tính tới việc là dùng 1 database phụ trợ như sql lite, cho nó load thông tin vô sql lite rồi mình thao tác trên đó nhưng thời gian còn lại hơi ít chưa kịp triển khai cho đợt này.

Q: App vớ app vẩn, thiết kế vậy thì nghỉ chơi.
A: Yeah, mình nghe câu này nhiều rồi, nhưng lỡ rồi biết làm sao đây.

1 Like

load gì mà kinh vậy bạn, xem có trường nào dư thì bỏ bớt đi, chỉ load những phần nào cần thiết thôi

4 Likes

Mình cũng đã cố rồi bạn, đây là điều kiện lý tưởng nhất của mình rồi bạn.

Thế thì chịu, chỉ có load những dữ liệu cần thiết, load dần các dữ liệu còn lại thôi. Chứ 25MB mà mạng đểu nữa thì đến mùa quýt

4 Likes

Xem biểu đồ có thể thấy thời gian chờ cũng chiếm gần 1 nửa, cái này chắc là bạn load dữ liệu từ 1 bên nào đó nữa. Dấu hiệu cho thấy kiến trúc code đang cực kì có vấn đề

5 Likes

mất tới hơn 26s để download mớ dữ liệu đó, dù server có phản hồi nhanh kiểu gì thì cũng không thể nào nhanh hơn 26s được

20.4MB là bao nhiêu record?
mục đích load dùng để làm gì mà không phân trang? show hết?
các thím lúc nào cũng bảo tối ưu các kiểu mà ngay từ cái design đã tạch rồi

5 Likes

Đúng là từ design đã tạch rồi nhưng giờ đâu “đập đi làm lại” được bạn, load hết vì 1 số ràng buộc bắt buộc phải load bạn à, mình cũng muốn phân trang lắm chứ nhưng với yêu cầu hiện tại thì nó bất khả kháng bạn ạ.

Hi @hoalaxanh123,

Mình hỏi chút:

  1. Request của cậu để lấy thông tin gì vậy? Tại sao nó có tới 25MB? Thông tin đó có thay đổi thường xuyên không?
  2. Ràng buộc gì khiến cậu phải load hết vậy?
  3. Tại sao thời gian chờ lại mất tới 19s?
  4. Design của phần này như thế nào? Cậu có thể tóm tắt cho bọn tớ được không?

Tớ mong nhận được câu trả lời của cậu.

6 Likes

ở đây chưa nói tới chuyện đập đi làm lại
bạn cần hiểu là dù cho bạn có response 1ms, thì hơn 20MB dữ liệu đó vẫn phải mất tới 26s mới tới client
và rất nhiều người vẫn đang cùng thắc mắc là 20MB dữ liệu đó phục vụ cho việc gì, và bạn đang làm gì mà lại mất gần 19s cho việc xử lý
còn không thì có tối ưu code cách mấy vẫn phải hơn 26s mà thôi

lời khuyên, bạn tự đọc lại topic của bạn thử xem, ngoài việc chụp cái timeline ra thì có thông tin nào để người khác đoán nguyên nhân và hỗ trợ không?

4 Likes

ko cho phân trang thì làm theo kiểu kéo chuột tới đâu load tới đó ấy. 20MB chia làm 100 phần, mỗi phần 200KB, phần client thì xài js detect kéo chuột tới cuối trang thì load tiếp trang kế :V

4 Likes

Để biết cách “tăng tốc” thì phải biết là request cái gì, đang xử lý request như thế nào và response về cái gì.

Chứ với thông tin như trong bài, thì mình nghĩ mọi người chỉ đoán mò dựa trên kinh nghiệm cá nhân thôi.

5 Likes

2 posts were merged into an existing topic: Duplicate posts will be moved here

Mình có update lại trên post đầu, bạn đọc thử nhé. Cách này cũng rấy hay.

1 Like

Rất cảm ơn mọi người nhiệt tình hỏi thăm giúp đỡ, mình có update thêm thông tin ở post đầu, kính phiền mọi người coi qua nhé, mình xin chân thành cảm ơn.

1 Like

Hmmm… Dùng kỹ thuật lazy loading thôi. Ngoài ra bảo bên làm API tối ưu lại, giảm bớt kích thước ảnh, trên mạng cũng có một vài trang cho cho phép giảm dung lượng ảnh mà không giảm chất lượng, đối với script thì minify lại để giảm bớt dung lượng.

4 Likes

Nếu đoán json của bạn nặng là do phần nội dung, giới thiệu, hay review của từng cuốn sách có nhiều text, nên mới nhiều vậy (chứ hiện mình load 60 ngàn records từ mysql vào json chỉ có 0.5s, bằng PHP).

Nếu mình đoán đúng, thì bạn có thể bỏ những field này ra khỏi phần response, như vậy thì bạn có thể load hết toàn bộ các đầu sách và các thông tin kèm theo nhanh và nhẹ. Khi nào cần chi tiết thì hãy load những info kia

Mình thấy stackoverlow có câu hỏi này khớp với vấn đề của bạn

Với mình có chút chưa rõ, là ở dưới bạn có nói là bạn chỉ có thể làm việc thông qua API có sẵn chứ không đung vào database được (?), nếu thật sự vậy thì chỉ có thể xử lý phần response của API rồi đưa lên front-end thôi, chứ đâu làm được gì khác?

4 Likes

Cho bạn tài liệu tham khảo nè:


2 Likes

Có vài thắc mắc1

  1. Đầu tiên mình làm là khi nhấp vô nhà xuất bản nào đó, nó sẽ load các loại sách đó và tương tự với các level khác. Nhưng khách hàng chả hiểu sao họ không chịu, họ muốn show lên hết mới chịu
    -> show hết 20MB dữ liệu lên màn hình ngay từ đầu chứ không có hide hay collage gì cả? thật không thể tưởng tượng là cần phải scroll bao lâu để hết 20MB đó, vậy thì chịu thôi

  2. Mình nói là mình “đã tối ưu hóa json hết cỡ". Căn bản là mình không có được trực tiếp làm database, chỉ được dùng API của bên nào đó thiết kế trước thôi để hành sự thôi
    2 câu trên khá trỗi nhau, bạn có vai trò gì trong project này? frontend hay backend hay cả 2?
    nếu bạn không làm backend mà chỉ call api do người ta thiết kế và implement sẵn thì việc tối ưu này không phải vấn đề của bạn => done
    nếu bạn là người quyết định luôn backend thì việc kiểm tra và thêm có thể chỉ cần 1 endpoint thôi, tại sao phải là 2 endpoint? và việc có phân trang hay không do bạn quyết định chứ còn ai nữu? (gọi phân trang không hẳn đúng, filter đúng hơn)

  3. Khi user 1 load hết mọi thứ lên client và sử dụng, sau đó có user 2 cũng sử dụng web app và edit data, vậy ông user 1 thì lại đang xem cái cũ?

  4. web app này là dùng nội bộ hay là public bên ngoài? vậy lượng user nó phục vụ khoảng bao nhiêu mỗi ngày? 1k lượt truy cập thì traffic cũng vài chục GB rồi đó

  5. Bạn đang dùng sql hay nosql để lưu trữ cái cây này? dùng cli để query tốn bao nhiêu thời gian? Trông giống nosql. Nếu là nosql thì cái object nhà xuất bản là cực lớn, các thao tác về việc thêm xóa sửu những object cấp nhỏ hơn đều là update, nosql không phải dùng cho case như vậy

Thật ra chẳng có cái công thức chung nào cho những việc như thế này, cái này dựa vào yêu cầu business cụ thể và kinh nghiệm mà thôi. Thiết kế đã sai thì code giỏi cũng bằng thừa

5 Likes

Japanese client detected :wink:


Cảm ơn cậu về câu trả lời của cậu nhé.
Tớ đồng ý với @kisuluoibieng về các point mà cậu ấy đưa ra, cậu nên đọc câu trả lời của cậu ấy và tự trả lời các câu hỏi đó nhé @hoalaxanh123.
Tớ chỉ bổ sung thêm 1 số điều thôi:

  • Tớ nghĩ vấn đề thực sự của cậu là ở việc thuyết phục khách hàng. Vì cậu là chuyên gia kỹ thuật, cậu có trách nhiệm nói cho khách hàng của cậu biết vấn đề sẽ gặp phải nếu như solution “phơi hết ra” được thực thi. Tớ nghĩ nếu cậu có lý do hợp lý (và cậu đã có bằng chứng rồi), cậu có thể thuyết phục khách hàng về quyết định đó.
    Đó là cách giải quyết vấn đề triệt để nhất.
  • Có vẻ như cậu là kỹ sư front-end, và API kia là do bên khác implement. Bottleneck của cậu là lượng response quá lớn từ API.
    Vậy nên, cậu có thể suggest họ điều mà cậu muốn (support pagination trên API - nếu không, cậu không có hi vọng nào đâu), và đồng thời optimize ở bên họ (DB/caching/whatever…) để response trả về trong vài ms. Lúc đó cậu mới nghĩ được tới việc lazyload/in memory cache hay bất cứ solution nào khác (nếu API không support, cậu không có solution nào).
    Đó là cách giải quyết nếu cậu target vấn đề là “response chậm”, và cậu cũng không tốn nhiều effort cho việc đó.

Hope it helps!

Edit: Cache lên in memory DB không chắc đã giải quyết được vấn đề của cậu (cậu load DB lúc nào?), mà còn có thể cho cậu những vấn đề mới (như invalidate cache lúc nào? Làm thế nào để đồng bộ với thay đổi trên DB?). Vậy nên, cậu cân nhắc kỹ nhé!

3 Likes
  1. Lỗi mình ghi không rõ, có hide á bạn, mở các node vô node cha thì show các node con. Trước đây mình làm là khi click vào nút cha (nhà xuất bản), lúc này mới đi call api, lấy dữ liệu loại sách và tương tự các level dưới bạn.
  2. Mình làm ở cả 2, mình dùng flask và call API để lấy data /xóa/sửa/thêm trên app của mình. Như bạn nói đúng là không phải việc của mình nhưng mình rất muốn có 1 giải pháp nào đó tốt nhất cho khách hàng của mình chứ mình không muốn bạn ạ.
  3. Khách hàng chấp nhận như vậy bạn ạ, chấp nhận mất mát hay sai lệch dữ liệu khi có >=2 user cùng làm 1 việc như bạn nói.
  4. App mình dùng nội bộ, thường thì chỉ có 1 người dùng / 1 thời điểm thôi bạn. Nhưng có lẽ mình cũng phải cân nhắc thêm trường hợp bạn đề cập.
  5. Mình có đề cập ở trên, mình lưu vô redux bạn ạ, và đúng như bạn nêu vấn đề, mình sai ngay từ đầu
    thiết kế không linh hoạt và đây là hệ quả của mình đang phải chịu.

Bạn nói cũng đúng, nhưng mình không bỏ ngang được, phạm sai lầm không lẽ không được sửa, phải chứ.

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?