Phát triển front-end có vẻ đơn giản hơn vào đầu những năm 2000, phải không? Trang web tiêu chuẩn chủ yếu bao gồm các trang tĩnh được tạo bằng HTML và CSS được nêm nếm bằng một chút JavaScript và jQuery. Ý tôi là, ai mà không nhớ những ngày tương thích với nhiều trình duyệt, phải không?
Chuyển tiếp nhanh đến ngày nay và có vẻ như một vũ trụ song song đang diễn ra với vô số lựa chọn. Bạn nên sử dụng framework nào cho một dự án mới? Có lẽ là những framework đã được thiết lập lâu đời hơn như React, Angular, Vue, Svelte hoặc có thể là framework mới hấp dẫn vừa ra mắt vào tháng trước? Mỗi framework đều có hệ sinh thái riêng. Bạn cũng cần quyết định xem có nên sử dụng TypeScript thay vì JavaScript thuần túy hay không và chọn cách tiếp cận kết xuất phía máy chủ (hoặc tạo trang web tĩnh) bằng siêu framework như Next, Nuxt hoặc Gatsby. Và chúng ta không thể quên về thử nghiệm đơn vị và đầu cuối nếu bạn muốn một ứng dụng web không có lỗi. Và chúng ta mới chỉ khai thác được bề mặt của hệ sinh thái front-end!
Nhưng liệu việc xây dựng trang web có thực sự trở nên phức tạp hơn không? Rất nhiều khuôn khổ và công cụ mà chúng ta tiếp cận ngày nay ban đầu được tạo ra cho các dự án lớn. Là người mới, thật đáng sợ khi phải cân nhắc quá nhiều thứ, gần như tạo ra nỗi sợ bỏ lỡ mà chúng ta thấy bị khai thác để bán các khóa học và hướng dẫn về khuôn khổ mới hấp dẫn mà bạn "không thể làm việc nếu không có".
Tất cả những điều này tạo ra ấn tượng rằng phát triển web có lẽ đã trở nên quá phức tạp. Nhưng có lẽ đó chỉ là một sự cường điệu? Trong bài viết này, tôi muốn khám phá những tuyên bố đó và tìm hiểu xem phát triển web có thực sự phức tạp như vậy không và quan trọng nhất là làm thế nào chúng ta có thể ngăn chặn nó trở nên khó khăn hơn những gì chúng ta vẫn nghĩ.
Các ứng dụng web lớn và năng động chắc chắn đã tồn tại vào thời điểm đó — YouTube và Facebook, để kể tên một số ứng dụng — nhưng chúng được phát triển bởi các công ty lớn. Không ai được kỳ vọng sẽ tự mình hoặc thậm chí là một nhóm nhỏ tạo ra loại dự án đó. Đó sẽ là ngoại lệ chứ không phải là chuẩn mực.
Tôi nhớ lại thời điểm đó, có xu hướng lo lắng nhiều hơn về những thứ như SEO và tối ưu hóa trang hơn là cách cấu hình IDE của mình, nhưng chỉ đến mức thêm thẻ meta và từ khóa vì các thông lệ tốt nhất không bao gồm thu nhỏ tất cả các tài sản của bạn, ba lần lắc mã của bạn, lưu trữ đệm trang web của bạn trên CDN biên hoặc hiển thị nội dung của bạn trên máy chủ (một vấn đề do các khuôn khổ hiện đại tạo ra cùng với hydrat hóa). Các yếu tố khác như khả năng truy cập, trải nghiệm người dùng và bố cục phản hồi cũng phần lớn bị bỏ qua so với các tiêu chuẩn ngày nay. Bây giờ, chúng được phân tích sâu sắc và được sử dụng để tăng điểm Lighthouse và gây ấn tượng với các thuật toán của công cụ tìm kiếm.
Web và mọi thứ xung quanh nó đã thay đổi khi nhiều khả năng được thêm vào và ngày càng nhiều người phụ thuộc vào nó. Chúng tôi đã tạo ra các giải pháp mới, công cụ mới, quy trình làm việc mới, tính năng mới và bất kỳ thứ gì mới khác cần thiết để đáp ứng một trang web lớn hơn với những nhu cầu thậm chí còn lớn hơn.
Web luôn có những vấn đề trong quá khứ đáng để khắc phục: Tôi hoàn toàn không nhớ các bảng và bố cục nổi, cùng với thao tác DOM lộn xộn. Bài đăng này không nhằm mục đích hạ thấp những tiến bộ mới trong khi hoài niệm về những ngày tươi đẹp của "web hoang dã cũ". Tuy nhiên, đồng thời, những vấn đề của ngày hôm qua có vẻ đơn giản hơn vô cùng so với những vấn đề mà chúng ta phải đối mặt ngày nay.
Phát triển phần cuối là một chủ đề hoàn toàn khác, tùy thuộc vào sự phức tạp riêng của nó. Tôi chỉ muốn tập trung vào phát triển front-end vì đó là ngành có lẽ đã vượt quá ranh giới của nó nhiều nhất khi xâm nhập vào các mối quan tâm truyền thống về back-end.
Nhưng framework cốt lõi chỉ là một phần của ứng dụng web. Một số công nghệ khác tạo nên cái được gọi là "stack" công nghệ và với việc web ngày càng có nhiều người dùng và framework đáp ứng nhu cầu của họ, các stack công nghệ ngày càng lớn hơn. Bạn có thể đã thấy các stack phổ biến như MEAN (MongoDB, Express, Angular và Node) hoặc các biến thể React (MERN) và Vue (MEVN) của nó. Các stack này được tiếp thị là nền tảng trưởng thành, đã được kiểm tra phù hợp với bất kỳ dự án front-end nào. Điều đó có nghĩa là kích thước được quảng cáo của một khuôn khổ cốt lõi bị đánh giá thấp một cách nghiêm trọng vì chúng dựa vào các khuôn khổ vi mô khác để đảm bảo kiến trúc có độ tin cậy cao, như bạn có thể thấy trong stackshare.io. Bên cạnh đó, không có một ngăn xếp nào phù hợp với tất cả; công cụ tốt nhất luôn phụ thuộc — và sẽ tiếp tục phụ thuộc — vào nhu cầu và mục tiêu của dự án cụ thể của bạn.
Điều này có nghĩa là mỗi dự án mới có thể yêu cầu một kiến trúc độc đáo để đáp ứng các yêu cầu của nó. Các công ty công nghệ lớn cần các kiến trúc khổng lồ trên tất cả các dự án của họ và các ngăn xếp của họ được thiết kế cao theo đó để đảm bảo khả năng mở rộng và bảo trì. Họ cũng có lượng khách hàng khổng lồ, vì vậy việc duy trì một cơ sở mã lớn sẽ dễ dàng hơn với nhiều doanh thu hơn, nhiều kỹ sư hơn và bức tranh rõ ràng hơn về vấn đề. Để giảm thiểu lãng phí, các ngăn xếp công nghệ của các công ty và dự án nhỏ hơn có thể và nên được giảm thiểu không chỉ để phù hợp với quy mô nhu cầu của họ mà còn phù hợp với khả năng của các nhà phát triển trong nhóm.
Chúng ta phải nhớ rằng trải nghiệm của người dùng cuối là trọng tâm vào cuối ngày và người dùng không quan tâm hoặc không biết chúng ta sử dụng ngăn xếp nào trong ứng dụng của mình. Điều họ quan tâm là một trang web đẹp mắt, hữu ích, nơi họ có thể hoàn thành mục tiêu của mình, chứ không phải công nghệ chúng ta sử dụng để đạt được mục tiêu đó. Đây là cách tôi tin rằng phát triển web không trở nên phức tạp hơn. Chính những nhà phát triển như chúng tôi đang duy trì nó bằng cách mua vào các giải pháp cho các vấn đề không cần phải giải quyết ở một quy mô nhất định.
Tôi xin nói rõ: Tôi không nói rằng phát triển web ngày nay hoàn toàn tệ. Thật vậy, chúng ta đã nhận ra rất nhiều tính năng tuyệt vời và nhiều trong số đó là nhờ các khuôn khổ JavaScript đã thúc đẩy một số tính năng nhất định. jQuery cũng có ảnh hưởng tương tự đến JavaScript trong nhiều, nhiều năm.
Chúng ta vẫn có thể tạo ra các sản phẩm khả thi tối thiểu ngày nay với nguồn lực tối thiểu. Không, những sản phẩm đó có thể không khiến mọi người nhấn nút Thích trên các bài đăng trên mạng xã hội của bạn, nhưng chúng đáp ứng các yêu cầu, không hơn không kém. Chúng ta muốn lớn hơn! Nhanh hơn! Rẻ hơn! Nhưng chúng ta không thể có cả ba.
Nếu có bất kỳ điều gì, phát triển front-end đã trở nên dễ dàng hơn rất nhiều nhờ các tính năng hiện đại giải quyết các vấn đề phát triển lâu đời, chẳng hạn như cách CSS Flexbox và Grid đã đơn giản hóa các bố cục vốn đòi hỏi các bản hack phức tạp liên quan đến các số thực và bảng. Đây cũng là cách JavaScript tiếp cận những cách mới để xây dựng tương tác vốn thường sử dụng các giải pháp thay thế thông minh hoặc mã khó hiểu, chẳng hạn như có API Intersection Observer để đơn giản hóa những thứ như tải chậm (mặc dù HTML cũng có các tính năng riêng trong lĩnh vực đó).
Ít nhất, đó là những gì mọi người có vẻ nghĩ. Nhưng điều đó có thực sự đúng không? Tôi cho rằng ngược lại. Các khuôn khổ JavaScript được sử dụng tốt nhất trên các ứng dụng lớn hơn. Nếu bạn đang làm việc trên một dự án nhỏ hơn, một khuôn khổ dựa trên thành phần sẽ chỉ làm phức tạp vấn đề, khiến bạn chia trang web của mình thành một hệ thống phân cấp thành phần, điều này trở nên quá mức cần thiết đối với các dự án nhỏ.
Ý tưởng cần một khuôn khổ cho mọi thứ đã bị thổi phồng quá mức. Có thể không trực tiếp, nhưng bạn vô thức có cảm giác đó bất cứ khi nào tên của một khuôn khổ xuất hiện, như kỹ sư Edge Alex Russell đã diễn đạt một cách hùng hồn trong bài viết của mình, “The Market For Lemons”:
Hãy lùi lại và suy nghĩ về điều này: HTML, CSS và một chút JavaScript có đủ để xây dựng trang web hoặc ứng dụng web của bạn không? Nếu có, hãy sử dụng chúng. Điều tôi sợ là thêm sự phức tạp vì lợi ích của sự phức tạp và vô tình tạo ra rào cản gia nhập đối với những người mới tham gia phát triển web. Chúng ta vẫn có thể hoàn thành được rất nhiều việc chỉ với HTML và CSS, một lần nữa nhờ vào nhiều tiến bộ trong thập kỷ qua. Nhưng chúng tôi tạo ra ấn tượng rằng chúng không phù hợp với nhu cầu sử dụng web ngày nay và cần phải được cải thiện.
Mandy Michael giải thích tác động của việc theo đuổi "full-stack" đối với các nhà phát triển đang cố gắng theo kịp:

