Đã bao giờ các bạn lướt web, dành thời gian cho một trang web load với một tốc độ rùa bò chưa? Mình đoán ắt hẳn là không và sẽ không bao giờ rồi. Theo một nghiên cứu của Google, 53% người dùng sẽ rời khỏi trang web nếu mất hơn 3 giây để tải. Điều đó cho thấy tốc độ tải trang ảnh hưởng rất lớn đến sự sống còn của một trang web. Sau đây sẽ là một số típ để tăng tốc trang web lên tốc độ bàn thờ
Menu
Tối ưu truy vấn database.
Khi thực hiện tối ưu hiệu năng, điều đầu tiên mình nghĩ tới đó là tối ưu truy vấn. Tại sao ư? Vì đối với các trang web chạy thật, lượng dữ liệu trong database là rất lớn có thể từ vài trăm MB lên đến hàng GB. Có nghĩa là câu truy vấn phải thực hiện trên một bảng có hàng trăm nghìn bản ghi. Có mấy phương án sau, mình hay sử dụng khi tối ưu truy vấn.
Database index (indexing).
Index là gì? Index là một dạng cấu trúc dữ liệu, trong đó chứa giá trị của một trường nhất định trong một bảng dữ liệu, đồng thời trỏ đến row dữ liệu tương ứng. Và ích lợi của index mang lại như nào?
SELECT * FROM users where name = ‘Lempi Veum’;
Ví dụ với việc thực hiện truy vấn trên bảng users có 56.000 bản ghi khi không có và có index trên trường name. Chi phí của việc truy vấn khi có index nhỏ hơn rất nhiều so với khi không có index. Do đó, khi thực hiện tối ưu hiệu năng (tốt nhất khi tạo database) nên đánh thực hiện đánh index trên các trường, ưu tiên theo nguyên tắc:
- Ưu tiên khóa chính (Trong Laravel khóa chính đã được đánh index khi sử dụng $table->increments())
- Khóa ngoài trên các bảng
- Trường xuất hiện trong câu điều kiện where (Như trên ví dụ phía trên)
Query cache.
The query cache stores the text of a SELECT
statement together with the corresponding result that was sent to the client. If an identical statement is received later, the server retrieves the results from the query cache rather than parsing and executing the statement again. The query cache is shared among sessions, so a result set generated by one client can be sent in response to the same query issued by another client.
Đây là định nghĩa về query cache trên trang chủ của MySql. Lợi ích của query cache khi các user cùng truy cập vào một page nào đó, kết quả của việc thực hiện truy vấn đã được lưu lại trong cache. Khi có các user khác truy cập vào page đó sẽ sử dụng các kết quả query từ cache nên tốc độ load trang sẽ nhanh hơn rất nhiều. Để sử dụng query cache, có thể tham khảo tại đây. Tuy nhiên, ở phiên bản MySql 5.7.20 thì query cache không được dùng nữa, và sẽ bị loại bỏ ở bản MySql 8.0.
Hoặc nếu sử dụng framework như Laravel chẳng hạn. Các framework này thường hỗ trợ sẵn các phương thức để có thể lưu cache query.
$posts = Cache::remember('index.posts', 30, function() { return Post::with('comments', 'tags', 'author', 'seo')->whereHidden(0)->get(); });
Thay đổi logic xử lý vấn đề.
Trong một số trường hợp mà ngay cả khi đã tối ưu truy vấn rồi, nhưng tốc độ vẫn chậm. Khi đó người nông dân phải làm sao. Khi đó, bạn nên suy nghĩ đến một hướng xử lý khác cho vấn đề hiện tại.
Ví dụ nhé, nếu như bạn phải thực hiện chức năng thống kê nào đó. Việc đó chắc chắn sẽ phải xử lý trên một lượng dữ liệu rất lớn được tích lũy qua nhiều ngày, nhiều tháng, thậm chí nhiều năm. Việc thống kê trong thời gian thực (real-time) nhiều lúc là không cần thiết. Người dùng sẽ không cần biết là trong 30s trước có bao nhiêu ông đã xem một cái gì đó trên trang web của mình đâu. Lúc đó, bạn nên thay đổi logic xử lý thống kê. Thực hiện thống kê hàng ngày thông qua cronjob hoặc tác vụ nào đó rồi lưu lại kết quả. Khi đó, việc xử lý mất nhiều thời gian đã chạy ngầm. Và người dùng sẽ được sử dụng kết quả của việc thống kê và cảm thấy rất nhanh.
Nói tóm lại, cái gì chạy lâu đến cực lâu mà không yêu cầu phải real time, mình nên nhét nó vào chỗ nào đó kín kín để chạy (underground)
Tận dụng ưu điểm của framework.
Các trang web hiện nay đều được xây dựng dựa trên các framework (Laravel, WordPress, CakePhp, …). Framework đương nhiên đã được xây dựng một các rất tối ưu. Vì vậy, chúng ta có thể tận dụng các ưu thế mà framework cung cấp sẵn. Ví dụ sau đây là các tips có thể áp dụng dành cho Laravel:
Config cache.
Sử dụng các lệnh cài đặt config cache sẵn có của Laravel như:
php artisan config:cache
php artisan route:cache
php artisan view:cache
Sử dụng lazy loading và eager loading.
Laravel cung cấp một ORM tuyệt vời để xử lý cơ sở dữ liệu. Được biết đến như Eloquent
, nó tạo ra các abstracts model từ các bảng trong cơ sở dữ liệu. Khi Eloquent sử dụng eager loading, nó sẽ truy xuất tất cả các object model được liên kết để response với truy vấn ban đầu. Điều này được thêm vào response của ứng dụng:
Lazy loading query sẽ như sau:
$books = App\Book::all(); foreach ($books as $book) { echo $book->author->name; }
Tương ứng, eager loading query sẽ như sau:
$books = App\Book::with('author')->get(); foreach ($books as $book) { echo $book->author->name; }
Lựa chọn Cache và Session Driver hợp lý.
Để điều chỉnh hiệu năng tối ưu của Laravel, cách tốt nhất là lưu trữ cache và session trong RAM. Ngoài ra có thể sử dụng các phương pháp lưu trữ cache khác để tăng tốc độ truy xuất cache và session như Redis hoặc Memcached.
Asset bundling.
Laravel cung cấp Laravel Mix để complie nhiều file css/js thành một file css/js duy nhất. Điều này giúp giảm thời gian khi load các file css/js.
Vài cái khác.
Tất nhiên là còn rất nhiều phương pháp và cách tối ưu hiệu năng khác. Các bạn có thể dễ dàng tìm kiếm và sử dụng tùy vào từng tình huống cụ thể. Từ khóa nên tìm kiếm đó là “optimize”. Mình đã sử dụng từ khóa này để trong quá trình tối ưu hiệu năng của một trang web sử dụng Laravel. Và kết quả rất tuyệt vời.
Kết lại, tối ưu hiệu năng rất quan trọng và đó là một quá trình dài xuyên suốt quá trình phát triền của một ứng dụng. Mình mong các bạn có thể sử dụng một vài phương án để tạo ra một kiệt tác load nhanh như những con thiên nga của Tchaikovsky.