Bất kể ý tưởng phát triển ứng dụng của bạn có xuất sắc đến đâu, Performance - hiệu suất là một trong những khía cạnh quan trọng nhất khi xây dựng ứng dụng web. Performance là yếu tố duy nhất quyết định thời gian user- người dùng sẽ tương tác với ứng dụng của bạn hay là rời khỏi ứng dụng. Người ta nhận thấy rằng user chỉ cần 10 giây đầu tiên để quyết định xem nên lướt xuống xem tiếp trang web hay "out" ngay và luôn!

Vì vậy, để giữ chân user ở lại website, điều quan trọng là phải tăng tốc độ trang và mang lại giá trị cho user, thu hút sự chú ý, để họ thích thú tìm hiểu website lâu hơn. Đến lúc cần để tâm tới Optimization - Tối ưu hóa rồi đó !

Node.js thực sự là "nhà sản xuất" nên các ứng dụng có hiệu suất siêu nhanh và có khả năng mở rộng vì nó sử dụng kiến ​​trúc hướng sự kiện và các tác vụ không đồng bộ chạy trên một luồng duy nhất (single thread)

Nhưng cho dù bạn là một nhà phát triển hay một doanh nhân, điều đầu tiên mà cả hai đều muốn là ứng dụng của bạn phải được tối ưu hóa hoàn toàn và hoạt động nhanh chóng.
Các chuyên gia cho rằng, nếu Node.js là ngọn lửa, thì việc tối ưu hóa hiệu suất chính là dầu/xăng. Vì vậy hãy " đổ thêm dầu vào lửa đi" ! Tưởng tượng ứng dụng của bạn sẽ nhanh như thế nào bằng cách sử dụng một số mẹo, công cụ và kỹ thuật tối ưu hóa ứng dụng đã được chứng minh mà tui sẽ trình bày dưới đây.

Chiến lược # 1 - Sử dụng hạn chế các chức năng đồng bộ

Vì Node.js được thiết kế với kiến ​​trúc luồng đơn và mã không đồng bộ cũng được sử dụng nhiều trong Node.js để đảm bảo luồng hoạt động không bị tắc nghẽn. Nhưng trong ứng dụng lại luôn tồn tại rất nhiều thành phần đồng bộ, chính điều này sẽ làm chậm ứng dụng, giảm performance.

Mã không đồng bộ sẽ cho phép bạn sử dụng hàng đợi - queue để theo dõi quy trình làm việc của mình, cho phép bạn thêm các tác vụ bổ sung và thêm các lệnh gọi lại bổ sung mà không chặn luồng chính của bạn. Trong khi bạn đang sử dụng các phương pháp Không đồng bộ, trong một số trường hợp, có thể thấy website của bạn đang thực hiện một số lệnh chặn - blocking calls. Đừng hoảng sợ! Một giải pháp đơn giản là thuê các DEV có kiến ​​thức để đối phó với tình huống này. Mặt khác, bạn có thể cần phải chấp nhận thực tế rằng điều này là phổ biến khi bạn sử dụng các mô-đun của bên thứ ba. Vì vậy, tất cả những gì bạn cần là theo dõi các thư viện và thực hiện tất cả các biện pháp phòng ngừa để tránh chúng chi phối các cuộc gọi đồng bộ.

Demo # 1: Đoạn mã để đồng bộ hóa và không đồng bộ hóa tệp: 

 

Chiến lược # 2 - Bộ nhớ cache để duy trì Load balance - cân bằng tải của ứng dụng với Redis