Thực tế là nhiều nhà phát triển mới vào nghề có xu hướng lao ngay vào các khuôn khổ mà không hiểu những kiến thức cơ bản về HTML và CSS không phải là vấn đề mới, vì Rachel Andrew đã thảo luận vào năm 2019:
Khóa nhà cung cấp trong phát triển web theo truyền thống bị giới hạn ở phần phụ trợ, giống như các dịch vụ đám mây như AWS hoặc Firebase; trong khi đó, khuôn khổ giao diện người dùng là một mối quan tâm hoàn toàn riêng biệt. Tuy nhiên, tôi đã nhận thấy một xu hướng gần đây là khóa nhà cung cấp đang vươn tới cả các siêu khuôn khổ. Với các công ty đứng sau một số siêu khuôn khổ cung cấp dịch vụ lưu trữ cho các sản phẩm của riêng họ, việc hoán đổi máy chủ ngày càng khó thực hiện (cho dù khóa được thiết kế có chủ ý hay không). Tất nhiên, các công ty và nhà phát triển sẽ có nhiều khả năng chọn dịch vụ lưu trữ của công ty đã tạo ra một khuôn khổ cụ thể được sử dụng trong các dự án của họ — họ là những chuyên gia! — nhưng điều đó chỉ làm tăng sự phụ thuộc của dự án vào các nhà cung cấp đó và các dịch vụ của họ.
Một ví dụ rõ ràng là mối quan hệ giữa Next và Vercel, dịch vụ đám mây mẹ của Next. Với sự ra mắt của Next 13, việc thiết lập một dự án Next bên ngoài Vercel ngày càng trở nên khó khăn hơn, dẫn đến các dự án như Open Next, được nêu ngay trên trang web của mình rằng “[m]hile Vercel rất tuyệt, nhưng đây không phải là lựa chọn tốt nếu toàn bộ cơ sở hạ tầng của bạn đều nằm trên AWS. Lưu trữ trong tài khoản AWS của bạn giúp dễ dàng tích hợp với phần phụ trợ của bạn [sic]. Và nó rẻ hơn nhiều so với Vercel.” May mắn thay, mối quan tâm của các nhà phát triển đã được lắng nghe và Next 14 làm rõ cách tự lưu trữ Next trên máy chủ Node.
Một ví dụ khác là Gatsby và Gatsby Cloud. Gatsby luôn cung cấp các hướng dẫn hữu ích và các đề xuất lưu trữ thay thế, nhưng kể từ khi ra mắt Gatsby Cloud vào năm 2019, khuôn khổ chính đã được tối ưu hóa để việc sử dụng Gatsby và Gatsby Cloud cùng nhau không yêu cầu cấu hình lưu trữ bổ sung. Thật tuyệt vời nếu bạn áp dụng cả hai, nhưng sẽ không tuyệt lắm nếu bạn chỉ cần một trong hai vì việc tích hợp khuôn khổ với các máy chủ khác — và ngược lại — đơn giản là khó hơn. Giống như thể bạn bị phạt vì thực hiện quyền lựa chọn.
Và đừng quên rằng không có nhóm nào mong đợi Netlify mua lại Gatsby Cloud vào tháng 2 năm 2023. Đây là trường hợp điển hình mà vấn đề khóa nhà cung cấp ảnh hưởng đến tất cả mọi người vì việc chuyển đổi từ trang web này sang trang web khác phải trả giá. Một số nhóm đã bị tính thêm 120% sau khi chuyển đổi từ Gatsby Cloud sang Netlify — ngay cả khi họ vẫn sử dụng cùng một gói dịch vụ với Gatsby Cloud!
Giải pháp là gì? Câu trả lời phổ biến mà tôi nghe được là ngừng sử dụng các dịch vụ đám mây trả phí để chuyển sang các giải pháp thay thế nguồn mở. Mặc dù điều đó tuyệt vời và thực sự là một lựa chọn khả thi cho một số dự án, nhưng nó không tính đến việc một dự án nguồn mở có thể không đáp ứng các yêu cầu cần thiết cho một ứng dụng nhất định.
Và ngay cả khi đó, phần mềm nguồn mở vẫn phụ thuộc vào cộng đồng các nhà phát triển bảo trì và cập nhật cơ sở mã với rất ít hoặc không có thù lao để đổi lại. Hơn nữa, nguồn mở cũng dễ bị ràng buộc vào một số giải pháp nhất định được thiết kế để giải quyết một khiếm khuyết của phần mềm.
Tất nhiên, có những khuôn khổ và thư viện không có nguy cơ bị bỏ rơi. React là một ví dụ tuyệt vời vì nó có một cộng đồng tích cực tham gia ủng hộ. Nhưng bạn không thể có cùng sự đảm bảo với mỗi phụ thuộc mới mà bạn thêm vào một dự án. Chúng ta không thể cứ tiếp tục cài đặt thêm nhiều gói và thành phần mỗi khi phát hiện ra điểm yếu trong chuỗi phụ thuộc, đặc biệt là khi một dự án hoàn toàn phù hợp với kiến trúc ít phức tạp hơn, tận dụng đúng nền tảng web.
Điều này làm tôi nhớ đến câu trích dẫn nổi tiếng:
Kể từ khi React được mã nguồn mở vào năm 2013 (và gần như được cấp phép lại vào năm 2017, nếu không phải vì cộng đồng WordPress), hàng trăm tiện ích mới đã được tạo ra để giải quyết nhiều vấn đề cụ thể của React. Làm thế nào để bạn bắt đầu một dự án React? Có Create React App và Vite. Bạn có cần nâng cao quản lý trạng thái của mình không? Có Redux, trong số các tùy chọn khác. Cần trợ giúp để tạo biểu mẫu? Có React Hook Form. Và có lẽ câu hỏi quan trọng nhất: Bạn có cần máy chủ render? Có Next, Remix hoặc Gatsby cho việc đó. Mỗi giải pháp đều có những cảnh báo riêng và các nhà phát triển sẽ tạo ra các giải pháp riêng cho chúng.
Có thể không công bằng khi chọn React vì nó tự coi mình là thư viện chứ không phải là khung. Nó chắc chắn có xu hướng được cộng đồng mở rộng. Trong khi đó, Angular và Vue là các khung có hệ sinh thái cộng đồng riêng. Và đây chỉ là phần nổi của tảng băng chìm vì có rất nhiều khung JavaScript ngoài kia, mỗi khung có hệ tư tưởng và phụ thuộc riêng biệt.
Một lần nữa, tôi không muốn bạn hiểu sai ý. Tôi thích việc các công nghệ mới xuất hiện và thấy thoải mái khi có nhiều lựa chọn như vậy. Nhưng khi xây dựng một thứ đơn giản như trang web hoặc trang web nhỏ — mà một số người bắt đầu gọi là "ứng dụng nhiều trang" — chúng ta phải vạch ra một ranh giới xác định số lượng công nghệ mới mà chúng ta sử dụng và mức độ tin cậy của chúng. Về cơ bản, chúng ta đang kết hợp mã của bên thứ ba do nhiều nhà phát triển bên thứ ba viết. Có thể có vấn đề gì không? Vui lòng không trả lời câu hỏi đó.
Hãy nhớ rằng người dùng của chúng ta không quan tâm đến những gì trong ngăn xếp của chúng ta. Họ chỉ nhìn thấy sản phẩm cuối cùng, vì vậy chúng ta có thể tự cứu mình khỏi việc làm việc trên các kiến trúc không cần thiết mà không được đánh giá cao bên ngoài các vòng tròn phát triển. Có vẻ như điều này trái ngược với trực giác khi đối mặt với công nghệ tiên tiến, nhưng việc biết rằng người dùng không quan tâm đến những gì diễn ra đằng sau hậu trường và chỉ nhìn thấy sản phẩm cuối cùng sẽ cải thiện đáng kể trải nghiệm của nhà phát triển và giải phóng bạn khỏi các phụ thuộc bị khóa. Tại sao phải sửa thứ không bị hỏng?
Hãy tưởng tượng bạn đang phát triển một ứng dụng cho phép người dùng khám phá, đánh giá và xếp hạng các nhà hàng trong khu vực của họ. Ứng dụng cần tối thiểu thông tin về từng nhà hàng, một công cụ tìm kiếm để truy vấn thông tin về nhà hàng đó và một luồng đăng ký tài khoản có xác thực để truy cập tài khoản một cách an toàn. Thật dễ dàng để đưa ra giả định về những gì người dùng trong tương lai có thể cần ngoài các tính năng quan trọng này. Trong nhiều trường hợp, một dự án bị trì hoãn vì chúng ta thêm các tính năng không cần thiết như SSR, thông báo, chế độ ngoại tuyến và hình ảnh động đẹp mắt — đôi khi trước khi ứng dụng chuyển đổi được người dùng đã đăng ký đầu tiên!
Tôi tin rằng chúng ta có thể cô đọng vấn đề phức tạp thành mong muốn cá nhân và nhu cầu được nhận thức thay vì xác định phạm vi dự án một cách phù hợp dựa trên nhu cầu và trải nghiệm của người dùng.
Mức độ phạm vi mở rộng đó có thể dễ dàng biến thành một sản phẩm được thiết kế quá mức và có khả năng sẽ không bao giờ được ra mắt.

