Sự khác biệt giữa thư viện và khung JavaScript

Bài viết này sẽ hướng dẫn bạn về sự khác biệt giữa khung và thư viện trong bối cảnh môi trường JavaScript phía máy khách, đây là mã chạy trong trình duyệt web của bạn. Tuy nhiên, một số điểm được nêu trong bài viết này cũng áp dụng cho các môi trường khác vì thư viện và khung là một phần của nhiều lĩnh vực kỹ thuật phần mềm, chẳng hạn như phát triển ứng dụng gốc dành cho thiết bị di động.

Nội dung thảo luận trong bài đăng này tập trung vào sự khác biệt về định tính thay vì sự khác biệt về định lượng giữa thư viện và khung. Ví dụ:

  • Số lượng: Các khung thường tuân thủ nguyên tắc đảo ngược quyền kiểm soát.
  • Chất lượng: Kinh nghiệm về khung này có thể hấp dẫn hơn đối với các nhà tuyển dụng trong tương lai khi bạn tìm việc.

Tại sao bạn nên tìm hiểu về thư viện và khung?

Việc sử dụng thư viện và khung JavaScript rất phổ biến trên web. Có vẻ như mọi trang web khác đều sử dụng một số mã của bên thứ ba trong tài nguyên JavaScript của trang web đó. Trọng số trang web ngày càng giảm theo thời gian, điều này ảnh hưởng đến người dùng. JavaScript là một yếu tố đóng góp lớn vào trọng lượng tổng thể của trang. Chính JavaScript này thường bao gồm các thư viện và khung của bên thứ ba.

Bạn không thể nói rằng "Ngừng sử dụng khung JavaScript" vì các khung này mang lại lợi ích lớn cho nhà phát triển. Khung có thể giúp bạn lập trình hiệu quả và cung cấp các tính năng một cách nhanh chóng, cùng nhiều lợi ích khác. Thay vào đó, bạn nên tự tìm hiểu để có thể đưa ra quyết định sáng suốt khi cần.

"Hôm nay tôi có nên sử dụng thư viện hay khung không?" là một câu hỏi không phổ biến mà bạn nên tự hỏi mình. Thư viện và khung là hai khái niệm rất khác nhau. Tuy nhiên, thư viện và khung thường được kết hợp với nhau và bạn càng có nhiều kiến thức về hai thư viện và khung này, bạn càng có nhiều khả năng đưa ra quyết định sáng suốt về việc sử dụng chúng.

Ví dụ về thư viện và khung

Bạn có thể thấy mã của bên thứ ba dưới các tên khác, chẳng hạn như tiện ích, trình bổ trợ, tệp polyfill hoặc gói. Tuy nhiên, tất cả các thành phần này thường thuộc danh mục thư viện hoặc khung. Về cơ bản, có thể tóm tắt sự khác biệt giữa hai loại nội dung này như sau:

Thư viện

Thư viện thường đơn giản hơn khung và cung cấp phạm vi chức năng hẹp. Nếu truyền dữ liệu đầu vào vào một phương thức và nhận dữ liệu đầu ra, thì có thể bạn đã sử dụng một thư viện.

Hãy xem ví dụ sau về thư viện lodash:

import lodash from 'lodash'; // [1]
const result = lodash.capitalize('hello'); // [2]
console.log(result); // Hello

Tương tự như trong nhiều thư viện, bạn nên đọc qua và hiểu rõ chức năng của mã này. Chỉ cần một chút phép thuật là xong:

  1. Câu lệnh import sẽ nhập thư viện lodash vào chương trình JavaScript.
  2. Phương thức capitalize() được gọi.
  3. Một đối số duy nhất sẽ được truyền vào phương thức này.
  4. Giá trị trả về được ghi nhận trong một biến.

Khung

Khung thường lớn hơn thư viện và đóng góp nhiều hơn vào tổng trọng lượng trang. Trên thực tế, một khung có thể chứa cả thư viện.

Ví dụ này cho thấy một khung đơn giản không có thư viện và sử dụng Vue, một khung JavaScript phổ biến:

