Mục lục
Áp Đặt Giới Hạn Kích Thước Payload Hợp Lý
Giải thích
Hiệu năng backend trong các ứng dụng web phần lớn phụ thuộc vào tốc độ máy chủ xử lý, lưu trữ và truy xuất dữ liệu. Khi các payload dữ liệu lớn được truyền tải, nó gây áp lực nặng nề lên tài nguyên mạng và máy chủ; có thể dẫn đến thời gian phản hồi chậm chạp và hiệu suất ứng dụng kém.Do đó, việc áp đặt các giới hạn kích thước payload hợp lý là rất quan trọng để duy trì hiệu năng tối ưu.
Ví dụ, một ứng dụng web xử lý các tệp hình ảnh lớn có thể triển khai các giới hạn để đảm bảo người dùng không tải lên các hình ảnh vượt quá kích thước nhất định. Điều này không chỉ giúp duy trì chi phí máy chủ và băng thông ở mức quản lý, mà còn đảm bảo ứng dụng hoạt động mượt mà cho tất cả người dùng.
Ví dụ
Việc áp đặt giới hạn kích thước payload cũng thường được thực hiện ở nhiều tầng, nhưng tốt nhất là nên được cấu hình ở cả proxy (Nginx) và ứng dụng backend (Django)
Cấu Hình Nginx:
# Giới hạn kích thước body request
client_max_body_size 10M; # Giới hạn 10MB
client_body_buffer_size 128k;
Cấu Hình Django:
# settings.py
# Giới hạn kích thước payload upload
DATA_UPLOAD_MAX_MEMORY_SIZE = 5 * 1024 * 1024 # 5MB cho dữ liệu JSON
FILE_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 # 10MB cho file upload
# views.py
from django.core.exceptions import SuspiciousOperation
def handle_upload(request):
try:
# Kiểm tra kích thước file
if request.FILES['file'].size > 10 * 1024 * 1024:
raise SuspiciousOperation("File quá lớn")
# Xử lý upload
except SuspiciousOperation as e:
return HttpResponseBadRequest(str(e))
Kích Hoạt Nén Cho Các Phản Hồi
Giải thích
Việc tối ưu hóa hiệu năng backend của các ứng dụng web thường đòi hỏi phải kích hoạt nén cho các phản hồi. Các phương pháp nén như Gzip hoặc Brotli giúp giảm kích thước dữ liệu được truyền giữa máy chủ và máy khách. Điều này dẫn đến việc truyền dữ liệu nhanh hơn, giảm thiểu thời gian tải trang web và cải thiện trải nghiệm người dùng.
Chẳng hạn, nếu một trang web có kích thước 100 KB, việc áp dụng nén có thể giảm xuống còn 30 KB. Điều này có nghĩa là ít dữ liệu hơn để tải xuống, do đó thời gian tải nhanh hơn. Do đó, việc kích hoạt nén cho các phản hồi là rất quan trọng để làm cho các ứng dụng web hiệu quả và đáp ứng hơn.
Ví dụ
Cấu Hình Nginx:
Việc nén Gzip thường được cấu hình ở tầng proxy (như Nginx) thay vì trực tiếp trong backend service như Django. Nguyên nhân là Nginx được tối ưu để xử lý nén và giải nén nhanh chóng, đồng thời cuũng giảm thiểu overhead cho ứng dụng Django
server {
# Kích hoạt Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
# Các loại MIME được phép nén
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml;
# Mức độ nén (1-9)
gzip_comp_level 6;
# Kích thước tối thiểu để nén
gzip_min_length 1100;
}
Cấu Hình Django:
Trong trường hợp bạn muốn config từ phía service như Django
# settings.py
MIDDLEWARE = [
'django.middleware.gzip.GZipMiddleware',
# Các middleware khác
]
# Hoặc trong view cụ thể
from django.views.decorators.gzip import gzip_page
@gzip_page
def large_data_view(request):
# View trả về dữ liệu lớn
Phân Trang Hiệu Quả cho Các Tập Dữ Liệu Lớn
Giải thích
Xử lý các tập dữ liệu lớn một cách hiệu quả là chìa khóa để cải thiện hiệu năng backend trong các ứng dụng web. Khi một truy vấn cơ sở dữ liệu trả về quá nhiều dữ liệu, nó có thể dẫn đến thời gian tải chậm và trải nghiệm người dùng kém. Việc triển khai phân trang hiệu quả sẽ giảm đáng kể lượng dữ liệu được xử lý cùng một lúc, từ đó giảm tải cho máy chủ và thời gian độ trễ.
Ví dụ, thay vì tải hàng nghìn, thậm chí hàng triệu bản ghi trong một lần, phân trang cho phép tải chỉ một số lượng bản ghi cụ thể trên mỗi trang, tăng tốc độ và hiệu quả. Nó giúp đảm bảo việc truy xuất dữ liệu diễn ra thuận lợi, thời gian phản hồi máy chủ ấn tượng và cuối cùng là hiệu suất tổng thể tốt hơn.
Ví dụ
# views.py
from django.core.paginator import Paginator
def list_products(request):
product_list = Product.objects.all()
paginator = Paginator(product_list, 20) # 20 sản phẩm mỗi trang
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'products.html', {'page_obj': page_obj})
# Template
{% for product in page_obj %}
{{ product }}
{% endfor %}
{{ page_obj.has_previous }}
{{ page_obj.has_next }}
Giảm Thiểu Xử Lý Không Cần Thiết hoặc Các Phép Tính Tốn Kém trên Máy Chủ
Giải thích
Hiệu năng backend hiệu quả trong các ứng dụng web thường được xác định bằng cách giảm thiểu các xử lý không cần thiết hoặc các phép tính tốn kém trên máy chủ. Khi một ứng dụng không có các xử lý dư thừa hoặc các phép tính phức tạp, nó sẽ tiêu tốn ít năng lượng hơn, thực thi các tác vụ nhanh chóng và giảm thiểu khả năng ngừng hoạt động. Điều này đáng kể cải thiện thời gian phản hồi của ứng dụng đối với các yêu cầu của người dùng.
Ví dụ, thay vì tính toán cùng một dữ liệu nhiều lần cho các người dùng khác nhau, ứng dụng có thể tính toán một lần, lưu trữ kết quả, và sau đó cung cấp kết quả đã lưu trữ này khi người dùng yêu cầu. Điều này về cơ bản sẽ giảm thiểu các quy trình không cần thiết, từ đó nâng cao hiệu năng backend của ứng dụng web.
Ví dụ
Sử dụng cache
# Sử dụng cache
from django.core.cache import cache
def get_expensive_computation(param):
# Kiểm tra cache trước
cache_key = f'computation_{param}'
result = cache.get(cache_key)
if result is None:
# Tính toán nếu chưa có trong cache
result = expensive_calculation(param)
# Lưu vào cache trong 1 giờ
cache.set(cache_key, result, 3600)
return result
# Sử dụng select_related() và prefetch_related()
def optimized_query(request):
# Giảm số lượng query database
products = Product.objects.select_related('category').prefetch_related('tags').all()
Tối Ưu Truy Vấn Cơ Sở Dữ Liệu
# Sử dụng only() và defer()
def efficient_query(request):
# Chỉ lấy các trường cần thiết
users = User.objects.only('username', 'email')
# Bỏ qua các trường tốn kém
products = Product.objects.defer('description', 'long_text_field')