Laravel: Một số cách tăng tốc website Laravel

Mục lục bài viết:

1. Route Caching

Mỗi khi máy chủ của bạn thực hiện một yêu cầu, tất cả các routes được đăng ký. Điều đó tiêu tốn một chút thời gian. Tuy nhiên, bạn có thể chọn cách cache chúng để bỏ qua bước này thay vì thực hiện nó.

Caching route không có gì quá khó. Tất cả những gì bạn phải làm là thực hiện một lệnh sau khi bạn triển khai ứng dụng của mình:

php artisan route:cache

Tuy nhiên, nếu bạn thêm các route mới hoặc chỉnh sửa một cái gì đó,  đừng quên xóa bộ nhớ cache routes và thực hiện lại lệnh này nhé

php artisan route:cache

Lưu ý: nếu trong route của bạn có chứa Closure (callback function) hẳn là bạn nhận ngay lỗi đó, đưa chúng nó vào trong Controller nha.

2. Config Caching

Cũng giống route, config cũng sẽ được nạp mỗi khi có request tới. Hãy cache nó như route

// Chạy lệnh này một lần nữa nếu có thay đổi gì ở các 

file

config nhé php artisan config:cache

3. Tối ưu Composer Autoloader

Thông thường, tệp autoloader được tạo bởi Composer khá nhanh. Tuy nhiên, trong môi trường production, mọi thứ có thể chậm hơn nếu các quy tắc tự động tải PSR-4 và PSR-0 được thiết lập.

Bạn có thể tối ưu hóa quá trình tạo tệp tự động tải bằng cách thêm như sau:

composer dump-autoload -o

4. Không phải: “Đừng sử dụng quá nhiều Blade view”

Hãy nhớ rằng: Laravel biên dịch các Blade view. Biên dịch có nghĩa là vào cuối của quá trình bạn có một tập tin hoàn chỉnh, và tập tin được biên dịch sẽ được sử dụng thay vì sử dụng nhiều tập tin như nhiều người vẫn nghĩ.

Vậy nên việc dùng nhiều Blade không ảnh hưởng đến tốc độ tải trang.

5. Dùng Cache/Session Driver khác

Redis là một trong những công cụ tuyệt vời để cache và session.

6. Update thường xuyên phiên bản Laravel

Phiên bản Laravel mới không chỉ có mỗi tính năng mới, nó giúp cải thiện hiệu suất rất nhiều.

7. Loại bỏ dịch vụ không sử dụng

Hãy dành một chút thời gian kiểm tra tệp config/app.php để xem bạn có thể tìm thấy service provider mà bạn không cần hay không. Hãy thử gỡ bỏ nó và kiểm tra ứng dụng của bạn nếu mọi thứ đều ổn.

8. Sử dụng Eager Loading cho những truy vấn database

Eager Loading là một cách giảm truy vấn db của bạn đấy, nó giải quyết vấn đề N + 1 truy vấn đấy.

$books = App\Book::

all

();

foreach

($books

as

$book) {

echo

$book->

author

->

name

; }

Hãy tưởng tượng rằng bạn có 1000 cuốn sách trong cơ sở dữ liệu của bạn. Bây giờ, mã này sẽ thực thi 1001 truy vấn để lấy tên tác giả cho 1000 cuốn sách.

1 (truy vấn tìm nạp dữ liệu cho 1000 sách) + 1000 (truy vấn tìm nạp dữ liệu tác giả cho mỗi sách) = 1001.

Tuy nhiên, nếu bạn viết mã này như sau

$books = App\Book::

with

(

'author'

)->

get

();

foreach

($books

as

$book) {

echo

$book->

author

->

name

; }

Vấn đề hiệu suất này đã được giải quyết. Bạn sẽ chỉ thực hiện hai truy vấn thay vì 1001! Một cải tiến hiệu suất rất lớn.

9. Cache kết quả DB

Đôi khi, việc lưu vào bộ nhớ cache kết quả truy vấn cụ thể có thể là một ý tưởng tuyệt vời.

Hãy tưởng tượng tình huống này: bạn có 1 widget, đang hiển thị “10 album hàng đầu” trong trang chủ của ứng dụng của bạn. Công việc được thực hiện bởi một truy vấn tìm nạp dữ liệu từ cơ sở dữ liệu (có thể liên quan đến các nghệ sĩ và các bảng khác). Trang chủ của bạn được xem 1000 lần/giờ.

1000 truy vấn mỗi giờ cho widget đó. 24000 truy vấn/ngày cho widget – quả thật là một widget điên rồ phải không nào.