<!-- index.html -->
<div id="main">
  {{ message }}
</div>

<script type="module">
import Vue from './node_modules/vue/dist/vue.esm.browser.js';

new Vue({
  el: '#main',
  data: {
    message: 'Hello, world'
  }
});
</script>

Nếu so sánh ví dụ về khung này với ví dụ về thư viện trước đó, bạn có thể nhận thấy những điểm khác biệt sau:

  • Mã khung bao gồm nhiều kỹ thuật và tóm tắt các kỹ thuật đó thành API có chủ ý riêng.
  • Nhà phát triển không có toàn quyền kiểm soát cách thức và thời điểm các thao tác xảy ra. Ví dụ: cách thức và thời điểm Vue ghi chuỗi 'Hello, world' vào trang sẽ được loại bỏ khỏi bạn.
  • Việc tạo bản sao của lớp Vue sẽ mang lại một số hiệu ứng phụ, điều này thường xảy ra khi bạn sử dụng khung, trong khi thư viện có thể cung cấp hàm thuần tuý.
  • Khung này quy định một hệ thống mẫu HTML cụ thể thay vì sử dụng hệ thống mẫu của riêng bạn.
  • Nếu đọc thêm tài liệu về khung Vue hoặc hầu hết tài liệu về khung khác, bạn có thể thấy cách các khung quy định các mẫu kiến trúc mà bạn có thể sử dụng. Khung JavaScript sẽ giảm bớt cho bạn một số gánh nặng về nhận thức vì bạn không phải tự tìm ra điều này.

Trường hợp nên sử dụng thư viện thay vì khung

Sau khi đọc nội dung so sánh giữa thư viện và khung, bạn có thể bắt đầu hiểu được thời điểm nên sử dụng thư viện hoặc khung:

  • Khung có thể giúp bạn (nhà phát triển) giảm bớt sự phức tạp. Như đã thảo luận, một khung có thể trừu tượng hoá logic, hành vi và thậm chí là các mẫu kiến trúc. Điều này đặc biệt hữu ích khi bạn bắt đầu một dự án mới. Thư viện có thể giúp giải quyết độ phức tạp, nhưng thường tập trung vào việc sử dụng lại mã.
  • Các tác giả khung muốn bạn làm việc hiệu quả và thường phát triển các công cụ bổ sung, phần mềm gỡ lỗi và hướng dẫn toàn diện cùng với các tài nguyên khác để giúp bạn sử dụng khung một cách hiệu quả. Các tác giả thư viện cũng muốn bạn làm việc hiệu quả, nhưng các công cụ chuyên biệt không phổ biến trong thư viện.
  • Hầu hết các khung đều cung cấp điểm khởi đầu về chức năng, chẳng hạn như khung hoặc mã nguyên mẫu, để giúp bạn xây dựng ứng dụng web một cách nhanh chóng. Thư viện trở thành một phần của cơ sở mã đã được thiết lập.
  • Nhìn chung, các khung sẽ làm tăng độ phức tạp cho cơ sở mã của bạn. Mức độ phức tạp không phải lúc nào cũng rõ ràng ngay từ đầu, nhưng có thể tự bộc lộ theo thời gian.

Xin lưu ý rằng bạn thường không so sánh thư viện với khung vì đó là hai thứ để thực hiện các nhiệm vụ khác nhau. Tuy nhiên, bạn càng có nhiều kiến thức về hai loại hình này thì bạn càng có nhiều thông tin để quyết định loại hình phù hợp nhất với mình. Quyết định sử dụng khung hoặc thư viện cuối cùng phụ thuộc vào yêu cầu của bạn.

Khả năng hoán đổi

Bạn sẽ không thay đổi thư viện hoặc khung nội dung mỗi tuần. Tuy nhiên, bạn nên hiểu rõ những hạn chế của một gói khiến bạn bị ràng buộc trong hệ sinh thái của gói đó. Bạn cũng nên hiểu rằng nhà phát triển quyết định sử dụng gói của bên thứ ba có một phần trách nhiệm tạo ra mối liên kết lỏng lẻo giữa gói và mã nguồn ứng dụng.

