- XSLT là công cụ build tích hợp sẵn cho web, có thể dùng ngay mà không cần hệ thống build phức tạp
- Phần lớn hệ thống build site tĩnh gặp vấn đề về độ phức tạp, khó hiểu và phụ thuộc framework
- Khi tận dụng XML và XSLT, có thể tạo HTML trực tiếp trong trình duyệt, giúp xử lý dữ liệu động và sinh markup dễ dàng
- Tất cả các trình duyệt chính đều hỗ trợ chuyển đổi dựa trên XSLT, nên có thể sử dụng mà không cần JavaScript hay công cụ riêng
- Dù không phải giải pháp hoàn hảo, đây vẫn là một lựa chọn thay thế đơn giản và linh hoạt dựa trên chuẩn web rất đáng để sử dụng
Giới thiệu và vấn đề đặt ra
- Quy trình phát triển website tĩnh của đa số dự án gồm các tệp dữ liệu (
.json, .md, .txt), một hệ thống build riêng biệt (Hugo, Next.js, Astro, v.v.) và cấu trúc đầu ra HTML
- Hệ thống build ngày càng gia tăng độ phức tạp, đến mức ngay cả một blog nhỏ cũng dần trở nên khó hiểu và khó vận hành
- Khi loại bỏ framework và cố gắng làm việc chỉ với HTML, CSS và các đặc tả tiêu chuẩn (HTTP, URI, HTML), sẽ nảy sinh giới hạn về bảo trì như việc lặp lại header hay footer
- HTML import, web component và các cách khác cũng đã được thử, nhưng cách đầu không được hỗ trợ, còn cách sau lại không trở thành giải pháp thay thế do phụ thuộc vào engine JavaScript
Biến trình duyệt web thành hệ thống build
- Ý tưởng xuất phát từ việc bản thân trình duyệt web hỗ trợ nhiều kiểu chuyển đổi dữ liệu (text/html, text/markdown, application/xml, v.v.)
- Sau khi xem xét kỹ các đặc tả web, tác giả đã suy nghĩ về cách giải quyết vấn đề mà không cần công cụ hay framework bên ngoài không cần thiết
Cách tận dụng XSLT
- Khi muốn hiển thị RSS feed đẹp hơn, tác giả đã phát hiện ra đặc tả XSLT
- XSLT là công nghệ tiêu chuẩn chính thức có thể biểu diễn cả dữ liệu XML lẫn cấu trúc đầu ra HTML
- Cách dùng khá đơn giản
- Ví dụ, sắp xếp dữ liệu trong
blog.xml
- Sau đó liên kết stylesheet XSLT như sau
<?xml-stylesheet type="text/xsl" href="blog.xsl"?>
- Trong
blog.xsl, viết template HTML và các quy tắc ánh xạ dữ liệu
- XSLT hỗ trợ hầu hết các tính năng của hệ thống build như template, lặp, biến, import tệp ngoài, v.v.
Cách chạy và ưu điểm
- Không cần công cụ riêng, chỉ cần mở tệp XML bằng trình duyệt web là kết quả chuyển đổi sẽ được render ngay
- Định dạng XML tương tự HTML nên thân thiện với con người và dễ bảo trì, dùng thay JSON cũng không quá bất tiện
- Các trình duyệt web chính đều hỗ trợ native việc chuyển đổi dựa trên XSLT, nên phía client có thể trực tiếp xem kết quả chuyển đổi
- Việc không cần JavaScript, công cụ build riêng hay bundler là một lợi thế cực lớn
- XSLT không phải là lời giải vạn năng cuối cùng, nhưng là một phương án build web đơn giản mà vẫn có khả năng mở rộng
Kết luận
- Tái khám phá giá trị của công nghệ cũ (XSLT) và các tiêu chuẩn rõ ràng
- Cách tận dụng trình duyệt web như một hệ thống build là một lựa chọn hữu ích đáng bổ sung vào bộ công cụ phát triển web
1 bình luận
Ý kiến trên Hacker News
Công ty tôi từng làm dùng XSLT rất nhiều trong các template XML, và có lẽ đến giờ vẫn vậy. Thành thật mà nói đó không phải lựa chọn hay, và nếu có thể thì hẳn họ cũng muốn chuyển sang thứ khác
JS cũng có vấn đề, nhưng ít nhất không đến mức bất lực trước kiểu độ phức tạp thuật toán này
XSLT/XPath đã tiến bộ khá nhiều sau 1.0. Có nhiều tính năng như
key(index)giúp tăng tốc xử lý đáng kể. Nếu dùng implementation XSLT chất lượng như Saxon thì vấn đề hiệu năng cũng nhẹ hơn rất nhiều. Khi chuyển đổi XML sang thứ khác, tôi nghĩ hiếm có gì tiện cho việc cấu trúc logic như XSLTXSLT khá khó học. Nó giống một thứ Prolog mộng mị, và nếu thật sự thành thạo thì có cảm giác phấn khích như giải Sudoku. Nhưng trong đa số trường hợp không cần những template phức tạp đến thế, nên khó trở thành lựa chọn tiêu chuẩn. Bản thân XML cũng không phải định dạng mà ai cũng thích
Tôi không hiểu lắm chỗ nói XSLT 1.0 vẫn còn được dùng nhiều. Ngay từ 2013 thì 1.0 gần như đã bị xem là lỗi thời, còn Saxon dùng được XSLT 2 thì miễn phí và hiệu năng cũng rất tốt. Tôi chưa từng gặp vấn đề hiệu năng khi chuyển đổi, dù là tài liệu lớn hay nhỏ
Thời kỳ XSLT ra đời là lúc việc xử lý XML có phần thân rất dài được xem là điều đương nhiên. Mà khi các vòng lặp lồng nhau như thế này thì nổ tung cũng là chuyện dễ hiểu
Không biết bạn có đang dùng bản thương mại của Saxon không. Giá cũng không quá đắt, mà xét về hỗ trợ chuẩn mới, hiệu năng và nhiều tính năng khác thì IMHO thực sự rất đáng tiền. Lần trước tôi dùng, tôi nhớ nó có các tối ưu hóa khá thông minh
Trình duyệt những năm 90-00 mỗi nơi một kiểu nên người ta bắt đầu đưa JS vào để đồng bộ hành vi
Thứ chúng ta thực ra muốn là CSS đẹp mắt, nhưng khi đó chưa dùng tử tế được
Theo thời gian, một trình duyệt dần chiếm ưu thế và các trình duyệt khác cũng trở nên khá giống nhau hơn (luật Highlander, dù Firefox vẫn chiến đấu rất ổn)
Framework rồi trở thành chuyện hiển nhiên và được cố định như cách để ép mọi trình duyệt có cùng UI. Đồng thời cả mô hình cũng chuyển sang render dữ liệu JSON
Bây giờ là thời mà ngay cả khi tạo web page kiểu truyền thống ở phía server thì vẫn nhanh và dùng ít bộ nhớ
Tôi nghĩ vậy vì gần đây khi migrate khỏi một hệ thống legacy, tôi lại trải nghiệm một site hoạt động theo kiểu request HTTP theo từng trang (chuẩn của những năm 2000). Mỗi hành động đều phải reload, nhưng ngược lại nó còn nhanh hơn hẳn hệ thống dùng React
Lý do là
AJAX và cập nhật DOM không xuất hiện chỉ để nhanh hơn. Nó xuất hiện để thoát khỏi mô hình của web, tức là vượt ra ngoài “website/web document”. Reload toàn bộ trang là cách có ý nghĩa trong mô hình lấy tài liệu làm trung tâm. Với ví dụ đơn giản như HN, cấu trúc này hoạt động cực kỳ phù hợp. Nhiều site hoàn toàn có thể vận hành tốt như vậy mà không cần JS framework.
Nhưng nói rằng “ai cũng có thể quay lại reload toàn trang” thì khá xa thực tế. Với các “web application” thật sự cần tương tác phức tạp, reload cả trang là UX rất tệ.
Tóm lại,
các “website”, “web document”, “form đơn giản” thường chỉ cần reload toàn trang là đủ, nhưng
với các trường hợp như “web application” cần màn hình dữ liệu/thao tác phức tạp thì không phải vậy
Dòng thời gian tôi nhớ hơi khác. JS ban đầu được dùng cho các yếu tố tương tác ngay từ đầu hơn là để thống nhất hành vi trình duyệt (DHTML, AJAX, v.v.). Còn chuyện dàn layout thì thực sự chủ yếu dựa vào mẹo và phát hiện user agent cho từng trình duyệt. Dù CSS mạnh hơn, vấn đề nhất quán cũng không dễ được giải quyết. CSS garden, semantic markup, lạm dụng bảng biểu là bầu không khí thời đó, và để qua được bài test ACID đầu tiên cũng mất rất lâu. Tôi hoài nghi framework đã ảnh hưởng gì lớn đến tính nhất quán UI—từ sau jQuery thì CSS mới là thủ phạm chính quyết định tính nhất quán hình ảnh.
Tất nhiên cũng có thể chỉ là ký ức cá nhân
Tôi đồng ý rằng trong stack hiện đại, web page truyền thống render ở server là nhanh và nhẹ
Trong stack .NET/Kestrel/SQLite của tôi, response SSR rất khó vượt quá 4ms. Đa số nằm ở mức vài trăm micro giây. Mỗi trang dùng nhiều query và join phức tạp để tạo hình dữ liệu đúng với view
Ngay cả trong trường hợp cực đoan như tạo bảng 100.000 dòng, nếu xử lý dữ liệu tốt trước khi ghép chuỗi HTML thì hiệu năng tăng lên rất rõ. LINQ cũng rất nhanh, nhưng nếu tạo collection cho từng dòng thì khi dữ liệu tăng lớn lại trở nên cực kỳ kém hiệu quả
Theo kinh nghiệm của tôi, cách tốt nhất để tối ưu hiệu năng là đặt template engine HTML và database càng gần nhau càng tốt. Cuối cùng DOM cũng chỉ là một luồng byte. Không nhất thiết phải dựng AST/parser phức tạp, chỉ cần kết hợp
StringBuildervới câu query SQL là đủ.Lập luận phản đối kiểu làm đơn giản này lúc nào cũng chỉ xoay quanh chuyện bên bảo mật nói rằng “không tin lập trình viên tự escape HTML cho đúng”
Nói rằng “với công nghệ hiện đại thì phía server có thể xử lý đủ kiểu web page cổ điển ngày xưa” có thể là một câu chuyện hoàn toàn khác nếu độ trễ mạng cao
Liên kết tham khảo
XML enterprise những năm 2000 đã phình to quá mức khiến công nghệ này trông như lỗi thời, và rồi mọi người đều say mê sự “gọn gàng” của JSON. Thực ra những công nghệ như XSLT, XPath vốn đã khá hoàn thiện và đã giải quyết được nhiều vấn đề mà đến nay ta vẫn còn băn khoăn
Tôi cũng từng lạm dụng XSLT include rất nhiều, dùng PHP stream wrapper kiểu như
<xsl:include href="mycorp://invoice/1234">Thành thật mà nói, cảm giác này giờ có thể hơi lỗi mốt, nhưng tôi vẫn thấy không yên tâm khi để trình duyệt tự xử lý XSLT cục bộ. Ngày xưa đó từng là một bãi mìn tương thích
Tôi vẫn nhớ những thành phần “cơ bản” của XML mà JSON còn thiếu rất lâu. Ví dụ như một spec thực sự được chuẩn hóa, hay định nghĩa schema, thì XML vượt trội hơn hẳn, còn JSON phải mất gần 10 năm mới đuổi kịp
Lần cuối tôi thật sự đụng XML là với EXI, một công nghệ truyền dẫn. Nó biến tài liệu XML thành luồng nhị phân nén, và đương nhiên quy trình cấu trúc ↔ ASCII ↔ nén/truyền ↔ giải ngược khá phiền. Giờ protobuf và gRPC là xu hướng chính, nhưng nếu XML tiếp tục được dùng rộng rãi thì có lẽ đã có một thế giới (trong trí tưởng tượng lý tưởng của tôi) nơi mọi thứ đều tương thích trên nền chuẩn chung. Thực tế thì giữa protobuf/gRPC và JSON API đã xuất hiện một bức tường rất lớn, nhưng biết đâu như thế lại tốt hơn
Tôi nghĩ XML là một định dạng ổn. Nó dài dòng và rườm rà, nhưng so với YAML thì vượt trội hơn hẳn về độ chính xác và khả năng biểu đạt
XPath khó quen, nhưng nếu chịu thử nghiệm thì cuối cùng bạn cũng làm được thứ mình muốn
Còn XSLT thì tôi thấy là một khái niệm hoàn toàn điên rồ. Nên bị loại bỏ
Game Rimworld lưu toàn bộ dữ liệu cấu hình bằng XML, và cho phép mod bằng XPath. Tổ hợp này cực kỳ mạnh. Với việc tùy biến dữ liệu cục bộ thì khó có gì bằng. Nhưng có vẻ đa số game không muốn dùng kiểu này chỉ vì XML bị gắn mác là “lỗi thời”
Tài liệu chính thức về modding XPath của Rimworld
Nhận xét rằng XML enterprise đầu những năm 2000 đã phình to quá mức là hoàn toàn đúng. Ban đầu XML là phiên bản đơn giản hóa của SGML để dùng trên web, phục vụ việc truyền markup/mở rộng vocabulary. Cuối cùng chỉ còn SVG và MathML sống sót. Trong cơn sốt web, W3C/MS tung ra hàng loạt SOAP, WS-* và các spec khác. Có một giai đoạn điên rồ khi cả những ngôn ngữ như XSLT, vốn mang bộ xương của Scheme, cũng bị ép nhét vào XML. Ngay cả JavaScript cũng là sản phẩm của thời kỳ mà cái tên còn được đặt để ăn theo Java
XPath khá đáng tiếc ở chỗ vì namespace mà phải viết các query dài dòng đến phát chán
Dạo này tôi vẫn dùng XSLT để style feed của mình.
Mẫu RSS feed
Mẫu XSLT
Nhìn những thứ như thế này lại khiến tôi nghĩ có lẽ blog đáng ra chỉ nên là một RSS feed
Tôi luôn quên mất XML vốn có thể làm được những việc như thế này. Nó tạo cảm giác trực giác hơi kỳ cục
Làm đẹp thật sự. Tôi mong nhiều người khác cũng thử áp dụng những ví dụ sáng tạo như thế này
Ở công việc đầu tiên của tôi (lúc 19 tuổi), tôi từng phụ trách tùy biến Google Search Appliance. Đó là dự án cài CentOS lên những máy chủ Dell màu vàng giá hàng chục nghìn đô, rồi đưa vào tìm kiếm toàn văn tài liệu bằng Python kiểu Google và CIFS.
Khoảng năm 2011, XHTML đang là xu hướng, và trong Google Search Appliance thì dữ liệu XML ở backend được chuyển thành XHTML bằng XSLT. Tôi đã phá nát template mẫu để làm ra một UI quái dị cho intranet nội bộ, rồi chắp vá Coldfusion, StackOverflow, W3Schools và những tài sản có sẵn khác vào đó
Tôi đã xóa kinh nghiệm này khỏi CV rất nhanh. Sau đó các nhà thầu phụ của DoD liên tục tìm đến, bảo tôi là “chuyên gia XML” rồi muốn kéo vào các dự án hiện đại hóa hệ thống tài liệu, rất mệt
Lần tới khi bạn thở dài vì phải dùng JSX để lặp mảng từ JSON sang TypeScript interface, hãy nhớ đến câu chuyện của tôi. Dù sao vẫn còn đỡ hơn làm chuyện đó bằng XSLT
Tôi đúng là kiểu người theo đuổi sự đơn giản. Tôi thích tài liệu dễ hiểu như readme của người tiền sử. Đôi lúc cũng thấy mình như người nguyên thủy đang vung bàn phím. Tôi không làm web và cũng không rành XSLT. Thỉnh thoảng tôi hack chút XML và muốn cho người dùng thấy thứ gì đó đẹp mắt. Có quá nhiều file format khiến đầu óc quay cuồng. Nhưng tôi vẫn thích thứ gì đó trông đẹp. Có khi tôi cũng sẽ dùng cái này
Cảm ơn vì đã đọc spec giúp, và cảm ơn vì đã làm ra công cụ này
Nhiều người bảo XML dài dòng và phức tạp, nhưng khi trực tiếp làm việc với nó thì đây là một định dạng tuyệt vời
Có thể validate bằng DTD và xuất ra thứ dễ đọc cho con người bằng XSLT
Với tôi, XML là dạng text format giống như C++. Trưởng thành, “kèm pin sẵn”, mạnh mẽ và kết nối được với mọi ngôn ngữ
Giống như các ngôn ngữ cũ đã trưởng thành, thật đáng tiếc khi chê bai XML như một thứ dành cho dị nhân lại trở thành trào lưu. Nếu không hợp use case thì đừng dùng, nhưng cũng không đáng để ghét quá mức
Nghe chuyện “XSLT chạy trực tiếp trong trình duyệt” thấy thật kỳ diệu. Lần cuối tôi dùng XSLT là 20 năm trước, khi mà mọi thứ bị nhấn chìm dưới đống Java enterprise cực kỳ phức tạp, làm mất hết thẩm mỹ riêng của XSLT.
Nhưng nếu XSLT mặc định chạy trong trình duyệt, có phải chén thánh của template tĩnh thật sự không cần framework host đã ở ngay trước mắt từ lâu rồi sao?
Trình duyệt chỉ hỗ trợ XSLT 1.0. Và thậm chí còn có người nói khả năng này có thể biến mất trong tương lai. Giá mà trình duyệt hỗ trợ đến 3.0 thì sẽ cực kỳ hữu dụng cho việc tạo web page tĩnh
Tôi cũng từng có trải nghiệm là không nhất thiết phải dùng “tháp Java enterprise khổng lồ” như vậy. Chúng tôi chỉ dùng tomcat và vài thư viện apache, mà chạy khá ổn. Từ CMS, HTML được dựng bằng XML, phần cá nhân hóa được nhúng dưới dạng thẻ XML, rồi nhờ proxy cache phía server nên việc chuyển đổi cũng nhanh và chịu được lưu lượng lớn. Điểm mấu chốt là stream đầu ra XSLT được đẩy ngay sang client, không buffer toàn bộ vào bộ nhớ.
Ngày nay với wasm thì gần như thứ gì cũng có thể chạy trong trình duyệt, nhưng JS thời kỳ đầu thật sự rất tệ, còn designer thì nhiều khi chỉ cần giao được file Photoshop PSD đã là may. Thời Google Maps và Gmail mới ra, người ta vật lộn làm UI nặng JavaScript và còn phải hỗ trợ cả Netscape lẫn Internet Explorer, đúng địa ngục thực sự
Cơn sốt XHTML bắt đầu nổi lên cũng chính vì “chén thánh template tĩnh” này. Nhưng điều lạ là những người thật sự hiểu thì lại nói năng như dùng tiếng lóng, không ai công khai nói thẳng ra
Tôi từng làm ở một site dùng XSLT trong trình duyệt vào năm 2008, và trước đó đầu những năm 2000 thì đã có hỗ trợ rồi
Chrome dùng
libxslt, Firefox dùng engine 1.0 tênTransformiix. Chrome chỉ hỗ trợexsl:node-set, còn Firefox hỗ trợ nhiều extension EXSLT khác nhau (không phải tất cả)Tôi cũng có công bố một công cụ nhỏ cho biết thông tin về XSLT processor đơn giản và danh sách extension khả dụng.
GitHub - xslt-detect-ext
Có thể kéo file
out/detect.xsltvào trình duyệt để xem thông tin (Chrome, Firefox). Safari thì bản Windows ngày xưa không làm đượcHồi còn là học sinh cấp ba những năm 90, thời mà người ta gọi là “web designer”, tôi từng dùng một pipeline phương ngữ DSSSL để tự động tạo site từ newsfeed. Đến giờ tôi vẫn thích các phép biến đổi XSLT. Tôi còn tự làm các tác vụ chuyển đổi văn bản và template thực tế bằng những công cụ như bananas XI reader
Nhưng số người thật sự thích kiểu tooling này rất ít, và cuối cùng khi có người khác thay tôi thì công nghệ được đưa vào thường biến mất rất nhanh
bananas XI reader
Để thấy cơn sốt XML và XSLT đầu những năm 2000 lớn đến mức nào: công ty tôi từng làm thậm chí còn tạo ASIC có thể parse XML ở tốc độ thời gian thực và xử lý cả XSLT ngay trên chip. Khi đó người ta tin rằng internet tương lai sẽ chạy hoàn toàn trên XML/XSLT.
Cuối cùng công ty này được Intel mua lại, và công nghệ đó đi vào nhóm tăng tốc SSE
Nếu một kiến trúc cho phép diễn giải XML, xử lý luôn XSLT trên ASIC mà trở thành chủ đạo, tôi hình dung web ngày nay chắc sẽ nhanh khủng khiếp
IBM đến giờ vẫn bán phần cứng có tính năng tương tự được tích hợp sẵn (DataPower Gateway)