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

Bài viết này hướng dẫn bạn về sự khác biệt giữa khung và thư viện trong ngữ cảnh môi trường JavaScript phía máy khách, 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 có thể á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 những điểm khác biệt về định tính thay vì những khác biệt về định lượng giữa các thư viện và khung. Ví dụ:

  • Định lượng: Khung thường tuân thủ nguyên tắc đảo ngược quyền kiểm soát.
  • Định tính: Trải nghiệm khung ứng dụng có thể thu hút nhiều nhà tuyển dụng trong tương lai hơn 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 khung và thư viện JavaScript rất đa dạng trên web. Mọi trang web khác dường như đang 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 lượng 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ố góp phần lớn tạo nên trọng lượng tổng thể của trang và chính JavaScript này cũng thường bao gồm các thư viện và khung của bên thứ ba.

Nói "Hãy ngừng sử dụng khung JavaScript" thì vẫn chưa đủ, vì khung 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 với 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 đến thời điểm.

"Hôm nay tôi có nên sử dụng thư viện hay khung nội dung không?" là một câu hỏi không phổ biến mà bạn tự hỏi mình. Thư viện và khung là hai thứ rất khác nhau. Tuy nhiên, các thư viện và khung thường không kết hợp với nhau. Do đó, bạn càng có nhiều kiến thức về hai thư viện và khung này, thì 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 bằng các tên khác, chẳng hạn như các tiện ích, trình bổ trợ, polyfills hoặc gói. Tuy nhiên, tất cả các mô-đun này thường thuộc danh mục của một thư viện hoặc một khung. Về cơ bản, sự khác biệt giữa hai loại có thể được tóm tắt như sau:

Thư viện

Thư viện thường đơn giản hơn khung và có phạm vi chức năng hẹp. Nếu truyền giá trị đầu vào vào một phương thức và nhận được kết quả, thì có thể bạn đã sử dụng 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ư nhiều thư viện, bạn nên đọc mã này để hiểu chức năng của mã. Rất ít điều kỳ diệu xảy ra:

  1. Câu lệnh import nhập thư viện lodash vào chương trình JavaScript.
  2. Phương thức capitalize() sẽ được gọi.
  3. Chỉ có một đối số được truyền đến phương thức này.
  4. Giá trị trả về được ghi lại 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ể bao gồm một thư viện.

Ví dụ này cho thấy một khung thuần tuý mà 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 chúng thành API định sẵn của riêng nó.
  • 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 hoạt động diễn ra. Ví dụ: cách thức và thời điểm Vue ghi chuỗi 'Hello, world' vào trang sẽ bị tách khỏi bạn.
  • Việc tạo thực thể của lớp Vue có một số hiệu ứng phụ, thường xảy ra khi bạn sử dụng khung, trong khi thư viện có thể cung cấp các 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 các tài liệu khác về khung, bạn có thể xem cách khung quy định các mẫu kiến trúc mà bạn có thể sử dụng. Khung JavaScript giúp bạn giảm bớt gánh nặng nhận thức vì bạn không phải tự mình tìm hiểu điều này.

Thời điểm sử dụng thư viện so với khung

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

  • Khung có thể làm giảm sự phức tạp cho bạn, với vai trò là nhà phát triển. Như đã thảo luận, một khung có thể trừu tượng hoá logic, hành vi và thậm chí cả các mô hình kiến trúc. Việc 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 xử lý độ phức tạp, nhưng thường tập trung vào việc sử dụng lại mã.
  • 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 dụng không phổ biến trong thư viện.
  • Hầu hết các khung đều cung cấp một điểm xuất phát chức năng, chẳng hạn như khung xương 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ã mà bạn đã thiết lập.
  • Nhìn chung, khung ứng dụng sẽ khiến cơ sở mã của bạn khá phức tạp. Không phải lúc nào bạn cũng thấy rõ sự phức tạp khi bắ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ì hai thư viện khác nhau và giúp đạt được các nhiệm vụ khác nhau. Tuy nhiên, bạn càng có nhiều kiến thức về hai phương pháp này thì bạn càng có nhiều quyền hơn để đưa ra quyết định phù hợp nhất với mình. Quyết định sử dụng khung hay thư viện sẽ 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 tiêu chí hằng tuần. Tuy nhiên, bạn nên hiểu rõ nhược điểm của một gói khiến bạn không thể rời khỏi 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ũng phần nào chịu trách nhiệm về việc tạo mối liên kết rời giữa gói đó và mã nguồn của ứng dụng.

Một gói được liên kết với mã nguồn sẽ khó xoá và hoán đổi cho một gói khác. Bạn có thể cần phải hoán đổi một 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 gói quá lỗi nên không 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.
  • Các yêu cầu về sản phẩm của bạn thay đổi nên bạn không cần dùng gói sản phẩm 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ý trên 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 về 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 được loại bỏ. Do đó, nếu phải hoán đổi gói của bên thứ ba, bạn chỉ cập nhật một tệp. Ngoài ra, giờ đây bạn có thể làm việc với mã này dễ 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ó một API phức tạp nhưng khung này có thể cung cấp các công cụ cho nhà phát triển giúp bạn dễ sử dụng hơn. Mức độ dễ sử dụng dựa trên nhiều yếu tố và có thể còn 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 vốn có một API phức tạp.
  • Khung này được ghi lại kém chất lượng, đồng thời cần nhiều lần thử và lỗi để giải quyết vấn đề.
  • Khung này sử dụng các kỹ thuật chưa quen thuộc với bạn và đội ngũ của bạn.

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

  • Khung này cung cấp cho nhà phát triển và các công cụ chẩn đoán để giúp gỡ lỗi dễ dàng hơn.
  • Khung này có một cộng đồng nhà phát triển tích cực cộng tác về các tài liệu, hướng dẫn, hướng dẫn và video miễn phí. Sau khi sử dụng nội dung này, bạn sẽ làm việc hiệu quả với khung làm việc.
  • 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 sẽ làm việc hiệu quả với khung này vì trước đây bạn đã tìm hiểu các quy ước đó và cũng tăng mức độ quen thuộc với các kiểu lập trình.