Bây giờ, giả sử Top 10 được cập nhật hàng giờ. Vì vậy, những gì ta cần làm để cache kết quả trong một giờ?

$value = Cache::

remember

(

'top_10_albums'

,

60

,

function

() {

return

Album::

with

(

'artist'

,

'producer'

)->

getTopTen

(); });

Với phương thức remember của Cache bạn sẽ có thể lấy dữ liệu từ cơ sở dữ liệu, lưu nó vào bộ nhớ cache và sử dụng nó trong 60 phút. Sau khoảng thời gian đó, dữ liệu “mới” sẽ được tìm nạp lại từ cơ sở dữ liệu.

=> Từ 24000 đến 24 truy vấn/ngày.

10. Thêm Index trong DB

Hãy nhớ thêm các chỉ mục vào các bảng của bạn khi cần thiết. Nó có vẻ là một mẹo nhỏ, nhưng nó không phải. Tôi thấy rất nhiều ứng dụng không có chỉ mục ở trong bảng.

Schema::

table

(

'my_table_name'

,

function

(Blueprint $table){ $table->

index

(

'field_to_be_indexed'

); });

Bạn không thể tạo chỉ mục ở bất cứ đâu bạn thích. Bạn phải nghiên cứu business, code và query db của mình, hiểu vị trí cần thiết và sau đó thêm các chỉ mục được yêu cầu.

11. Không dùng nhiều Middleware

Dưới những gì đơn giản bạn thấy, Laravel thực hiện rất nhiều cuộc gọi (pre/post) cho mỗi middleware mà bạn đăng ký trong code ứng dụng. Vì vậy, hãy nhớ kiểm tra kỹ và loại bỏ những gì bạn không cần.

Bạn có thể tìm danh sách middleware trong tệp Kernel.php.

12. Sử dụng hàng đợi

PHP là đồng bộ bạn biết rồi đó.

Đôi khi, các ứng dụng Laravel chậm hơn dự kiến ​​bởi vì bạn có thể triển khai không đồng bộ các tác vụ đồng bộ và bạn không làm điều đó.

Ví dụ được sử dụng nhiều nhất là gửi welcome email. Hãy hình dung một luồng:

  1. người dùng điền vào form và submit
  2. ứng dụng của bạn sẽ lưu thông tin vào cơ sở dữ liệu;

  3. ứng dụng gửi một email với một tin nhắn chào mừng và một liên kết xác nhận;
  4. redirect đến trang “Cảm ơn!” nào đó

Vâng, tôi đã thấy rất nhiều lần, nhìn thấy tất cả những thứ này được thực hiện hoàn toàn trong một Controller nào đó và tuần tự như mặt trời mọc và lặn vậy.

Đề xuất của tôi ở đây là tìm hiểu cách sử dụng các sự kiện và hàng đợi. Bạn có thể sử dụng chúng để ủy quyền quy trình gửi email đến một quy trình chuyên dụng khác và cải thiện trải nghiệm người dùng cuối cùng.

13. Sử dụng Pusher để cải thiện tác vụ không đồng bộ

Ở trên đã có nói về hàng đợi, hàng đợi xử lý thứ gì đó ở server và người dùng không hề biết điều đó.

Hãy tưởng tượng rằng bạn đang tạo một quy trình nặng (về tính toán) và bạn muốn hiển thị thanh tiến trình cho người dùng của mình. Bạn có thể dễ dàng sử dụng một công việc không đồng bộ (async job) trên hàng đợi và tích hợp với Pusher để gửi một thông báo đến người dùng ngay cả khi tác vụ chưa hoàn tất.

Trên blog của Chung, nếu ai đó comment vào bài viết hay comment của bạn, bạn sẽ nhận được một thông báo đó.

14. Sử dụng Logs / Debugbars / Telescope để đo lường

Bạn không thể cải thiện được điều gì, nếu bạn không thể đo lường nó.

