DRAFT: Roadmap to DNA 4 #94
edoardocavazza
started this conversation in
General
Replies: 1 comment 1 reply
-
Not sure where this goes, but on the website on the migrations page, under the V3 -> v4 Section;
Does this mean DNA will drop JSX/TSX in future? |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
DNA is a library created to develop Web Components without relying to the very heavy and very slow polyfills for the Shadow DOM. Now that the Shadow DOM is supported by the vast majority of browsers, it is time for DNA to design new foundations for version 4.
New goals
Maximise compatibility with other frameworks
Most modern JavaScript frameworks deal not only with client-side rendering of applications, but also with bundle and server optimisation. This requires that the third-party component (so not a component created ad hoc for the app, but designed as a library) interfaces with very different technologies that are not quite as "predictable" as when the browser was the only execution environment.
To achieve this goal, it becomes almost inevitable that DNA uses the Shadow DOM to render the component template (so as not to interfere with the framework's render mechanism) and forgoes component lifecycle management altogether.
Lazy definitions
To take full advantage of the efficiency of code splitting to maximise page loading times, it should be possible to define the component in a lazy manner. In this way, the component code is loaded only when required by the page through the use of the tag. This is a particularly useful mode in the case of Multiple Page Applications or Web sites for which it is very difficult to create ad hoc bundles for each page.
Some of these goals will be achieved in the current version (the 3.x) as a migration path, for others we will have to decide whether to accept minor breaking changes or to defer directly to the new version.
Embrace the shadows 🚧
DNA components currently have a single rendering mode that uses only the light DOM (i.e., elements that belong to the main page tree). Having always discouraged the use of
querySelector
or direct interactions with the DOM in favour of properties, states and references, moving the template inside a ShadowRoot should not be a problem from a logical point of view. It certainly is, however, from a styling point of view, so we will need to start using the::part
and::slotted
selectors instead of class selectors.☐ Task: Render in the Shadow DOM (v3.x)
renderMode
to the component class, valued by default as'light'
in v3 and as'shadow'
in v4static renderMode = 'shadow'
, DNA will automatically create a ShadowRoot which it will use as the root of the template render. Also, in this mode, DNA must stop handling the creation of<slot>
elements and doing CSS scoping☐ Task: Shadow Parts migration (v3.x)
renderMode
s a migration utils fromlight
toshadow
and vice versa:sunset
: when rendering a template in the Shadow DOM, copy node class list values topart
attributesunrise
: when rendering a template in the Light DOM, addpart
attribute value to the node class list☐ Task: Slotted children mapping (v3.x)
<slot>
. This is useful to wrap and redistribute slotted nodes in the component template☐ Task: Slotted children attributes (v3.x)
Browser support
Chrome 73 (March 12, 2019)
Edge 79 (January 15, 2020)
Safari 13.1 (July 15, 2020)
iOS 13.4 (March 24, 2020)
Firefox 72 (January 2, 2020)
Opera 60 (April 9, 2019)
Samsung 11.1 (February 25, 2020)
Total
Global 94.06%
Italy 94.89%
Can I use?
Lazy loading and definition
Lazy loading of a component has an implementation similar to the Hot Module Replacement runtime. This implementation is made possible by the use of the
Proxy
object, which we cannot be polyfilled but it is available for the new browser support range.Here is, in broad strokes, how it would work:
Proxy
that acts as the constructor of a component.customElements.define
using the proxied constructor.connectedCallback
of the element, the library executes asynchronous code to import the actual definition and updates the proxyFrom the application point of view, instead of importing the component with a static import, we could use lazy loading as follow:
☐ Task: Integrate HMR logic in the project (v4)
☐ Task: Introduce the
lazyDefine
helper (v4)Custom renderers
Since the focus of DNA can finally shift entirely to component definition and construction, we are no longer tied to an internal render system. Out of backward compatibility, or even just out of habit and utility, the DNA render will still be present in v4, but we could open up the possibility of using other render engines such as
lit
orpreact
.☐ Task: Introduce a
static render
property (v4)The static
render
property is the function invoked to render component's template into its Shadow Root. It accepts the template as first argument, the Shadow Root instance as second and the element itself as third.Example:
Native lifecycle
Deprecating browsers that do not natively support Custom Elements and giving up completely on handling slotted children frees us from exposing an API (the
DOM
namespace of DNA) for DOM manipulation resulting in improvements in maintainability, interoperability, and performance.Since Safari does not yet handle the extension of builtin elements, however, we need to introduce a polyfill for the specific case to enable the lifecycle for these elements as well.
☐ Task: Remove
DOM
namespace (v4)☐ Task: Include polyfill for Custom Elements that extend builtin elements (v4)
/~https://github.com/ungap/custom-elements-builtinReactivity and rendering only for connected nodes
Many Web Components libraries do not allow the component to render if it is not "connected" (i.e., if it is not part of the DOM tree of the page), whereas DNA keeps the template updated with each property change. Aligning with other frameworks would greatly improve performance, and we have no evidence that has emerged over the years that would advise us to maintain the current behaviour.
☐ Task: Add checks for connected nodes before rendering (v4)
Modernise DOM APIs
By removing support for IE 11 (0.48%) and Edge <= 17 (0.06%), some DNA internals can be updated to reduce library size, improve maintainability, and reduce automated testing time.
☐ Task: Remove internal
isConnected
helper (v3.x or v4?)☐ Task: Use
CustomEvent
constructor for event initialisation (v4)document.createEvent
usageDOM.createEvent
method☐ Task: Remove internal
Element.prototype.matches
helper (v4)☐ Task: Remove internal
cloneChildNodes
helper using rest array (v4)☐ Task: Remove internal
customElements
registry in favour of native API (v4)Other changes
☐ Task: Repository structure (v4)
In order to improve the maintainability of the project, we should move to a monorepo structure consisting of the library, the analyzer for the Custom Element Manifest, and the runtime for the Hot Module Replacement (to be created).
Beta Was this translation helpful? Give feedback.
All reactions