Gói liên kết với mã nguồn sẽ khó xoá và hoán đổi cho gói khác hơn. Bạn có thể cần hoán đổi gói khi:

  • Bạn phải cập nhật một gói không còn được duy trì.
  • Bạn phát hiện ra rằng gói này quá lỗi nên không thể xử lý được.
  • Bạn tìm hiểu về một gói mới đáp ứng tốt hơn nhu cầu của mình.
  • Yêu cầu về sản phẩm của bạn thay đổi và gói không còn cần thiết nữa.

Hãy xem xét ví dụ sau:

// header.js file
import color from '@package/set-color';
color('header', 'dark');

// article.js file
import color from '@package/set-color';
color('.article-post', 'dark');

// footer.js file
import color from '@package/set-color';
color('.footer-container', 'dark');

Ví dụ trước sử dụng gói @package/set-color của bên thứ ba trên 3 tệp riêng biệt. Nếu xử lý mã này và cần thay thế gói của bên thứ ba, bạn phải cập nhật mã ở ba vị trí.

Ngoài ra, bạn có thể đơn giản hoá việc bảo trì và tóm tắt việc sử dụng thư viện ở một nơi, như trong ví dụ sau:

// lib/set-color.js file
import color from '@package/set-color';

export default function color(element, theme = 'dark') {
  color(element, theme);
}

// header.js file
import color from './lib/set-color.js';
color('header');

// article.js file
import color from './lib/set-color.js';
color('.article-post');

// footer.js file
import color from './lib/set-color.js';
color('.footer-container');

Trong ví dụ trước, việc sử dụng thư viện trực tiếp bị loại bỏ. Do đó, nếu phải hoán đổi gói bên thứ ba, bạn chỉ cần cập nhật một tệp. Ngoài ra, mã này hiện dễ sử dụng hơn vì tệp set-color.js nội bộ đặt giao diện màu mặc định để sử dụng.

Dễ sử dụng

Một khung có thể có API phức tạp, nhưng khung đó có thể cung cấp các công cụ cho nhà phát triển giúp dễ sử dụng hơn. Mức độ dễ sử dụng dựa trên nhiều yếu tố và có thể mang tính chủ quan cao. Bạn có thể gặp khó khăn khi sử dụng một khung vì:

  • Khung này có một API vốn đã phức tạp.
  • Khung này được ghi chép không đầy đủ và đòi hỏi nhiều thử nghiệm và sai sót để giải quyết vấn đề.
  • Khung này sử dụng các kỹ thuật mà bạn và nhóm của bạn không quen thuộc.

Các khung có thể giảm thiểu những thách thức này thông qua các phương pháp hay nhất phổ biến, chẳng hạn như:

  • Khung này cung cấp các công cụ chẩn đoán và công cụ dành cho nhà phát triển để giúp việc gỡ lỗi trở nên dễ dàng hơn.
  • Khung này có một cộng đồng nhà phát triển năng động, cộng tác trên tài liệu, hướng dẫn, bài viết hướng dẫn và video miễn phí. Sau khi xem nội dung này, bạn có thể sử dụng khung này một cách hiệu quả.
  • Khung này cung cấp một API tuân theo các quy ước lập trình phổ biến. Bạn làm việc hiệu quả với khung này vì đã tìm hiểu các quy ước như vậy trước đây và đã quen hơn với các kiểu lập trình.

Mặc dù các điểm này thường được phân bổ cho khung, nhưng chúng cũng có thể được phân bổ cho thư viện. Ví dụ: thư viện JavaScript D3.js rất mạnh mẽ và có một hệ sinh thái lớn cung cấp các hội thảo, hướng dẫn và tài liệu cùng với các tài nguyên khác, tất cả đều tác động đến khả năng dễ sử dụng của thư viện này.

Ngoài ra, khung thường quy định một cấu trúc cho ứng dụng web của bạn trong khi thư viện thường tương thích với cấu trúc hiện có, bất kể cấu trúc đó là gì.

Hiệu suất