Chúng ta có thể làm gì để đơn giản hóa các dự án của riêng mình? Lời khuyên sau đây có liên quan khi bạn kiểm soát được dự án của mình, vì đó là dự án cá nhân, dự án nhỏ hơn dành cho nhóm nhỏ hơn hoặc bạn kiểm soát được các quyết định trong bất kỳ tổ chức nào mà bạn tham gia.
Bước khó nhất và quan trọng nhất là có cảm giác phát hiện khi cơ sở mã của bạn trở nên phức tạp không cần thiết. Tôi cho rằng đây là bước khó nhất vì không chắc chắn về các yêu cầu hoặc nhu cầu của người dùng; chúng ta chỉ có thể đưa ra các giả định. Một số thì hiển nhiên, chẳng hạn như giả định rằng người dùng sẽ cần một cách để đăng nhập vào ứng dụng. Những điều khác có thể không rõ ràng, chẳng hạn như liệu ứng dụng có nên có chức năng nhắn tin riêng tư giữa những người dùng hay không. Những lý do khác vẫn còn xa vời, chẳng hạn như việc tin rằng người dùng cần độ trễ cực thấp trên trang thương mại điện tử. Các tính năng khác nằm trong phạm vi "có thì tốt".
Điều đó liên quan đến trải nghiệm người dùng, nhưng những câu hỏi tương tự lại nảy sinh ở phía phát triển:

Chúng ta cũng nên tự hỏi điều gì sẽ xảy ra nếu một tính năng hoặc phụ thuộc cụ thể không được thêm vào dự án. Nếu câu trả lời là "không có gì", thì chúng ta nên chuyển sự chú ý của mình sang thứ khác.
Một câu hỏi khác đáng để hỏi: "Tại sao chúng ta lại chọn thêm [X]?" Có phải vì đó là thứ đang phổ biến tại thời điểm đó hay vì nó giải quyết được vấn đề ảnh hưởng đến một tính năng cốt lõi? Một khía cạnh khác cần xem xét là mức độ quen thuộc của chúng ta với một số công nghệ nhất định và ưu tiên những công nghệ mà chúng ta biết và có thể bắt đầu sử dụng ngay thay vì phải dừng lại và tìm hiểu mọi ngóc ngách của một khuôn khổ mới.
Chọn đúng công cụ cho công việc, công cụ đáp ứng các yêu cầu và phù hợp với mô hình tinh thần của bạn. Tập trung ít hơn vào mức độ phổ biến và khả năng mở rộng của thư viện mà thay vào đó là đưa ứng dụng của bạn đến điểm cần mở rộng ngay từ đầu.
Sau khi đọc từ "khung" chính xác 48 lần trong bài viết này, giờ chúng ta có thể nói rằng web đang trở nên quá phức tạp không? Bản chất của nó vốn phức tạp ngay từ khi mới ra đời, nhưng sự phức tạp không có nghĩa là các ứng dụng web được "thiết kế quá mức". Web không phải là thiết kế quá mức về bản chất, và chúng ta chỉ có thể tự trách mình vì đã thiết kế quá mức các dự án của mình bằng các giải pháp được xây dựng quá mức cho các nhu cầu được nhận thức.
Chuyển tiếp nhanh đến ngày nay và có vẻ như một vũ trụ song song đang diễn ra với vô số lựa chọn. Bạn nên sử dụng framework nào cho một dự án mới? Có lẽ là những framework đã được thiết lập lâu đời hơn như React, Angular, Vue, Svelte hoặc có thể là framework mới hấp dẫn vừa ra mắt vào tháng trước? Mỗi framework đều có hệ sinh thái riêng. Bạn cũng cần quyết định xem có nên sử dụng TypeScript thay vì JavaScript thuần túy hay không và chọn cách tiếp cận kết xuất phía máy chủ (hoặc tạo trang web tĩnh) bằng siêu framework như Next, Nuxt hoặc Gatsby. Và chúng ta không thể quên về thử nghiệm đơn vị và đầu cuối nếu bạn muốn một ứng dụng web không có lỗi. Và chúng ta mới chỉ khai thác được bề mặt của hệ sinh thái front-end!
Nhưng liệu việc xây dựng trang web có thực sự trở nên phức tạp hơn không? Rất nhiều khuôn khổ và công cụ mà chúng ta tiếp cận ngày nay ban đầu được tạo ra cho các dự án lớn. Là người mới, thật đáng sợ khi phải cân nhắc quá nhiều thứ, gần như tạo ra nỗi sợ bỏ lỡ mà chúng ta thấy bị khai thác để bán các khóa học và hướng dẫn về khuôn khổ mới hấp dẫn mà bạn "không thể làm việc nếu không có".
Tất cả những điều này tạo ra ấn tượng rằng phát triển web có lẽ đã trở nên quá phức tạp. Nhưng có lẽ đó chỉ là một sự cường điệu? Trong bài viết này, tôi muốn khám phá những tuyên bố đó và tìm hiểu xem phát triển web có thực sự phức tạp như vậy không và quan trọng nhất là làm thế nào chúng ta có thể ngăn chặn nó trở nên khó khăn hơn những gì chúng ta vẫn nghĩ.
Trước đây như thế nào
Là một người bắt đầu phát triển web sau năm 2010, tôi không thể chứng thực cho trải nghiệm của riêng mình về cách phát triển web từ cuối những năm 1990 đến những năm 2000. Tuy nhiên, ngay cả mười lăm năm trước, việc học phát triển front-end đơn giản hơn vô cùng, ít nhất là đối với tôi. Bạn có thể bắt đầu một trang web với các trang HTML tĩnh, CSS tối thiểu để tạo kiểu và một chút JavaScript (và có thể là một chút jQuery) để thêm các tính năng tương tác, từ thanh bên chuyển đổi đến vòng quay hình ảnh và các mẫu khác. Không có nhiều điều khác được mong đợi từ nhà phát triển trung bình của bạn ngoài điều đó — mọi thứ khác đều được coi là "nỗ lực hơn nữa". Tất nhiên, các tính năng CSS và JavaScript gốc tuyệt vời mà chúng ta có ngày nay không có vào thời điểm đó, nhưng chúng cũng không cần thiết đối với những gì được coi là thông lệ tốt nhất trong những năm trước.Các ứng dụng web lớn và năng động chắc chắn đã tồn tại vào thời điểm đó — YouTube và Facebook, để kể tên một số ứng dụng — nhưng chúng được phát triển bởi các công ty lớn. Không ai được kỳ vọng sẽ tự mình hoặc thậm chí là một nhóm nhỏ tạo ra loại dự án đó. Đó sẽ là ngoại lệ chứ không phải là chuẩn mực.
Tôi nhớ lại thời điểm đó, có xu hướng lo lắng nhiều hơn về những thứ như SEO và tối ưu hóa trang hơn là cách cấu hình IDE của mình, nhưng chỉ đến mức thêm thẻ meta và từ khóa vì các thông lệ tốt nhất không bao gồm thu nhỏ tất cả các tài sản của bạn, ba lần lắc mã của bạn, lưu trữ đệm trang web của bạn trên CDN biên hoặc hiển thị nội dung của bạn trên máy chủ (một vấn đề do các khuôn khổ hiện đại tạo ra cùng với hydrat hóa). Các yếu tố khác như khả năng truy cập, trải nghiệm người dùng và bố cục phản hồi cũng phần lớn bị bỏ qua so với các tiêu chuẩn ngày nay. Bây giờ, chúng được phân tích sâu sắc và được sử dụng để tăng điểm Lighthouse và gây ấn tượng với các thuật toán của công cụ tìm kiếm.
Web và mọi thứ xung quanh nó đã thay đổi khi nhiều khả năng được thêm vào và ngày càng nhiều người phụ thuộc vào nó. Chúng tôi đã tạo ra các giải pháp mới, công cụ mới, quy trình làm việc mới, tính năng mới và bất kỳ thứ gì mới khác cần thiết để đáp ứng một trang web lớn hơn với những nhu cầu thậm chí còn lớn hơn.
Web luôn có những vấn đề trong quá khứ đáng để khắc phục: Tôi hoàn toàn không nhớ các bảng và bố cục nổi, cùng với thao tác DOM lộn xộn. Bài đăng này không nhằm mục đích hạ thấp những tiến bộ mới trong khi hoài niệm về những ngày tươi đẹp của "web hoang dã cũ". Tuy nhiên, đồng thời, những vấn đề của ngày hôm qua có vẻ đơn giản hơn vô cùng so với những vấn đề mà chúng ta phải đối mặt ngày nay.
JavaScript Frameworks
Các framework JavaScript, như Angular và React, được Google và Facebook tạo ra để sử dụng trong các dự án của riêng họ và đáp ứng nhu cầu mà chỉ những công ty lớn dựa trên web như họ mới có. Đó chính là vấn đề chính với tính phức tạp của web: Các framework JavaScript ban đầu được tạo ra để duy trì các dự án lớn chứ không phải các dự án nhỏ hơn. Nhiều nhà phát triển đánh giá thấp rất nhiều thời gian cần thiết để xây dựng một cơ sở mã đáng tin cậy và có thể bảo trì bằng một framework JavaScript. Tuy nhiên, giải pháp thay thế là sử dụng JavaScript thuần túy tệ hơn và jQuery không đủ cho nhiệm vụ này. JavaScript thuần túy cũng không thể phát triển đủ nhanh để đáp ứng nhu cầu phát triển của chúng tôi, vốn đã thay đổi từ các trang web thông tin đơn giản sang các ứng dụng động. Vì vậy, nhiều người trong chúng ta đã nhanh chóng áp dụng các framework để tránh trực tiếp trộn lẫn với JavaScript và thao tác DOM lộn xộn của nó.Phát triển phần cuối là một chủ đề hoàn toàn khác, tùy thuộc vào sự phức tạp riêng của nó. Tôi chỉ muốn tập trung vào phát triển front-end vì đó là ngành có lẽ đã vượt quá ranh giới của nó nhiều nhất khi xâm nhập vào các mối quan tâm truyền thống về back-end.
Stacks ngày càng lớn hơn
Việc các framework JavaScript phát triển theo thời gian là điều hợp lý. Web là một nơi rộng lớn và không một framework nào có thể bao quát mọi thứ. Nhưng chúng cố gắng và độ phức tạp, đến lượt nó, tăng lên. Kích thước của một framework dường như có mối tương quan một-một với độ phức tạp của nó.Nhưng framework cốt lõi chỉ là một phần của ứng dụng web. Một số công nghệ khác tạo nên cái được gọi là "stack" công nghệ và với việc web ngày càng có nhiều người dùng và framework đáp ứng nhu cầu của họ, các stack công nghệ ngày càng lớn hơn. Bạn có thể đã thấy các stack phổ biến như MEAN (MongoDB, Express, Angular và Node) hoặc các biến thể React (MERN) và Vue (MEVN) của nó. Các stack này được tiếp thị là nền tảng trưởng thành, đã được kiểm tra phù hợp với bất kỳ dự án front-end nào. Điều đó có nghĩa là kích thước được quảng cáo của một khuôn khổ cốt lõi bị đánh giá thấp một cách nghiêm trọng vì chúng dựa vào các khuôn khổ vi mô khác để đảm bảo kiến trúc có độ tin cậy cao, như bạn có thể thấy trong stackshare.io. Bên cạnh đó, không có một ngăn xếp nào phù hợp với tất cả; công cụ tốt nhất luôn phụ thuộc — và sẽ tiếp tục phụ thuộc — vào nhu cầu và mục tiêu của dự án cụ thể của bạn.
Điều này có nghĩa là mỗi dự án mới có thể yêu cầu một kiến trúc độc đáo để đáp ứng các yêu cầu của nó. Các công ty công nghệ lớn cần các kiến trúc khổng lồ trên tất cả các dự án của họ và các ngăn xếp của họ được thiết kế cao theo đó để đảm bảo khả năng mở rộng và bảo trì. Họ cũng có lượng khách hàng khổng lồ, vì vậy việc duy trì một cơ sở mã lớn sẽ dễ dàng hơn với nhiều doanh thu hơn, nhiều kỹ sư hơn và bức tranh rõ ràng hơn về vấn đề. Để giảm thiểu lãng phí, các ngăn xếp công nghệ của các công ty và dự án nhỏ hơn có thể và nên được giảm thiểu không chỉ để phù hợp với quy mô nhu cầu của họ mà còn phù hợp với khả năng của các nhà phát triển trong nhóm.
Cố gắng bắt chước các ngăn xếp lớn của họ là vô nghĩa. Một số người có thể cho rằng đó là sự hy sinh mà chúng ta phải thực hiện để có khả năng mở rộng và bảo trì trong tương lai, nhưng trước tiên chúng ta nên tập trung vào việc xây dựng các trang web tuyệt vời cho người dùng mà không cần lo lắng về các tính năng mà người dùng có thể cần trong tương lai. Nếu những gì chúng ta đang xây dựng là đáng để theo đuổi, nó sẽ đạt đến điểm mà chúng ta cần những kiến trúc khổng lồ đó vào đúng thời điểm. Hãy vượt qua cây cầu đó khi chúng ta đến đó. Nếu không, nó không khác gì việc đi đôi giày thể thao cỡ Shaquille O'Neal với hy vọng sẽ phát triển thành chúng. Chúng thậm chí có thể không tồn tại cho đến lúc đó nếu điều đó xảy ra!
Chúng ta phải nhớ rằng trải nghiệm của người dùng cuối là trọng tâm vào cuối ngày và người dùng không quan tâm hoặc không biết chúng ta sử dụng ngăn xếp nào trong ứng dụng của mình. Điều họ quan tâm là một trang web đẹp mắt, hữu ích, nơi họ có thể hoàn thành mục tiêu của mình, chứ không phải công nghệ chúng ta sử dụng để đạt được mục tiêu đó. Đây là cách tôi tin rằng phát triển web không trở nên phức tạp hơn. Chính những nhà phát triển như chúng tôi đang duy trì nó bằng cách mua vào các giải pháp cho các vấn đề không cần phải giải quyết ở một quy mô nhất định.
Tôi xin nói rõ: Tôi không nói rằng phát triển web ngày nay hoàn toàn tệ. Thật vậy, chúng ta đã nhận ra rất nhiều tính năng tuyệt vời và nhiều trong số đó là nhờ các khuôn khổ JavaScript đã thúc đẩy một số tính năng nhất định. jQuery cũng có ảnh hưởng tương tự đến JavaScript trong nhiều, nhiều năm.
Chúng ta vẫn có thể tạo ra các sản phẩm khả thi tối thiểu ngày nay với nguồn lực tối thiểu. Không, những sản phẩm đó có thể không khiến mọi người nhấn nút Thích trên các bài đăng trên mạng xã hội của bạn, nhưng chúng đáp ứng các yêu cầu, không hơn không kém. Chúng ta muốn lớn hơn! Nhanh hơn! Rẻ hơn! Nhưng chúng ta không thể có cả ba.
Nếu có bất kỳ điều gì, phát triển front-end đã trở nên dễ dàng hơn rất nhiều nhờ các tính năng hiện đại giải quyết các vấn đề phát triển lâu đời, chẳng hạn như cách CSS Flexbox và Grid đã đơn giản hóa các bố cục vốn đòi hỏi các bản hack phức tạp liên quan đến các số thực và bảng. Đây cũng là cách JavaScript tiếp cận những cách mới để xây dựng tương tác vốn thường sử dụng các giải pháp thay thế thông minh hoặc mã khó hiểu, chẳng hạn như có API Intersection Observer để đơn giản hóa những thứ như tải chậm (mặc dù HTML cũng có các tính năng riêng trong lĩnh vực đó).
Chúng ta có cần một khuôn khổ JavaScript cho mọi thứ không?
Mỗi dự án, bất kể sự đơn giản của nó, đều rất cần một khuôn khổ JavaScript. Một dự án không có khuôn khổ phức tạp giống như phục vụ trứng cá muối trên một đĩa giấy.Ít nhất, đó là những gì mọi người có vẻ nghĩ. Nhưng điều đó có thực sự đúng không? Tôi cho rằng ngược lại. Các khuôn khổ JavaScript được sử dụng tốt nhất trên các ứng dụng lớn hơn. Nếu bạn đang làm việc trên một dự án nhỏ hơn, một khuôn khổ dựa trên thành phần sẽ chỉ làm phức tạp vấn đề, khiến bạn chia trang web của mình thành một hệ thống phân cấp thành phần, điều này trở nên quá mức cần thiết đối với các dự án nhỏ.
Ý tưởng cần một khuôn khổ cho mọi thứ đã bị thổi phồng quá mức. Có thể không trực tiếp, nhưng bạn vô thức có cảm giác đó bất cứ khi nào tên của một khuôn khổ xuất hiện, như kỹ sư Edge Alex Russell đã diễn đạt một cách hùng hồn trong bài viết của mình, “The Market For Lemons”:
Hãy nhớ rằng, mục đích của một khuôn khổ là đơn giản hóa cuộc sống và tiết kiệm thời gian. Nếu dự án bạn đang làm nhỏ hơn, thời gian bạn tiết kiệm được có thể bị lu mờ bởi thời gian bạn dành cho việc thiết lập khung hoặc làm cho nó hoạt động với phần còn lại của dự án. Một khung có thể giúp làm cho các ứng dụng web lớn hơn trở nên tương tác và năng động hơn, nhưng đôi khi khung là một giải pháp nặng nề thực sự tạo ra các quy trình làm việc kém hiệu quả và tạo ra nợ kỹ thuật.“Những công nghệ này ban đầu được đưa ra dựa trên “trải nghiệm người dùng tốt hơn” nhưng hoàn toàn không thực hiện được lời hứa đó bên ngoài các tổ chức có trình độ quản lý cao nơi chúng ra đời. Khi được cấy ghép vào web rộng hơn, các ngăn xếp mới này đã chứng minh là những thứ vô dụng đắt đỏ.”
— Alex Russell
Hãy lùi lại và suy nghĩ về điều này: HTML, CSS và một chút JavaScript có đủ để xây dựng trang web hoặc ứng dụng web của bạn không? Nếu có, hãy sử dụng chúng. Điều tôi sợ là thêm sự phức tạp vì lợi ích của sự phức tạp và vô tình tạo ra rào cản gia nhập đối với những người mới tham gia phát triển web. Chúng ta vẫn có thể hoàn thành được rất nhiều việc chỉ với HTML và CSS, một lần nữa nhờ vào nhiều tiến bộ trong thập kỷ qua. Nhưng chúng tôi tạo ra ấn tượng rằng chúng không phù hợp với nhu cầu sử dụng web ngày nay và cần phải được cải thiện.
Biết mọi thứ và không biết gì cùng một lúc
Tiêu chuẩn được cho là các nhóm phải áp dụng kiến trúc lấy khung làm trung tâm không chỉ gây gánh nặng cho bản thân dự án mà còn cho cả phúc lợi của nhà phát triển. Như đã đề cập trước đó, hầu hết các nhóm không đủ khả năng chi trả cho các kiến trúc đó và chỉ có một số ít nhà phát triển để duy trì chúng. Nếu chúng ta phá hoại những gì có thể đạt được chỉ bằng HTML và CSS và đặt ra kỳ vọng rằng bất kỳ dự án nào — bất kể quy mô — đều cần có một ngăn xếp mới nhất, thì gánh nặng để đáp ứng những kỳ vọng đó sẽ đè lên vai nhà phát triển, với trách nhiệm lớn lao là phải thành thạo trong mọi lĩnh vực, từ máy chủ và cơ sở dữ liệu đến giao diện người dùng, đến thiết kế, đến khả năng truy cập, đến hiệu suất, đến thử nghiệm và điều đó không dừng lại. Đó là động lực thúc đẩy “Sự chia rẽ lớn” trong phát triển front-end, mà Chris Coyier giải thích như sau:Theo những kỳ vọng này, các nhà phát triển tập trung nhiều hơn vào HTML, CSS, thiết kế và khả năng truy cập thay vì công nghệ mới nhất sẽ cảm thấy ít được coi trọng trong một ngành công nghiệp dường như ca ngợi những người quan tâm đến ngăn xếp. Chính xác thì chúng ta đang nói gì khi bắt đầu phân chia trách nhiệm theo thuật ngữ “phát triển toàn diện” hoặc những thuật ngữ vô lý như “phát triển 10 lần”? Một thời gian trước, Brad Frost bắt đầu phân biệt các bộ phận này thành "front-of-the-front-end" và "back-of-the-front-end".“Sự chia rẽ nằm giữa những người tự nhận mình là (hoặc có chức danh công việc là) nhà phát triển front-end nhưng lại có các kỹ năng khác nhau. Một bên là một đội quân các nhà phát triển có sở thích, trách nhiệm và kỹ năng tập trung nhiều vào JavaScript. Mặt khác là một đội quân các nhà phát triển có sở thích, trách nhiệm và kỹ năng tập trung vào các lĩnh vực khác của front-end, như HTML, CSS, thiết kế, tương tác, mẫu, khả năng truy cập, v.v.”
— Chris Coyier
Mandy Michael giải thích tác động của việc theo đuổi "full-stack" đối với các nhà phát triển đang cố gắng theo kịp:
Đây không phải là triệu chứng duy nhất của việc áp dụng các giải pháp cứng nhắc cho những gì HTML, CSS và JavaScript “vanilla” đã xử lý tốt. Khi kỳ vọng về những gì chúng ta có thể làm với tư cách là nhà phát triển front-end tăng lên, đường cong học tập của quá trình phát triển front-end cũng tăng theo. Một lần nữa, chúng ta không thể học và biết mọi thứ trong lĩnh vực rộng lớn này. Nhưng chúng ta tự nhủ rằng mình phải làm vậy, và nhờ vào tâm lý này, thật không may là chúng ta thường thấy các nhà phát triển có thể cực kỳ thành thạo với một khuôn khổ cụ thể nhưng thực tế lại biết và hiểu rất ít về chính nền tảng web, chẳng hạn như ngữ nghĩa và cấu trúc HTML.“Điều tồi tệ nhất khi thúc đẩy tư duy "biết mọi thứ" là chúng ta sẽ tạo ra một ngành công nghiệp toàn những chuyên gia đang phải chịu đựng tình trạng kiệt sức và bệnh tâm thần. Chúng ta có những người phát biểu tại các hội nghị về sức khỏe, hội chứng kẻ mạo danh và lo lắng về full-stack, nhưng mặc dù vậy, chúng ta vẫn duy trì ý tưởng rằng mọi người phải biết mọi thứ và trở nên tuyệt vời trong việc đó.”
— Mandy Michael