Khái niệm này phù hợp hoàn hảo trong bối cảnh của các ứng dụng web. Có rất nhiều thứ cần đo để cải thiện thời gian. May mắn thay, cũng có rất nhiều công cụ tuyệt vời để làm điều đó.

  • Slow query logs: trong MySQL, MariaDB và các cơ sở dữ liệu khác, bạn có thể bật nhật ký dành riêng cho các truy vấn chậm để theo dõi những gì mất nhiều thời gian. Bạn có thể sử dụng dữ liệu này để hiểu xem một đoạn mã (hoặc truy vấn) cụ thể có phải được thay đổi hoặc tối ưu hóa hay không;
  • Debugbar:  Laravel Debugbar là một gói tuyệt vời mà bạn có thể sử dụng để thu thập dữ liệu về rất nhiều khía cạnh ứng dụng của bạn. Truy vấn, lượt xem, thời gian, v.v.
  • Laravel Telescope: một công cụ tuyệt vời khác là Laravel Telescope, được định nghĩa là “một trợ lý gỡ rối thanh lịch” cho một ứng dụng Laravel. Hiện đã publish và bạn có thể tích hợp vào ứng dụng của mình rồi nhé.

15. Update phiên bản PHP

Kể từ khi PHP 7 ra đời và được cập nhật liên tục cả về tính năng và hiệu năng. Đó là lí do vì sao Laravel yêu cầu phiên bản PHP cao đến như vậy, Chung đã có nhiều bài viết về PHP 7 như: PHP 7.3 có gì mới?, PHP 7.4: Preload – Tốc độ bàn thờ cho PHP, Category PHP, …

16. Xem xét dùng Lumen cho các Service

Nếu ứng dụng của bạn đang phát triển rất nhiều, hãy bắt đầu xem xét cách chia nhỏ nội dung thành các dịch vụ riêng biệt. Không có một hướng dẫn rõ ràng để làm điều này: các tiêu chí tách hoàn hảo phụ thuộc vào nhiều yếu tố, từ miền của ứng dụng của bạn đến công việc bạn cần làm để phân chia tất cả những thứ cần thiết.

Nếu bạn thích chủ đề này, thì bài viết này sẽ hợp với bạn Large Scale Laravel Application

17. Phân phối nội dung bằng CDN

Tôi khá chắc chắn rằng bạn có rất nhiều tài sản giao diện người dùng, như tệp CSS và tập lệnh JS.

Bạn có thể giảm lượng dữ liệu bạn gửi cho người dùng theo nhiều cách:

  • Nén code
  • Đóng gói nhiều file thành một
  • Bật nén gzip

Tuy nhiên, nếu bạn gặp nhiều lưu lượng truy cập, bạn có thể lưu trữ nội dung của mình vào một dịch vụ CDN chuyên dụng, như:

  • Akamai
  • Max CDN;
  • Cloudflare;
  • Amazon AWS Services (S3 + CloudFront);

18. Sử dụng công cụ đo lường nâng cao

Ở phía trên có nói về các công cụ đo lường, nhưng với các ứng dụng to và quan trọng hơn, thì từng đó là chưa đủ

Bạn nên chọn các công cụ nâng cao hơn như:

  • New Relic;
  • AppOptics;
  • Datadog;
  • Sentry;

Các ứng dụng trong danh sách trên không làm điều tương tự: chúng được tạo ra cho các mục đích khác nhau. Hãy dành một chút thời gian để học cách hiểu họ có thể giúp bạn như thế nào.

19. Mở rộng theo chiều dọc

Bạn đã làm mọi thứ để tối ưu hóa từng bit trong code của bạn, nhưng ứng dụng của bạn đang phát triển. Sớm hay muộn bạn sẽ cần phải mở rộng ứng dụng của bạn theo chiều dọc.

Đơn giản là: nhiều RAM hơn, nhiều space hơn, nhiều băng thông hơn, nhiều CPU hơn.

20. Mở rộng theo chiều ngang

Một cách tiếp cận khác để mở rộng quy mô, khác với quy mô theo chiều dọc truyền thống, vì hai lý do:

  • Thay vì tăng tài nguyên của bạn lên, bạn sẽ cấu hình để xử lý tăng lưu lượng truy cập khác nhau. Mặc dù trong bối cảnh chia tỷ lệ theo chiều dọc, bạn chỉ tăng mức cấu hình máy chủ, mở rộng ứng dụng theo chiều ngang có nghĩa là nó sẽ chạy trên các máy khác nhau, có thể đằng sau bộ cân bằng tải (load balancer) và các dịch vụ khác. Nó có nghĩa là thiết lập và cấu hình nhiều hơn và nó không đơn giản;
  • Không phải tất cả các ứng dụng đều được viết để được thu nhỏ theo chiều ngang chỉ trong vài giờ. Đôi khi bạn sẽ cần phải refactor và cô lập một số code; đôi khi bạn sẽ cần phải chia ứng dụng của mình thành các dịch vụ khác nhau, nhỏ hơn sẽ có quy mô khác nhau;