Đã đến lúc đưa API template DOM vào sử dụng
(justinfagnani.com)- Nền tảng web đã trở thành môi trường chạy ứng dụng động, nhưng DOM tiêu chuẩn vẫn thiếu một API template khai báo có thể đồng thời xử lý dữ liệu, sự kiện, thuộc tính, phòng vệ XSS và cập nhật hiệu quả
- Các framework hiện đại như React, Vue, Angular, Lit, Svelte, SolidJS lấy hệ thống template kết hợp markup và dữ liệu làm cốt lõi, và điều này ảnh hưởng đến khả năng đọc, bảo mật, hiệu năng, phân tích tĩnh và server-side rendering
- Trước đây, E4X, E4H và thẻ template literal
htmltích hợp sẵn từng giúp tạo DOM nhưng không giải quyết được cập nhật DOM; giờ đây tagged template literals và kinh nghiệm từ các framework đã tạo nền tảng cho việc tiêu chuẩn hóa - API dựa trên JavaScript có phạm vi nhỏ hơn so với tiêu chuẩn hóa JSX hay template dựa trên HTML, đồng thời có thể trở thành mục tiêu biên dịch cho chuyển đổi JSX, rồi tiếp tục mở đường sang template HTML và custom element khai báo
- Lộ trình đề xuất gắn với các cơ chế nền như DOM Parts, template identity, Signals và DOM scheduler, đồng thời có thể cung cấp nền tảng chung cho lập trình viên vanilla, người dùng web components và người triển khai framework
Lớp template khai báo còn thiếu trong DOM tiêu chuẩn
- Nền tảng web là môi trường chạy ứng dụng thành công nhất trong lịch sử, và DOM API là nền tảng biến một trình xem tài liệu tĩnh thành môi trường chạy động, giàu khả năng biểu đạt
- Ngay cả các ứng dụng phức tạp như Photoshop cũng được cung cấp dưới dạng web app, và DOM là một API đủ mạnh để toàn bộ UI được xây bằng Web Components
- Tuy vậy, DOM API tiêu chuẩn hiện nay không có cách thuận tiện để xử lý cùng lúc các tác vụ sau
- Tạo các mảnh node DOM từ dữ liệu
- Thêm event listener
- Đặt thuộc tính cho element
- Đảm bảo an toàn trước tấn công XSS
- Cập nhật hiệu quả mảnh DOM đó bằng dữ liệu mới
Framework đã chứng minh giá trị của template
- Các web framework và thư viện render hiện đại dùng template kết hợp markup và dữ liệu một cách khai báo làm tính năng cốt lõi
- Bao gồm React, Vue, Angular, Preact, Lit, Svelte, SolidJS, Stencil, Quik, Ember, FAST, Polymer, Marko
- Template khai báo dễ viết và dễ đọc hơn DOM API kiểu mệnh lệnh
- Nội suy, event listener và thiết lập thuộc tính nằm gần template nên dễ giữ tính cục bộ của hành vi
- Hệ thống template có thể tự động escape giá trị nội suy nên có lợi cho phòng vệ XSS
- Một hệ thống template tốt có thể chỉ cập nhật phần DOM cần thay đổi, nên thường nhanh hơn phần lớn mã viết tay
- Nhiều hệ thống template hỗ trợ phân tích tĩnh như kiểm tra kiểu và tự động hoàn thành
- Định nghĩa template khai báo có thể được diễn giải ngay cả ngoài môi trường trình duyệt đầy đủ, giúp server-side rendering hiệu quả
Chi phí do thiếu template
- Nền tảng vẫn chưa trực tiếp đáp ứng một yêu cầu cốt lõi của gần như mọi ứng dụng web
- Giống như API quốc tế hóa, Temporal, Scheduler hay Sanitizer, template cũng xứng đáng là tính năng chuẩn của nền tảng
- Người dùng phải chịu ảnh hưởng từ thời gian tải app, overhead render và các ứng dụng có bảo mật yếu
- Mã thư viện template trong trường hợp tốt nhất có thể chỉ vài kB, còn tệ nhất có thể hơn 100kB
- Ngay cả vài kB cũng có thể chiếm tỷ trọng lớn trong ngân sách render tương tác ban đầu
- Lập trình viên phải phụ thuộc vào thư viện, npm và CDN ngay cả cho các tác vụ cơ bản
- Tính hữu ích của các file tĩnh đơn giản và DevTools bị giảm đi
- Không có kiến thức template cơ bản nào có thể mang theo giữa các stack
- Các API tạo DOM native như
innerHTMLvốn dĩ không an toàn theo mặc định
- Framework và thư viện template phải đánh đổi khó khăn giữa khả năng viết, tốc độ render, tốc độ cập nhật, bảo mật và kích thước mã
- Nền tảng web đang cạnh tranh với các nền tảng native như Flutter, SwiftUI và Jetpack Compose
- Các nền tảng này tích hợp sẵn hệ thống giống template, dùng cài đặt ứng dụng và ngôn ngữ biên dịch, nên ít nhạy cảm hơn với bundle chỉ vài kB
Vì sao giờ có thể thử lại
- Trước đây từng có các đề xuất nền tảng gần với template
- E4X từng thực sự được tích hợp trong Firefox và Flash
- E4H là ý tưởng được Ian Hixie đơn giản hóa
- Khoảng năm 2012 cũng từng có prototype cho thẻ template literal
htmltích hợp sẵn
- Các nỗ lực trước đây giúp tạo DOM nhưng khó trở thành lời giải đầy đủ vì không xử lý được cập nhật
- Hiện nay, các framework đã tạo ra đủ use case, và các lời giải template ở tầng userland cũng ngày càng giống nhau hơn theo thời gian
- Ngay cả trong cộng đồng lập trình viên không dùng framework và cộng đồng web components cũng có nhu cầu về thao tác DOM tiện lợi và API phản ứng
- Các đề xuất primitive cập nhật DOM cấp thấp như DOM Parts đang được thúc đẩy
- Một API template khai báo ở cấp cao hơn có thể giảm gánh nặng triển khai framework, đồng thời kiểm chứng và bổ sung cho các đề xuất API cấp thấp
Mẫu số chung về cú pháp và ngữ nghĩa
- Phần lớn hệ thống template phía client phổ biến đều chia sẻ cấu trúc kết hợp markup và binding
- Dấu phân tách biểu thức, luồng điều khiển và ký hiệu kiểu binding có khác nhau đôi chút, nhưng điểm chung còn lớn hơn
- Có sự tương đồng cả giữa Vue, Angular, Svelte dựa trên HTML và React, Lit, Solid dựa trên JavaScript
- Trong API dựa trên JavaScript, template thường là một biểu thức, việc ghép nối được thực hiện bằng cách lồng hoặc tham chiếu các biểu thức template, còn luồng điều khiển do JavaScript đảm nhiệm
- Nhiều hệ thống dựa trên API JavaScript trả về mô tả DOM từ biểu thức template rồi áp dụng nó bằng một lời gọi hàm
renderriêng- Đa số cũng cập nhật DOM bằng chính lời gọi
renderđó - Một số tránh cách này bằng cơ chế phản ứng hạt mịn
- Đa số cũng cập nhật DOM bằng chính lời gọi
- E4X và E4H, giống JSX, thêm cú pháp mới để đặt markup vào JavaScript, nhưng chúng trả về chính mảnh DOM thay vì mô tả DOM
- Điều đó tốt cho tạo DOM ban đầu, nhưng cập nhật vẫn phải làm theo kiểu mệnh lệnh
API có thể biểu đạt bằng JavaScript ngày nay
- JavaScript đã có tagged template literals cho các DSL nhúng như HTML
- Có thể biểu đạt template trong DOM API mà không cần thêm cú pháp JavaScript mới
- Các thư viện phổ biến cho thấy cách tiếp cận này hoạt động tốt
- Việc có thể thúc đẩy đề xuất mà không cần cú pháp mới là yếu tố quan trọng về tính khả thi trong tiêu chuẩn hóa
Quan hệ giữa JSX và API template native
- tagged template literals là một tính năng mạnh của ES2015, nhưng trong các hệ thống component userland, nó có overhead cú pháp lớn hơn JSX
- JSX rất phổ biến, nhưng chỉ có cú pháp mà không có ngữ nghĩa runtime
- Muốn tiêu chuẩn hóa thì không chỉ thêm cú pháp mới mà còn phải định nghĩa ngữ nghĩa
- Cách coi nó như lời gọi
createElement()được định nghĩa ở xung quanh sẽ bị loại trừ - Cách tạo cây object có thể trộn phần tĩnh và phần động, từ đó ngăn cản các mẫu cập nhật hiệu quả hơn
- Nếu đề xuất Records and Tuples đang tiến triển, JSX có thể từng trở thành cách tạo Records có box, nhưng đề xuất đó đã chững lại, đặc biệt ở phần record identity và box
- Muốn kiểm chứng xem cú pháp và ngữ nghĩa kiểu JSX có phù hợp với template DOM hoàn chỉnh hay không thì cần một hệ thống template đích
- Template của React không có cách bind tường minh tới thuộc tính và sự kiện của DOM element hoặc áp dụng directive lên element
- Vì JSX phi tiêu chuẩn hiện nay là cú pháp thuần túy không có ngữ nghĩa runtime, có thể tạo compiler chuyển JSX thành tagged template literal
- Đã có những ví dụ như JSX-to-Lit
- Một API template native có thể trở thành mục tiêu biên dịch cho cú pháp mà lập trình viên muốn dùng
Vì sao xem xét API JavaScript trước template dựa trên HTML
- Nhiều web developer muốn một hệ thống template dựa trên HTML với đầy đủ tính năng
- Có nhu cầu từ người dùng web components, người dùng framework và cộng đồng lập trình viên vanilla
- Cũng có những lập trình viên từng kỳ vọng
<template>, declarative shadow DOM và Web Components sẽ cung cấp chức năng như vậy
- Template dựa trên HTML là công việc lớn hơn rất nhiều so với API dựa trên JavaScript
- Cú pháp binding
- Ngôn ngữ biểu thức
- Cú pháp luồng điều khiển
- Cơ chế cập nhật template
- Cũng chưa có cách native để nạp định nghĩa template dựa trên HTML
- HTML Imports của Web Components v0 đã biến mất, còn HTML Modules thì vẫn chưa có
- Nếu phải đặt template HTML bên trong JavaScript module, thì dùng biểu thức JavaScript trong cùng lexical scope với dữ liệu sẽ hợp lý hơn
- Polymer 3 đã chuyển template HTML của Polymer 2 sang JavaScript, và điều đó dẫn trực tiếp tới Lit
- Để JavaScript làm phần việc giống script giúp ít mã hơn và trải nghiệm tốt hơn
- API JavaScript có thể là tập con và bàn đạp cho API dựa trên HTML
- Khi API JavaScript được đưa vào và kiểm chứng, API HTML sẽ còn lại bài toán định nghĩa binding, biểu thức, luồng điều khiển và hệ module
Các lựa chọn cho mô hình phản ứng
- Các đề xuất template DOM ban đầu không bao gồm cập nhật, nhưng các hệ thống userland đã khám phá kỹ mô hình phản ứng và cách triển khai
- Có thể gom ba hướng tiếp cận phản ứng tiêu biểu thành
- VDOM và diffing của React
- template identity của Lit
- Signals và phản ứng hạt mịn dùng trong Solid, Svelte, Vue, Angular và các hệ khác
- diffing dễ hiểu và hoạt động với mọi loại dữ liệu, nhưng chậm hơn các cách khác
- Sự khác biệt giữa các thuật toán diffing có thể quan sát được
- Khó để tiêu chuẩn hóa một thuật toán diffing duy nhất và khiến các kỹ sư nền tảng chấp nhận overhead đó
- template identity hoạt động bằng cách cập nhật nếu DOM hiện tại được render từ đúng template đó, nếu không thì thay thế
- Cách này nhanh và trong nhiều use case cho kết quả rất giống diffing
- Nó phù hợp với tagged template literals, chuyển đổi JSX và template dựa trên HTML
- Ngữ nghĩa đơn giản nên dễ đặc tả
- Signals là mô hình đáng để đưa vào API DOM phản ứng và API template mới
- Có đề xuất JavaScript Signals, nhưng đây vẫn chưa phải tính năng native của nền tảng và chưa chắc sẽ được chấp nhận
- Hệ thống dựa trên Signals hoạt động tốt nhất khi mọi dữ liệu đều được bọc trong signal
- Vì còn nhiều dữ liệu không phải signal và nhiều API nền tảng cũng không tạo signal, rerender là cách đơn giản để phản ánh những thay đổi đó
- template identity và Signals có thể cùng tồn tại
- Template chỉ nhận signal trong binding có thể được cập nhật chỉ bằng signal mà không cần rerender
- Template có thể tham chiếu dữ liệu không phải signal thì cần rerender
- Thông thường rerender sẽ được tầng component hoặc framework tự động thực hiện, chẳng hạn qua thuộc tính component phản ứng
Thảo luận tiêu chuẩn hóa và các việc còn lại
- Thảo luận về API template JavaScript khai báo native bắt đầu tại WICG webcomponents#1069
- API này có thể là bước tiếp theo hợp lý của API tạo DOM
- Trở thành primitive tạo DOM an toàn và dễ viết cho lập trình viên web vanilla
- Có ích ngay cho các thư viện web components hiện có như Lit, FAST và HyperElement
- Hữu ích cho người dùng API Web Components thuần và là bàn đạp tới API định nghĩa component phản ứng hoàn chỉnh hơn
- Framework mới có thể được xây trên API này
- Framework hiện có có thể dùng nó làm mục tiêu biên dịch, backend runtime hoặc đối tượng hỗ trợ trực tiếp
- Hữu ích cho cả kỹ thuật rerender lẫn Signals
- Là bàn đạp tiến tới template HTML khai báo và custom element khai báo
- Bề mặt API cần thống nhất và đặc tả tương đối nhỏ
- Giúp định nghĩa ngữ nghĩa template
- Công việc này gắn liền với việc hoàn thiện đề xuất DOM Parts
- Nó cũng góp phần định nghĩa DOM Parts và chứng minh tính hữu ích của nó
- Tuy API bề mặt và cú pháp không lớn, không gian hành vi và API DOM Parts bên dưới lại rất rộng
- Phản ứng hạt mịn cũng cần một dạng DOM scheduler nào đó
- Còn nhiều hạng mục cần quyết định, cần đồng thuận, cần đặc tả và cần kiểm thử nên đòi hỏi hợp tác
- Lập trình viên quan tâm có thể để lại bình luận tại webcomponents#1069 hoặc liên hệ qua Bluesky
1 bình luận
Các ý kiến trên Hacker News
Câu nói “chúng ta biết cú pháp tốt cho template là gì” nghe buồn cười đến mức phải bật cười. Tôi cho rằng hiện vẫn hoàn toàn chưa biết. Một template tốt gần như chắc chắn gần với công cụ trực quan hơn là cú pháp ký hiệu, đó cũng là lý do các công cụ kiểu Dreamweaver ngày trước thành công và các nhà thiết kế học bằng những công cụ như Photoshop
Ngoài ra, thật tiếc vì nó trông giống một nỗ lực tạo lại XSLT. Rốt cuộc chắc chắn sẽ có người muốn template hóa các mảnh không well-formed, rồi ghép lại thành thứ gì đó well-formed. Các thực thể liên kết với nhau trong trang nhưng không nằm trong cùng một cây cũng vậy.
labelvàfortrong markup thông thường là một ví dụ dễ hiểuNếu có thể, mong rằng sẽ bớt những nỗ lực ép mọi template phải khớp với cỗ máy Rube Goldberg mang tên bố cục tài liệu chuẩn của markup. Người ta đi những con đường phức tạp đến vô lý chỉ để tái tạo những việc vốn có thể làm khá tốt nếu dùng định vị tuyệt đối một cách thận trọng. Để khớp thì có thể cần tính toán, nhưng tôi không hiểu vì sao phải buộc máy cứ lặp lại phép tính đó trên cùng một dữ liệu
Thật tiếc là XML từng thịnh hành ở những chỗ không phù hợp như cấu hình, giao tiếp liên tiến trình, nhưng lại lụi tàn ở nơi nó có thể tỏa sáng với tư cách một ngôn ngữ markup có năng lực biến đổi tuyệt vời là XSLT
Tôi nghĩ điểm khiến XSLT sụp đổ là nó là một DSL thật sự, hơn nữa còn là DSL khai báo, thuần và hàm. Người ta thường tung hô DSL rất lớn trên lời nói, nhưng thực tế nhiều khi chỉ dừng ở trò chơi cú pháp đơn giản, không trừu tượng hóa nổi ngữ nghĩa thủ tục của ngôn ngữ chủ phổ biến. Khi gặp một DSL được thiết kế tốt, biến việc khó thành việc tầm thường, người ta lại không chịu học
Và tôi cũng thắc mắc vì sao lại nhắc đến định vị tuyệt đối. Tôi thấy kiểu lập luận này lặp lại trên HN, và tất nhiên định vị tuyệt đối có chỗ dùng, trong nhiều trường hợp còn là cần thiết
Nhưng nếu dùng cho bố cục trang hoặc ứng dụng, theo kinh nghiệm của tôi, phần lớn đó là cơn ác mộng chỉ cần nội dung hoặc kích thước màn hình thay đổi chút ít là vỡ. Ngay cả bố cục báo in cũng không làm như vậy vì còn vướng typography
Khi tôi còn làm nhiều với CSS, nếu tiếp quản một layout “gần xong” do ai đó dựng bằng định vị tuyệt đối, việc sửa mất cực kỳ nhiều thời gian, và làm lại bằng flex hoặc normal flow luôn nhanh hơn. Vì dùng định vị tuyệt đối làm công cụ bố cục chính khiến vấn đề gần như không thể sửa được
Có thể có những kỹ thuật hợp lý khi dùng
calc()và đơn vị viewport, nhưng theo kinh nghiệm của tôi, trừ khi nội dung và kích thước viewport hoàn toàn tĩnh, định vị tuyệt đối không phù hợp để làm layoutReact nhìn chung là framework lớn duy nhất vận hành theo kiểu các hàm JavaScript thông thường trả về biểu diễn trì hoãn của markup dưới dạng JSX. React không có khái niệm lặp hay render có điều kiện ở cấp template; những thứ đó được xử lý bằng JavaScript thông thường
Và giờ tôi cho rằng chúng ta đã biết cú pháp template tốt là gì. Về cơ bản là JSX. Tôi nói vậy dù bản thân không mấy thích React. Khó có thể phủ nhận rằng JSX đã lan khắp web, được biến thể để phù hợp với nhiều framework, và các hệ thống template JavaScript đã hội tụ vào các đặc tính chung: xem template như biểu thức, hợp thành bằng lồng nhau, và xử lý control flow bằng chính JavaScript thay vì bằng một cú pháp template riêng
Bài học cơ bản được rút ra lặp đi lặp lại là API/ABI không phải là trạng thái cuối cùng. Nhu cầu của ứng dụng không thể được đáp ứng vĩnh viễn bằng một API ổn định duy nhất, và cũng không thể đẩy mọi vấn đề trong tương lai thành vấn đề ở cấp ứng dụng
Đề xuất này cho thấy rất rõ quá trình các vấn đề chung của nền tảng được giải quyết ở tầng cao hơn như React, rồi cuối cùng khi được công nhận là vấn đề thì lại được đẩy xuống bên dưới. Polyfill cũng là một ví dụ như vậy
Khi những đề xuất kiểu này thành công, chúng được chú ý trong chốc lát, nhưng phần lớn vòng đời hữu ích của chúng lại trở thành những thứ cũ kỹ mà mọi người tìm cách né tránh. DOM API, các phiên bản ECMA, trình duyệt cũ, và mọi công nghệ hữu ích không thể động vào vì đã là một phần của hệ thống đều như vậy
Liệu có thể xem entropy, mở rộng và tương thích ngược là các trường hợp sử dụng chính để suy nghĩ không
Tôi muốn nền tảng web có mọi năng lực có thể có của nền tảng native. Tất nhiên vẫn phải tuân thủ các ràng buộc về quyền riêng tư và sandboxing. Và tôi cũng muốn trải nghiệm phát triển của lập trình viên web thật tuyệt vời
Nhưng điều đó phải được cân bằng với hệ quả của việc gia tăng độ phức tạp. Trong trường hợp này, tôi không chắc template native thật sự cải thiện trải nghiệm phát triển. Tôi không thấy lợi ích vượt quá chi phí
getElementByIdđã ổn định khoảng 25 năm rồi. Câu “không có thứ gì gọi là API ổn định” là lời của những người không có khả năng, hoặc không có ý chí, tạo ra các interface bền lâu. Đó không phải quy luật của vũ trụ, mà gần với sự buông xuôi cá nhân hơn. Phản ví dụ thì nhiều vô sốNhu cầu của ứng dụng cũng vô hạn như các nhu cầu khác. Những nhu cầu đó được đáp ứng bằng cách thêm API mới, chứ không phải bằng cách phá vỡ API đang hoạt động
Vì thế có những API đến giờ vẫn bị cuốn vào các sự cố như
smooshgatevì các quyết định từ 20 năm trước: https://developer.chrome.com/blog/smooshgateWeb thật sự cần template native, tính phản ứng và data binding. Không thể tưởng tượng nổi bao nhiêu CPU và băng thông bị lãng phí khi hàng tỷ người dùng tải xuống, parse và chạy những thứ như React
Phần Signals nói lên rất nhiều điều, và cho thấy rõ rằng ý tưởng thì tuyệt vời nhưng trên thực tế lại khó
Có thể hiểu vì sao tác giả thích Signals. Mỗi dự án đủ lớn đều có một cây tính toán DAG làm dở, và việc ngôn ngữ chuẩn hóa một cái như vậy là hợp lý
Nhưng những abstraction kiểu này có chi phí nhận thức và chi phí triển khai lớn
Như phần lớn kỹ thuật, vấn đề là sự đánh đổi. Mô hình React cập nhật trạng thái toàn cục rồi render lại tất cả nên chậm, nhưng dễ hiểu. Mô hình Signals thì nhanh nhưng đòi hỏi quá nhiều công sức
Hầu hết ứng dụng không cần nhanh điên cuồng, và mọi người sẽ chọn React đơn giản hơn
Nhưng Signals đâu có liên quan nhiều đến template, đúng không. Vậy tại sao phải chọn nó. Chẳng phải có thể có template và Signals tách biệt sao
Khi nghĩ về template, ta sẽ cần cách nói cho DOM biết nên chèn node template vào đâu, và cập nhật nó thế nào khi có thay đổi. Chính ở điểm này các đề xuất như vậy thất bại
API ở đây phải chọn một phía. Về mặt kỹ thuật có thể cho phép cả hai, nhưng sẽ rất kinh khủng. Các lập trình viên sẽ không bao giờ thống nhất được nên là phía nào
Vấn đề lớn của UI luôn không phải là định nghĩa nó thế nào, mà là cập nhật nó thế nào. Microsoft đã cố định nghĩa nhiều mô hình như MVC, MVP, MVVM và thất bại, tất cả đều đau đớn. Rồi imgui nói “nếu UI hoàn toàn không có trạng thái thì sao?”, cách đó khá tốt nhưng gây tải cho CPU
Có lẽ một trong những lý do lớn nhất khiến web app thành công là DOM không ép buộc cách ràng buộc dữ liệu vào view. Vì vậy có lẽ chúng ta khó thoát khỏi địa ngục framework
Cá nhân tôi thích ivi-js: https://github.com/localvoid/ivi
Nó chỉ chậm hơn 8% so với thứ JavaScript vanilla nhanh nhất, xấu xí nhất, imperative nhất và không thể bảo trì nhất mà cuối cùng bạn có thể đạt tới nếu chỉ nghĩ đến việc thắng benchmark
https://krausest.github.io/js-framework-benchmark/2025/table...
Thay vì nói rằng hầu hết ứng dụng không cần nhanh điên cuồng, tôi mong người ta thừa nhận hơn rằng ứng dụng nên nhẹ
Tôi đồng ý rằng mọi người chọn React vì nó đơn giản hơn, nhưng chính vì lý do đó mà tôi không thích React
Thay vì chọn JSX, tôi mong nó gần hơn với cách Kotlin cung cấp cú pháp được tổng quát hóa cho DSL bằng receiver và builder, và cú pháp đó cũng rất phù hợp để biểu diễn phân cấp component
Nó sẽ hữu ích rộng rãi không chỉ cho template HTML mà còn để biểu diễn cấu hình và nhiều loại cấu trúc khác
Ngữ nghĩa thực tế của template và data binding chỉ cần là một tập hàm chuẩn dùng các tính năng cú pháp như vậy, như ta thấy trong Jetpack Compose
Điều quan trọng nữa là bài này được viết bởi một trong những người có nhiều kinh nghiệm nhất trong lĩnh vực này. Đây là tác giả chính của Lit / Polymer, người làm về Web Components tại Google và đã đóng góp vào các đặc tả DOM cốt lõi đã trở thành một phần của nền tảng web
Safari đã lập luận từ 15 năm trước rằng ở đây cần có một cách khai báo
Tôi tự hỏi có ai khác cảm thấy template khai báo thực ra còn tệ hơn jQuery không. Tôi đã dùng React gần 10 năm, nhưng SPA càng phức tạp thì tôi càng muốn điều khiển DOM trực tiếp theo kiểu imperative
Lý do là DOM là một abstraction bị rò rỉ, và ở một mức nào đó tôi cảm thấy cách “lần ghi cuối thắng” tốt hơn
Tôi biết template khai báo cố xử lý chuyện đó, nhưng một khi bắt đầu chia sẻ trạng thái có thể thay đổi giữa các component thì cách này sụp đổ rất nhanh
ref, và nếu dám nói thì thậm chí tìm component bằngidrồi xử lý trực tiếp cũng không sao. Thực tế các thư viện “nhanh” và ít re-render, ví dụ như thư viện form, đều làm vậyinnerHTMLvàrefThứ hai, tôi không rõ có việc gì điều khiển DOM theo imperative làm được ít phiền phức hơn declarative. Tôi chỉ nghĩ tới vài method cụ thể như
attachShadow(),showModal(), nhưng ngay cả chúng cũng có thể được bọc bằng một component 10 dòng để thành declarativeTheo tôi biết, Ryan Carniato và Solid JS vẫn đang khám phá những gì có thể làm với Signals. Tôi không nghĩ quá trình khám phá ở userland trong lĩnh vực này đã hoàn toàn kết thúc, và có thể vẫn còn đổi mới bổ sung
Tôi thích hướng đi này, nhưng trước đó tôi nghĩ một vài API cấp thấp hơn nên được đưa vào trình duyệt trước
Gần như không thể để tất cả mọi người đồng thuận về một hệ thống template chuẩn. Thay vào đó, việc trình duyệt có thể làm là cung cấp API cấp thấp để áp dụng diff lên DOM theo cách native và hiệu năng cao
Sẽ rất tuyệt nếu trình duyệt có sẵn thứ này ở dạng native
element.applyDiff(DocumentFragment | string, { method: 'innerHTML' | 'outerHTML' })Cách này có thể áp dụng diff theo hướng ít gây gián đoạn, chẳng hạn giữ focus của element, giá trị input, trạng thái trình phát audio/video và thay đổi thuộc tính. Các thư viện JavaScript như Idiomorph làm việc này, nhưng giải pháp native có khả năng nhanh hơn nhiều
Nó cũng sẽ hữu ích cho các dự án không dùng framework, và đặc biệt hữu ích nếu đề xuất Signals cũng được chấp nhận
Đề xuất Records and Tuples không chỉ bị đình trệ mà đã bị rút lại. https://github.com/tc39/proposal-record-tuple/issues/394
Vị trí đó đã được thay thế bởi https://github.com/tc39/proposal-composites