Mặc dù những điểm này thường được quy cho khung, nhưng chúng cũng có thể được quy 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 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 ảnh hưởng đến tính dễ sử dụng.

Ngoài ra, khung thường quy định một cấu trúc cho ứng dụng web, còn thư viện thường tương thích với cấu trúc hiện tại (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ó những ngoại lệ cho trường hợp này. Hiệu suất web là một lĩnh vực rất lớn với nhiều chủ đề, vì vậy những phần này đề cập đến hai chủ đề cần lưu ý: rung cây và cập nhật phần mềm.

Cây rung chuyển

Việc đóng gói chỉ là một khía cạnh của hiệu suất web, nhưng có tác động lớn về hiệu suất, đặc biệt là với các thư viện lớn hơn. Việc sử dụng kỹ thuật rung cây trong quá trình nhập và xuất sẽ giúp cải thiện hiệu suất vì tính năng này tìm và cắt giảm 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à rung cây, là cách 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 sử dụng thư viện sẽ dễ dàng hơ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ã này vào một hoặc một vài tệp đầu ra. Ví dụ: tất cả các tệp header.js, footer.jssidebar.js được kết hợp thành 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 rung chuyển cây, hãy xem xét các mã ví dụ 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));

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

Một 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ó trong gói hoàn thiện. 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 của bạn phải trả. Phương pháp lắc cây cơ bản sẽ loại bỏ mã không hoạt động và tạo ra kết quả này:

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

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

Lưu ý rằng mã sẽ ngắn hơn và súc tích hơn. Trong ví dụ này, mức độ cải thiện về hiệu suất là không đáng kể, nhưng trong một ứng dụng thực tế có thư viện có hàng nghìn dòng, hiệu suất có thể quan trọng hơn nhiều. Điều thú vị là các công cụ gói hiện đại, chẳng hạn như Bưu kiện, Gói web và Dữ liệu tổng hợp, là một công cụ tiến hơn một bước vì chúng kết hợp việc giảm thiểu và rung cây để tạo ra một gói được tối ưu hoá cao. Để chứng minh hiệu quả của các công cụ gói, chúng ta đã sử dụng tính năng Parcel để tạo tệp gói với các ví dụ về mã nêu trên. Parcel đã xoá tất cả mã không sử dụng và xuất mô-đun duy nhất này:

console.log(7+10);

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

Việc đóng gói chỉ là một khía cạnh của hiệu suất web, nhưng có tác động lớn về hiệu suất, đặc biệt là với các thư viện lớn hơn. Rung cây thường đơn giản hơn khi sử dụng 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, các bản cập nhật phần mềm bổ sung chức năng, sửa lỗi và sau 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. Tuy nhiên, nếu bản cập nhật bao gồm bản sửa lỗi, tính năng nâng cao bạn muốn hoặc bản sửa lỗi bảo mật, thì có thể bạn nên cập nhật. Tuy nhiên, bạn càng gửi nhiều dữ liệu qua mạng, ứng dụng của bạn càng kém hiệu quả và ảnh hưởng đến hiệu suất đối với trải nghiệm người dùng càng lớn.

Nếu thư viện phát triển về kích thước, bạn có thể dùng tính năng rung cây để giảm thiểu sự tăng trưởng. Ngoài ra, bạn có thể sử dụng một giải pháp thay thế nhỏ hơn cho thư viện JavaScript. Để biết thêm thông tin, hãy xem bài viết Khả năng hoán đổi.

Nếu một khung phát triển về kích thước, thì cây không chỉ rung chuyển nhiều hơn mà còn gặp nhiều khó khăn hơn khi thay đổi khung này cho khung khác. Để biết thêm thông tin, hãy xem bài viết Khả năng hoán đổi.

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

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

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

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

  • Hãy nhớ rằng nếu dành nhiều thời gian trong sự nghiệp của mình chỉ cho một khung làm việc, bạn có thể bỏ lỡ những trải nghiệm học hỏi các khung làm việc khác hiện đại hơn.
  • Hãy cân nhắc một nhà phát triển không hiểu rõ các kiến thức cơ bản về phát triển phần mềm hoặc phát triển web, 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 rắc rối 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ụ: có thể bạn phải tái cấu trúc mã hoặc điều chỉnh hiệu suất vì mã này chạy chậm.
  • Khi bạn tìm hiểu cách phát triển web, cách tốt nhất là bắt đầu bằng việc tập trung hoàn toàn vào các nguyên tắ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. Một nền tảng vững chắc như vậy sẽ giúp bạn chọn bất kỳ khung JavaScript nào một cách nhanh chóng và hiệu quả.

Kết luận

Bạn đã rất nỗ lực trong việc tìm hiểu so sánh các khung và thư viện JavaScript. Bạn sẽ không thường xuyên chọn các khung hoặc thư viện trừ phi bạn làm việc trong các dự án các công ty mới hoặc với tư cách là một nhà tư vấn. Tuy nhiên, khi những quyết định như vậy phát sinh, 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, việc lựa chọn khung phát triển (và trong một số trường hợp, việc 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 của bạn, chẳng hạn như hiệu suất.