Nhìn chung, khung có thể ảnh hưởng đến hiệu suất nhiều hơn thư viện, mặc dù có một số trường hợp ngoại lệ. Hiệu suất web là một lĩnh vực rộng lớn với nhiều chủ đề, vì vậy, các phần này sẽ đề cập đến hai chủ đề đáng chú ý: loại bỏ phần không dùng đến và cập nhật phần mềm.

Lắc cây

Việc tạo gói chỉ là một khía cạnh của hiệu suất web nhưng mang lại hiệu quả lớn, đặc biệt là đối với các thư viện lớn hơn. Việc sử dụng tính năng loại bỏ mã không cần thiết trong quá trình nhập và xuất giúp cải thiện hiệu suất vì tính năng này tìm và loại bỏ mã không cần thiết cho ứng dụng.

Khi bạn gói mã JavaScript, có một bước hữu ích được gọi là loại bỏ cây (tree shaking). Đây là một hoạt động tối ưu hoá hiệu suất có giá trị mà bạn có thể thực hiện cho mã của mình, mặc dù việc này dễ dàng hơn với thư viện so với khung.

Khi nhập mã của bên thứ ba vào mã nguồn, bạn thường gói mã đó vào một hoặc một vài tệp đầu ra. Ví dụ: các tệp header.js, footer.jssidebar.js đều được kết hợp vào tệp output.js. Đây là tệp đầu ra mà bạn tải trong ứng dụng web.

Để hiểu rõ hơn về việc loại bỏ cây, hãy xem xét các ví dụ về mã sau:

// library.js file
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

// main.js file
import {add} from './library.js';

console.log(add(7, 10));

Để mục đích minh hoạ, mã mẫu library.js được cố ý giữ nhỏ so với những gì bạn có thể tìm thấy trong thực tế, trong đó thư viện có thể dài hàng nghìn dòng.

Quy trình gói đơn giản có thể xuất mã với kết quả sau:

// output.js file
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

console.log(add(7, 10));

Mặc dù không cần hàm subtract() trong ứng dụng này, nhưng hàm này vẫn được đưa vào gói cuối cùng. Mã không cần thiết như thế này làm tăng kích thước tải xuống, thời gian phân tích cú pháp và biên dịch cũng như chi phí thực thi mà người dùng phải trả. Phương pháp loại bỏ mã không dùng đến cơ bản sẽ xoá mã không dùng đến và tạo ra kết quả sau:

// output.js file
function add(a, b) {
  return a + b;
}

console.log(add(7, 10));

Lưu ý rằng mã ngắn hơn và súc tích hơn. Trong ví dụ này, mức cải thiện hiệu suất là không đáng kể, nhưng trong một ứng dụng thực tế có thư viện dài hàng nghìn dòng, hiệu suất có thể cải thiện đáng kể. Điều thú vị là các công cụ gói hiện đại, chẳng hạn như Parcel, Webpack và Rollup, còn đi xa hơn nữa vì chúng kết hợp việc rút gọn và loại bỏ mã không dùng đến để tạo một gói được tối ưu hoá cao. Để minh hoạ hiệu quả của các công cụ gói, chúng tôi đã sử dụng Parcel để tạo một tệp gói bằng các ví dụ về mã trước đó. Gói đã xoá tất cả mã không dùng đến và xuất mô-đun duy nhất này:

console.log(7+10);

Gói đủ thông minh để xoá các câu lệnh nhập, định nghĩa hàm và hành vi trong số các mục khác để tạo mã được tối ưu hoá cao.

Việc tạo gói chỉ là một khía cạnh của hiệu suất web nhưng mang lại hiệu suất lớn, đặc biệt là đối với các thư viện lớn hơn. Việc loại bỏ mã thường đơn giản hơn với thư viện so với khung.

Cập nhật phần mềm

Đối với nhiều thư viện và khung, bản cập nhật phần mềm sẽ bổ sung chức năng, sửa lỗi và cuối cùng là tăng kích thước theo thời gian. Không phải lúc nào bạn cũng cần tải bản cập nhật xuống, nhưng nếu bản cập nhật bao gồm các bản sửa lỗi, tính năng nâng cao mong muốn hoặc bản sửa lỗi bảo mật, thì bạn nên cập nhật. Tuy nhiên, càng gửi nhiều dữ liệu qua mạng thì ứng dụng của bạn càng hoạt động kém hiệu quả và hiệu suất càng ảnh hưởng nhiều đến trải nghiệm người dùng.