Cache -  bộ nhớ đệm là một kỹ thuật đơn giản và phổ biến nhất cho phép bạn tạm thời lưu trữ dữ liệu ở nơi nó được lấy ra mà không cần phải truy cập nguồn dữ liệu gốc. Cache sẽ cải thiện thời gian phản hồi của website và thậm chí giảm một số chi phí như băng thông và khối lượng dữ liệu.
Trong trường hợp, lượng user truy cập thấp, thì performance có thể không bị ảnh hưởng nhiều. Các vấn đề về performance thường phát sinh khi lưu lượng truy cập tăng lên và bạn cần duy trì cân bằng tải. Lưu trữ bộ nhớ đệm thường xuyên là một giải pháp tuyệt vời để đạt được hiệu suất cao hơn.
Có thể hơi khó một chút, bạn cần các công cụ để lưu ứng dụng của mình vào bộ nhớ cache một cách hiệu quả. Trước khi bạn tiếp tục truy cập vào bất kỳ công cụ nào dành cho Cache, hãy nhớ rằng nó có là một quy trình làm việc phức tạp nhưng đó là chiến lược có hiệu quả cao đấy. Vì vậy, rất đáng để thuê một công ty phát triển Node.js có thể xử lý công việc chuyên nghiệp và đảm bảo hiệu suất liền mạch.

Dưới đây là một số công cụ phổ biến và đáng tin cậy nhất được sử dụng để lưu vào cache các ứng dụng web.

  1. Memcached: Với sự trợ giúp của các cửa hàng Memcached, dữ liệu có thể được lưu trữ trên các nodes khác nhau vì nó sử dụng hashing schema cung cấp chức năng hash table. Những điều này đảm bảo rằng việc thêm hay xóa một serve node không làm thay đổi đáng kể giá trị các key tới serve node.
  2. Node-Cache: Công cụ Cache này hoạt động gần giống như Memcached với các phương thức set, get và delete. Nó có chức năng xóa dữ liệu khỏi bộ nhớ cache khi hết thời gian chờ.
  3. Nginx: Nó cũng sẽ giúp duy trì cân bằng tải. Nginx sẽ giúp lưu trữ các tệp tĩnh sẽ giảm tải đáng kể công việc của máy chủ ứng dụng. Nó cung cấp mức sử dụng bộ nhớ thấp và khả năng xử lý đồng thời cao.
  4. Redis Cache: Redis là phiên bản phức tạp nhất của Memcached. Nó cung cấp và chỉnh sửa dữ liệu trong bộ nhớ chính của máy chủ để hệ thống nhanh chóng truy xuất dữ liệu cần thiết. Với sự trợ giúp của công cụ Cache này, bạn cũng có thể giảm thời gian tải trang và làm cho ứng dụng của bạn hoạt động nhanh hơn.

Redis hoạt động để trợ giúp và cải thiện hiệu suất tải từ cơ sở dữ liệu quan hệ hoặc NoSQL bằng cách tạo 1 phần bộ nhớ phụ trội cho in-Memory Cache để giảm độ trễ truy cập. Sử dụng Redis, bạn có thể lưu trữ bộ nhớ cache bằng lệnh Set and Get. Ngoài ra, Redis cũng có thể làm việc với dữ liệu kiểu phức tạp như Lists, Sets, Cấu trúc dữ liệu sắp xếp, v.v

Tham khảo khoá Lộ trình Node.js 4.5 tháng của Techmaster 

Demo # 2: Ở đây, chúng tôi so sánh hai đoạn mã từ Node.js trong khi cố gắng truy xuất dữ liệu từ API Sách của Google, có và không có Redis

  • Node.js không có Redis

  • Node.js có Redis

Với những mã này, bạn có thể nhận thấy cách Redis sẽ lưu trữ dữ liệu bộ nhớ cache của giá trị Key duy nhất mà chúng tôi đã chỉ định, bằng cách sử dụng chức năng này:

Và, sử dụng chức năng dưới đây để lấy dữ liệu bộ nhớ cache:

Kết quả cuối cùng: Mất ít nhất 908,545 mili giây, đây là kết quả khi bạn không sử dụng bộ nhớ cache. Nhưng khi bạn sử dụng, chỉ mất 0,621 mili giây để truy xuất dữ liệu.

Chiến lược số 3 - Tối ưu hóa các truy vấn của bạn

Giả sử bạn có một ứng dụng viết blog hiển thị các bài đăng mới nhất trên trang chủ. Trong trường hợp đó, bạn có thể sử dụng lệnh dưới đây trong khi tìm nạp dữ liệu bằng Mongoose