Thực tế là nhiều nhà phát triển mới vào nghề có xu hướng lao ngay vào các khuôn khổ mà không hiểu những kiến thức cơ bản về HTML và CSS không phải là vấn đề mới, vì Rachel Andrew đã thảo luận vào năm 2019:
Và tôi muốn làm rõ thêm một lần nữa rằng các khuôn khổ và thư viện Javascript hiện đại không phải là xấu; chúng chỉ không được thiết kế để thay thế nền tảng web và các tiêu chuẩn của nó. Nhưng chúng ta vẫn tiếp tục thúc đẩy chúng như chúng ta muốn!“Đó là điểm khởi đầu thực sự ở đây, và đúng vậy, vào năm 2019, họ sẽ phải nhanh chóng chuyển sang các công cụ và kỹ thuật giúp họ có thể sử dụng được, nếu đó là mục tiêu của họ. Tuy nhiên, cuối cùng, các công cụ đó sẽ tạo ra HTML và CSS. Đó là nền tảng của mọi thứ chúng ta làm, khiến cho việc hạ thấp giá trị của những người có kỹ năng thực sự sâu sắc trong các lĩnh vực đó trở nên khó hiểu hơn nhiều.”
— Rachel Andrew
Hậu quả của Vendor Lock-In
“Khóa nhà cung cấp” xảy ra khi chúng ta phụ thuộc quá nhiều vào các sản phẩm và dịch vụ độc quyền đến mức việc chuyển sang các sản phẩm và dịch vụ khác trở thành nhiệm vụ gần như bất khả thi. Điều này thường xảy ra khi các dịch vụ đám mây từ một công ty cụ thể được tích hợp sâu vào một dự án. Đây là một vấn đề, đặc biệt là trong điện toán đám mây, vì việc di chuyển cơ sở dữ liệu sau khi thiết lập rất tốn kém và mất nhiều thời gian.Khóa nhà cung cấp trong phát triển web theo truyền thống bị giới hạn ở phần phụ trợ, giống như các dịch vụ đám mây như AWS hoặc Firebase; trong khi đó, khuôn khổ giao diện người dùng là một mối quan tâm hoàn toàn riêng biệt. Tuy nhiên, tôi đã nhận thấy một xu hướng gần đây là khóa nhà cung cấp đang vươn tới cả các siêu khuôn khổ. Với các công ty đứng sau một số siêu khuôn khổ cung cấp dịch vụ lưu trữ cho các sản phẩm của riêng họ, việc hoán đổi máy chủ ngày càng khó thực hiện (cho dù khóa được thiết kế có chủ ý hay không). Tất nhiên, các công ty và nhà phát triển sẽ có nhiều khả năng chọn dịch vụ lưu trữ của công ty đã tạo ra một khuôn khổ cụ thể được sử dụng trong các dự án của họ — họ là những chuyên gia! — nhưng điều đó chỉ làm tăng sự phụ thuộc của dự án vào các nhà cung cấp đó và các dịch vụ của họ.
Một ví dụ rõ ràng là mối quan hệ giữa Next và Vercel, dịch vụ đám mây mẹ của Next. Với sự ra mắt của Next 13, việc thiết lập một dự án Next bên ngoài Vercel ngày càng trở nên khó khăn hơn, dẫn đến các dự án như Open Next, được nêu ngay trên trang web của mình rằng “[m]hile Vercel rất tuyệt, nhưng đây không phải là lựa chọn tốt nếu toàn bộ cơ sở hạ tầng của bạn đều nằm trên AWS. Lưu trữ trong tài khoản AWS của bạn giúp dễ dàng tích hợp với phần phụ trợ của bạn [sic]. Và nó rẻ hơn nhiều so với Vercel.” May mắn thay, mối quan tâm của các nhà phát triển đã được lắng nghe và Next 14 làm rõ cách tự lưu trữ Next trên máy chủ Node.
Một ví dụ khác là Gatsby và Gatsby Cloud. Gatsby luôn cung cấp các hướng dẫn hữu ích và các đề xuất lưu trữ thay thế, nhưng kể từ khi ra mắt Gatsby Cloud vào năm 2019, khuôn khổ chính đã được tối ưu hóa để việc sử dụng Gatsby và Gatsby Cloud cùng nhau không yêu cầu cấu hình lưu trữ bổ sung. Thật tuyệt vời nếu bạn áp dụng cả hai, nhưng sẽ không tuyệt lắm nếu bạn chỉ cần một trong hai vì việc tích hợp khuôn khổ với các máy chủ khác — và ngược lại — đơn giản là khó hơn. Giống như thể bạn bị phạt vì thực hiện quyền lựa chọn.
Và đừng quên rằng không có nhóm nào mong đợi Netlify mua lại Gatsby Cloud vào tháng 2 năm 2023. Đây là trường hợp điển hình mà vấn đề khóa nhà cung cấp ảnh hưởng đến tất cả mọi người vì việc chuyển đổi từ trang web này sang trang web khác phải trả giá. Một số nhóm đã bị tính thêm 120% sau khi chuyển đổi từ Gatsby Cloud sang Netlify — ngay cả khi họ vẫn sử dụng cùng một gói dịch vụ với Gatsby Cloud!
Giải pháp là gì? Câu trả lời phổ biến mà tôi nghe được là ngừng sử dụng các dịch vụ đám mây trả phí để chuyển sang các giải pháp thay thế nguồn mở. Mặc dù điều đó tuyệt vời và thực sự là một lựa chọn khả thi cho một số dự án, nhưng nó không tính đến việc một dự án nguồn mở có thể không đáp ứng các yêu cầu cần thiết cho một ứng dụng nhất định.
Và ngay cả khi đó, phần mềm nguồn mở vẫn phụ thuộc vào cộng đồng các nhà phát triển bảo trì và cập nhật cơ sở mã với rất ít hoặc không có thù lao để đổi lại. Hơn nữa, nguồn mở cũng dễ bị ràng buộc vào một số giải pháp nhất định được thiết kế để giải quyết một khiếm khuyết của phần mềm.
Tất nhiên, có những khuôn khổ và thư viện không có nguy cơ bị bỏ rơi. React là một ví dụ tuyệt vời vì nó có một cộng đồng tích cực tham gia ủng hộ. Nhưng bạn không thể có cùng sự đảm bảo với mỗi phụ thuộc mới mà bạn thêm vào một dự án. Chúng ta không thể cứ tiếp tục cài đặt thêm nhiều gói và thành phần mỗi khi phát hiện ra điểm yếu trong chuỗi phụ thuộc, đặc biệt là khi một dự án hoàn toàn phù hợp với kiến trúc ít phức tạp hơn, tận dụng đúng nền tảng web.
Về cơ bản, đó là hai lựa chọn duy nhất. Nhiều nhóm mà tôi biết hoặc đã từng làm việc phụ thuộc vào các dịch vụ của bên thứ ba vì họ không đủ khả năng tự phát triển chúng; đó là một sự xa xỉ mà chỉ những công ty lớn mới có thể chi trả được. Đây là vấn đề mà chúng ta phải trải qua khi bắt đầu một dự án mới, nhưng chúng ta có thể giảm thiểu bằng cách giảm số lượng các phụ thuộc và lựa chọn một cách khôn ngoan khi cần thiết.
Mỗi giải pháp lại tạo ra một vấn đề mới
Chính xác thì tại sao các ngăn xếp phát triển hiện đại lại trở nên lớn và phức tạp như vậy? Chúng ta có thể chỉ ra "Nghịch lý phát triển". Với mỗi khuôn khổ hoặc thư viện mới, một vấn đề mới lại nảy sinh, và các nhà phát triển thiếu thời gian dành nhiều tháng để phát triển một công cụ mới để giải quyết vấn đề đó. Và khi không có vấn đề gì, đừng lo lắng — cuối cùng chúng ta sẽ tạo ra một vấn đề. Đây là một vòng phản hồi tạo ra các giải pháp và công nghệ tuyệt vời nhưng có thể dẫn đến các trang web được thiết kế quá mức nếu chúng ta không kiểm soát được.Điều này làm tôi nhớ đến câu trích dẫn nổi tiếng:
Chúng ta hãy xem xét cụ thể React. Ban đầu, React được tạo ra bởi Facebook cho Facebook để phát triển nhiều tính năng động hơn cho người dùng đồng thời cải thiện trải nghiệm của nhà phát triển trên Facebook.“Sự thật đơn giản là nếu bạn không có vấn đề, bạn sẽ tạo ra một vấn đề. Nếu bạn không có vấn đề gì, bạn không cảm thấy mình đang sống.”
— U.G. Krishnamurti
Kể từ khi React được mã nguồn mở vào năm 2013 (và gần như được cấp phép lại vào năm 2017, nếu không phải vì cộng đồng WordPress), hàng trăm tiện ích mới đã được tạo ra để giải quyết nhiều vấn đề cụ thể của React. Làm thế nào để bạn bắt đầu một dự án React? Có Create React App và Vite. Bạn có cần nâng cao quản lý trạng thái của mình không? Có Redux, trong số các tùy chọn khác. Cần trợ giúp để tạo biểu mẫu? Có React Hook Form. Và có lẽ câu hỏi quan trọng nhất: Bạn có cần máy chủ render? Có Next, Remix hoặc Gatsby cho việc đó. Mỗi giải pháp đều có những cảnh báo riêng và các nhà phát triển sẽ tạo ra các giải pháp riêng cho chúng.
Có thể không công bằng khi chọn React vì nó tự coi mình là thư viện chứ không phải là khung. Nó chắc chắn có xu hướng được cộng đồng mở rộng. Trong khi đó, Angular và Vue là các khung có hệ sinh thái cộng đồng riêng. Và đây chỉ là phần nổi của tảng băng chìm vì có rất nhiều khung JavaScript ngoài kia, mỗi khung có hệ tư tưởng và phụ thuộc riêng biệt.
Một lần nữa, tôi không muốn bạn hiểu sai ý. Tôi thích việc các công nghệ mới xuất hiện và thấy thoải mái khi có nhiều lựa chọn như vậy. Nhưng khi xây dựng một thứ đơn giản như trang web hoặc trang web nhỏ — mà một số người bắt đầu gọi là "ứng dụng nhiều trang" — chúng ta phải vạch ra một ranh giới xác định số lượng công nghệ mới mà chúng ta sử dụng và mức độ tin cậy của chúng. Về cơ bản, chúng ta đang kết hợp mã của bên thứ ba do nhiều nhà phát triển bên thứ ba viết. Có thể có vấn đề gì không? Vui lòng không trả lời câu hỏi đó.
Hãy nhớ rằng người dùng của chúng ta không quan tâm đến những gì trong ngăn xếp của chúng ta. Họ chỉ nhìn thấy sản phẩm cuối cùng, vì vậy chúng ta có thể tự cứu mình khỏi việc làm việc trên các kiến trúc không cần thiết mà không được đánh giá cao bên ngoài các vòng tròn phát triển. Có vẻ như điều này trái ngược với trực giác khi đối mặt với công nghệ tiên tiến, nhưng việc biết rằng người dùng không quan tâm đến những gì diễn ra đằng sau hậu trường và chỉ nhìn thấy sản phẩm cuối cùng sẽ cải thiện đáng kể trải nghiệm của nhà phát triển và giải phóng bạn khỏi các phụ thuộc bị khóa. Tại sao phải sửa thứ không bị hỏng?
Làm thế nào chúng ta có thể đơn giản hóa cơ sở mã của mình?
Chúng tôi đã đề cập đến một số lý do tại sao phát triển web có vẻ phức tạp hơn ngày nay so với những năm trước, nhưng việc đổ lỗi cho các nhà phát triển vì đã phát hành các tiện ích mới không phải là cách mô tả chính xác về vấn đề thực sự. Xét cho cùng, khi phát triển một trang web, chúng ta không buộc phải sử dụng mọi công nghệ mới xuất hiện trên thị trường. Trên thực tế, nhiều người trong chúng ta thường không biết về một thư viện cụ thể và chỉ tìm hiểu về nó khi phát triển một tính năng mới. Ví dụ: nếu chúng ta muốn thêm thông báo toast vào ứng dụng web của mình, chúng ta sẽ tìm kiếm một thư viện nhưreact-toastify
thay vì một số cách xây dựng khác vì nó "phù hợp" với thư viện cụ thể đó. Bạn nên tự hỏi liệu ứng dụng có cần thông báo toast hay không nếu chúng tạo ra các phụ thuộc mới.Hãy tưởng tượng bạn đang phát triển một ứng dụng cho phép người dùng khám phá, đánh giá và xếp hạng các nhà hàng trong khu vực của họ. Ứng dụng cần tối thiểu thông tin về từng nhà hàng, một công cụ tìm kiếm để truy vấn thông tin về nhà hàng đó và một luồng đăng ký tài khoản có xác thực để truy cập tài khoản một cách an toàn. Thật dễ dàng để đưa ra giả định về những gì người dùng trong tương lai có thể cần ngoài các tính năng quan trọng này. Trong nhiều trường hợp, một dự án bị trì hoãn vì chúng ta thêm các tính năng không cần thiết như SSR, thông báo, chế độ ngoại tuyến và hình ảnh động đẹp mắt — đôi khi trước khi ứng dụng chuyển đổi được người dùng đã đăng ký đầu tiên!
Tôi tin rằng chúng ta có thể cô đọng vấn đề phức tạp thành mong muốn cá nhân và nhu cầu được nhận thức thay vì xác định phạm vi dự án một cách phù hợp dựa trên nhu cầu và trải nghiệm của người dùng.
Mức độ phạm vi mở rộng đó có thể dễ dàng biến thành một sản phẩm được thiết kế quá mức và có khả năng sẽ không bao giờ được ra mắt.