Nếu một thư viện tăng kích thước, bạn có thể sử dụng tính năng loại bỏ cây để giảm mức tăng đó. Ngoài ra, bạn có thể sử dụng một thư viện JavaScript nhỏ hơn. Để biết thêm thông tin, hãy xem phần Khả năng hoán đổi.

Nếu một khung tăng kích thước, việc loại bỏ cây không chỉ là một thách thức lớn hơn mà còn khó có thể hoán đổi một khung cho một khung khác. Để biết thêm thông tin, hãy xem phần Khả năng hoán đổi.

Tình trạng việc làm

Có một bí mật hiển thị đó là nhiều công ty có những yêu cầu khó khăn đối với những nhà phát triển biết một khung làm việc cụ thể. Họ có thể bỏ qua kiến thức của bạn về các nguyên tắc cơ bản của web và chỉ tập trung vào kiến thức cụ thể của bạn về một khung JavaScript nhất định! Đúng hay sai, đây là thực tế đối với nhiều công việc.

Kiến thức về một vài thư viện JavaScript sẽ không gây hại cho đơn xin việc của bạn, nhưng chắc chắn một điều rằng công cụ này sẽ giúp bạn trở nên nổi bật. Nếu bạn nắm rõ một số khung JavaScript phổ biến, thì nhiều khả năng nhà tuyển dụng sẽ coi kiến thức này là một lợi thế trong thị trường việc làm hiện tại dành cho nhà phát triển web. Một số tổ chức doanh nghiệp lớn bị mắc kẹt với các khung JavaScript quá cũ và thậm chí có thể tuyệt vọng đối với những ứng cử viên có thể sử dụng các khung này.

Bạn có thể tận dụng bí mật công khai này để mang lại lợi thế cho mình. Tuy nhiên, hãy thận trọng khi tiếp cận thị trường việc làm và cân nhắc những điều sau:

  • Hãy nhớ rằng nếu chỉ sử dụng một khung trong suốt sự nghiệp, bạn có thể bỏ lỡ trải nghiệm học tập với các khung hiện đại hơn.
  • Hãy xem xét một nhà phát triển không hiểu rõ các nguyên tắc cơ bản về phát triển web hoặc phát triển phần mềm, nhưng được thuê làm nhà phát triển khung. Nhà phát triển này không viết mã hiệu quả và bạn có thể thấy khó khăn hoặc choáng ngợp khi làm việc trên một cơ sở mã như vậy. Trong một số trường hợp, tình huống này có thể dẫn đến tình trạng kiệt sức. Ví dụ: bạn có thể phải tái cấu trúc mã hoặc điều chỉnh hiệu suất của mã vì mã đó chạy chậm.
  • Khi tìm hiểu về phát triển web, cách tốt nhất là bắt đầu bằng việc tập trung vào các kiến thức cơ bản về phát triển web, phát triển phần mềm và kỹ thuật phần mềm. Với một nền tảng vững chắc như vậy, bạn có thể sử dụng bất kỳ khung JavaScript nào một cách nhanh chóng và hiệu quả.

Kết luận

Bạn đã làm rất tốt khi tìm hiểu về sự khác biệt giữa các thư viện và khung JavaScript. Bạn sẽ không thường xuyên chọn khung hoặc thư viện trừ phi bạn làm việc trong các dự án lĩnh vực mới hoặc với tư cách là nhà tư vấn. Tuy nhiên, khi những quyết định như vậy xuất hiện, bạn càng có nhiều kiến thức về chủ đề đó thì quyết định của bạn càng sáng suốt hơn.

Như bạn đã tìm hiểu, lựa chọn khung và trong một số trường hợp, lựa chọn thư viện có thể ảnh hưởng đáng kể đến trải nghiệm phát triển và người dùng cuối, chẳng hạn như hiệu suất.