Tuy nhiên, thách thức lớn nhất khi sử dụng hàm find () trong Mongoose là tìm nạp tất cả các trường của một đối tượng và có thể có một số trường trong đối tượng Post không bắt buộc trên trang chủ.

Demo #3

Ví dụ: Comment là một trong những trường phổ biến chứa một loạt các nhận xét cho một bài đăng cụ thể. Tuy nhiên không nhất thiết phải hiển thị tất cả các comments trong khi tìm nạp. Điều này chắc chắn sẽ cải thiện tốc độ. Vì vậy, để tối ưu hóa truy vấn trên, bạn có thể dùng cách sau: 

 

Chiến lược # 4 - Theo dõi hoạt động của bạn bằng Logging

Tại sao Logging lại quan trọng? Trước tiên, hãy đảm bảo rằng ứng dụng của bạn đang chạy mượt mà, không có bất kỳ lỗi nghiêm trọng nào. Nếu một ngày, bạn thấy có điều gì "sai sai" trong ứng dụng của mình, thì đã đến lúc xác định mã nào gây ra lỗi. Và với tính năng Logging, bạn có thể dễ dàng theo dõi hoạt động và lưu lượng truy cập API.

Thông thường, mọi người sử dụng console.log (LogOutput) như một quá trình ghi nhật ký vì theo mặc định, nó sẽ chèn một số log vào chuẩn đầu ra (stdout) và console.error (log error) cũng sẽ đi vào chuẩn lỗi (stderr).
Tuy nhiên, nếu bạn hỏi một công ty phát triển ứng dụng web chuyên nghiệp, họ sẽ khuyên bạn sử dụng mô-đun ghi nhật ký phổ biến và hiệu quả hơn, chẳng hạn như Winston, Morgan và Buyan.

Dưới đây là một vài tính năng của Winston:

  • Tạo hồ sơ đơn giản và dễ dàng
  • Hỗ trợ truy vấn, Logging
  • Có thể catch and log uncaughtException
  • Định mức cho logging message

Nhưng để truy cập nó, trước hết bạn cần cài đặt Winston và làm thế nào để đưa Winston vào dự án mới? Bạn có thể chạy lệnh dưới đây:

Demo #4

 Và để cấu hình Winston, bạn có thể sử dụng lệnh này

 

Chiến lược #5 - Chạy song song để tăng tốc quá trình phát triển ứng dụng

Để hiển thị HTML cho bất kỳ trang dashboard nào, ứng dụng node.js cần truy xuất nhiều dữ liệu cho dashboard. Và để tìm nạp nhiều dữ liệu khác nhau, bạn cần thực hiện nhiều lệnh gọi API nội bộ. Có nhiều chức năng cần thực hiện và quá trình này tiêu tốn rất nhiều thời gian, ảnh hưởng đến performance. Đây là lý do tại sao các tổ chức thường thích thuê các nhà phát triển ứng dụng web giúp bạn tìm nạp dữ liệu một cách chuyên nghiệp.

Trên thực tế, trong khi hiển thị trang dashboard, bạn có thể thực hiện các lệnh gọi giả định sau, để hiển thị HTML cho bất kỳ trang tổng quan nào, ứng dụng Node.js cần truy xuất nhiều dữ liệu từ trang dashboard.

Để truy xuất các chi tiết này, hầu hết các DEV đều tạo một middleware riêng cho từng chức năng. Sau khi hoàn thành, họ sẽ gắn nó vào dashboard route. Nhưng cũng có thể gặp nhiều khó khăn vì từng hành động phải diễn ra lần lượt, nối tiếp nhau. Như vậy tiến trình lại bị chậm đi một chút.

Vì vậy, cách đơn giản để tăng tốc quá trình phát triển ứng dụng Node.js là chạy mọi thứ song song. Vì Node.js hoàn toàn phù hợp để chạy song song nhiều hàm không đồng bộ và rất nhiều yêu cầu API nội bộ này không phụ thuộc vào nhau, do đó, việc song song hóa chúng là rất hợp lý.

Demo #5

Chúc các bạn ứng dụng thành công ! 

Lược dịch từ plainenglish.io