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 cho thiết bị di động.
Các nội dung thảo luận trong bài đăng này tập trung vào sự khác biệt về chất lượng thay vì sự khác biệt về số 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 đó. Kích thước trang web ngày càng lớn 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. Ngoài các lợi ích khác, khung có thể giúp bạn lập trình hiệu quả và phân phối tính năng nhanh chóng. 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 bị nhầm lẫn với nhau. Bạn càng có nhiều kiến thức về hai khái niệm này, thì càng có nhiều khả năng bạn đư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 theo các tên khác, chẳng hạn như tiện ích, trình bổ trợ, 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, sự khác biệt giữa hai loại này có thể được tóm tắt như sau:
- Đối với thư viện, mã ứng dụng của bạn sẽ gọi mã thư viện.
- Đối với khung, mã ứng dụng của bạn được khung gọi.
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
Cũng như nhiều thư viện khác, bạn nên đọc kỹ mã này để hiểu rõ chức năng của nó. Chỉ cần một chút phép thuật là xong:
- Câu lệnh
import
nhập thư viện lodash vào chương trình JavaScript. - Phương thức
capitalize()
được gọi. - Một đối số duy nhất được truyền đến phương thức.
- Giá trị trả về được lưu vào 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 trọng lượng tổng thể của 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 đơ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 tóm tắt cho bạn. - Việc tạo bản sao của lớp
Vue
sẽ gây ra 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 giúp bạn giảm bớt gánh nặng nhận thức vì bạn không phải tự tìm hiểu vấn đề 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í cả 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ả. 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 một điểm xuất phát chức năng, chẳng hạn như khung hoặc mẫu nguyên mẫu, để giúp bạn nhanh chóng xây dựng ứng dụng web. 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 này 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ì chúng là những thứ khác nhau để 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 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 có quá nhiều lỗi nên không thể sử dụng được.
- Bạn tìm hiểu về một gói mới phù hợp hơn với 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 này 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 ba 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ã ở 3 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 đã được trừu tượng hoá. 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 gỡ lỗi 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, 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 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ó của bạn, 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
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 đến hiệu suất, đặc biệt là 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.js
và sidebar.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));
Để 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ã này 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 tiến xa hơn nữa vì chúng kết hợp tính năng 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.
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 đến hiệu suất, đặc biệt là 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 kích thước của một thư viện tăng lên, 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 thay thế nhỏ hơn cho thư viện JavaScript. Để 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 này cho một khung khác. Để biết thêm thông tin, hãy xem phần Khả năng hoán đổi.
Khả năng tìm việc
Có một bí mật không còn là bí mật nữa là nhiều công ty có những yêu cầu khắt khe đối với các nhà phát triển biết một khung 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.
Việc nắm được 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 cũng không đảm bảo rằng điều này sẽ giúp bạ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 đang mắc kẹt với các khung JavaScript rất cũ và thậm chí có thể rất cần những ứng viên quen thuộc với các khung như vậ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õ về các nguyên tắc cơ bản của việc phát triển phần mềm hoặc phát triển web, nhưng lại đượ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. Nền tảng vững chắc như vậy giúp bạn nắm bắt nhanh chóng và hiệu quả mọi khung JavaScript.
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 trên các dự án mới hoặc làm 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.