Efficiency and performance
As more complex web applications have appeared in recent years, browsers have answered with DOM performance optimizations that favor more dynamic content. However, in order to render their user interfaces, web applications still need to interact with an imperative API that has remained mostly unchanged for decades. Modern web applications designed around reactive data propagation need a more efficient way of translating their user interfaces into a webpage’s DOM.
Dojo abstracts the DOM away from applications and promotes the use of reactive state flows to minimize application boilerplate while also allowing for increased rendering performance. Widgets output virtual nodes from their render functions which represent the widgets’ structural representation within a virtualized DOM. The framework then handles the process of changes to the VDOM across renders in the most efficient way possible, only affecting concrete DOM elements that actually require changing.
Dojo provides another DOM abstraction layer through its middleware system for applications that need concrete information from the DOM to implement their requirements. Dojo middleware solves a variety of these concerns in a consistent manner while still supporting reactive data flows across an application.
Application delivery - layering and bundling
Fetching an application resource incurs additional overhead around HTTP resource negotiation. Data needs to be requested by the client, after which the client has to wait before the server finishes sending the last byte of the resource. In more severe cases, the overhead can also include DNS resolution, full TCP connection re-establishment and TLS cipher/certificate negotiation.
Browsers are efficient in minimizing this overhead, but they cannot eliminate it entirely - a web application still has its own part in the responsibility of minimizing resource transfer overhead. The overhead associated with fetching application resources is relatively static when compared to the size of a given resource. Fetching a 1 KB file incurs similar overhead to fetching a 100 KB file.
Overhead can therefore be minimized in two ways: by decreasing the total number of resources, and by increasing the size of a single resource. Web applications can achieve both by layering and bundling related resources.
When using Dojo’s routing system, applications can benefit from automatic layering and bundling. An application’s top-level routes each become a separate layer, and Dojo’s build system will automatically generate bundles for each subsection. This gives layer separation and resource bundling without needing any additional tool chain configuration. There is a tradeoff with this automation in that common dependencies shared across multiple layers are inlined and duplicated within each bundle.
Declarative layering
Complex applications may require more fine-grained control over their layer/bundle definitions. For example, if an application has a set of shared dependencies that are used across multiple routes - rather than inlining/duplicating the dependencies within each route’s bundle, it may be desirable to extract the shared dependencies to their own bundle which can be lazily-loaded on first reference.
Dojo’s build pipeline allows for designating resource bundles within an application’s build configuration file, and can automatically convert module dependencies that cross bundle boundaries into lazily-loaded references.