Chúng ta có thể làm gì để đơn giản hóa các dự án của riêng mình? Lời khuyên sau đây có liên quan khi bạn kiểm soát được dự án của mình, vì đó là dự án cá nhân, dự án nhỏ hơn dành cho nhóm nhỏ hơn hoặc bạn kiểm soát được các quyết định trong bất kỳ tổ chức nào mà bạn tham gia.
Bước khó nhất và quan trọng nhất là có cảm giác phát hiện khi cơ sở mã của bạn trở nên phức tạp không cần thiết. Tôi cho rằng đây là bước khó nhất vì không chắc chắn về các yêu cầu hoặc nhu cầu của người dùng; chúng ta chỉ có thể đưa ra các giả định. Một số thì hiển nhiên, chẳng hạn như giả định rằng người dùng sẽ cần một cách để đăng nhập vào ứng dụng. Những điều khác có thể không rõ ràng, chẳng hạn như liệu ứng dụng có nên có chức năng nhắn tin riêng tư giữa những người dùng hay không. Những lý do khác vẫn còn xa vời, chẳng hạn như việc tin rằng người dùng cần độ trễ cực thấp trên trang thương mại điện tử. Các tính năng khác nằm trong phạm vi "có thì tốt".
Điều đó liên quan đến trải nghiệm người dùng, nhưng những câu hỏi tương tự lại nảy sinh ở phía phát triển:
- Chúng ta có nên sử dụng bộ tiền xử lý CSS hay khung CSS hay chúng ta có thể đạt được điều đó chỉ bằng cách sử dụng các mô-đun CSS?
- JavaScript thuần túy có đủ không hay chúng ta sẽ thêm TypeScript?
- Ứng dụng có cần SSR, SSG hay kết hợp cả hai không?
- Chúng ta có nên triển khai Redis ở phía sau để truy vấn cơ sở dữ liệu nhanh hơn không hay như vậy là quá nhiều phạm vi cho công việc?
- Chúng ta có nên triển khai thử nghiệm đầu cuối hay thử nghiệm đơn vị không?
Và, này, ngay cả những ứng dụng lớn nhất và phức tạp nhất cũng bắt đầu từ mức tối thiểu các dịch vụ được lặp lại trong suốt quá trình.“Hoàn thành còn hơn hoàn hảo”.
— Sheryl Sandberg

Chúng ta cũng nên tự hỏi điều gì sẽ xảy ra nếu một tính năng hoặc phụ thuộc cụ thể không được thêm vào dự án. Nếu câu trả lời là "không có gì", thì chúng ta nên chuyển sự chú ý của mình sang thứ khác.
Một câu hỏi khác đáng để hỏi: "Tại sao chúng ta lại chọn thêm [X]?" Có phải vì đó là thứ đang phổ biến tại thời điểm đó hay vì nó giải quyết được vấn đề ảnh hưởng đến một tính năng cốt lõi? Một khía cạnh khác cần xem xét là mức độ quen thuộc của chúng ta với một số công nghệ nhất định và ưu tiên những công nghệ mà chúng ta biết và có thể bắt đầu sử dụng ngay thay vì phải dừng lại và tìm hiểu mọi ngóc ngách của một khuôn khổ mới.
Chọn đúng công cụ cho công việc, công cụ đáp ứng các yêu cầu và phù hợp với mô hình tinh thần của bạn. Tập trung ít hơn vào mức độ phổ biến và khả năng mở rộng của thư viện mà thay vào đó là đưa ứng dụng của bạn đến điểm cần mở rộng ngay từ đầu.
Kết luận
Thật khó để không thiết kế quá mức các ứng dụng web khi xét đến tâm lý chung chung và sợ bỏ sót hiện nay. Nhưng chúng ta có thể ý thức hơn về các mục tiêu của dự án và cảnh giác trong việc bảo vệ công việc của mình khỏi tình trạng mở rộng phạm vi. Điều tương tự cũng có thể áp dụng cho ngăn xếp mà chúng ta sử dụng, đưa ra lựa chọn dựa trên những gì thực sự cần thiết thay vì chỉ tập trung vào những gì mọi người khác đang sử dụng cho công việc cụ thể của họ.Sau khi đọc từ "khung" chính xác 48 lần trong bài viết này, giờ chúng ta có thể nói rằng web đang trở nên quá phức tạp không? Bản chất của nó vốn phức tạp ngay từ khi mới ra đời, nhưng sự phức tạp không có nghĩa là các ứng dụng web được "thiết kế quá mức". Web không phải là thiết kế quá mức về bản chất, và chúng ta chỉ có thể tự trách mình vì đã thiết kế quá mức các dự án của mình bằng các giải pháp được xây dựng quá mức cho các nhu cầu được nhận thức.