Ionic’s Stencil Component Compiler Design Considerations — Adam Bradley at DotJS2019
Adam Bradley, creator of StencilJS and co-creator of Ionic Framework, reviewed at dotjs2019 the design and architecture that went into Stencil, a component compiler which generates framework-agnostic components.
Bradley first explained the rationale behind a component compiler. Within the same organization, a technology team could use Angular for a purchasing application, while the internal support team may use Vue for an expense report application, and yet another team may create a marketing PWA with React. While this may be locally satisfying, at the organization level, the duplication of efforts resulting from implementing the same components in different frameworks is a source of loss of efficiency. Even those companies using a design system benefit from the reusability of components only within the framework the design system was implemented for.
While this occurs less in small companies, large organizations with many teams face such costs and challenges deriving from the multiplicity of frameworks. The alternative of imposing a single framework to the whole organization is not only often not a possibility, but also poses itself another set of problems.
Ionic, as a mobile-focused UI library for the web featuring hundreds of components, faced similar challenges. Ionic first adopted AngularJS component model when it started in 2013. As other frameworks appeared, including an entirely new Angular, the developer community was consistently asking the Ionic team for flavors of Ionic catering to specific frameworks. However, adopting a given component model for Ionic meant that any bug fix or design improvement would only be available for the component model’s framework, thus forcing to duplicate work across frameworks. The situation would likely repeat itself in the future with the new frameworks unavoidably poised to appear.
Ionic then decided on a common component model, the web component standard that reuses existing, standard browser APIs, APIs which are not poised to change at any point in the future. Ionic also crafted a component compiler called Stencil which operates purely at build time, is complementary to existing frameworks, and can compile a component description to several framework component models. Bradley emphasized:
Stencil is a built-time tool. It is not a framework. The problem Stencil is solving for Ionic is allowing our components to work in many of today’s frameworks and hopefully tomorrow’s too. It is a tool that helps us generate and maintain reusable components.
Bradley then went more in detail about the design goals and technological choices made for the compiler. Stencil uses TypeScript custom transformers to statically analyze Stencil component source code, and generate the compiled code according to the chosen target component model.
The compiler applies many optimizations in order to generate lean, optimized and performant source code. Bradley gave one example of minification optimization in which functions are converted to arrow functions when possible, removing the
return keywords. The output code is then reduced to a constant being assigned to an arrow function, which significantly reduces the size of the code.
With such aggressive optimizations, the generated code for a
<hello-world /> component is only 87 bytes. The TodoMVC application, which is commonly used for benchmarking front-end frameworks, amounts to 2.2KB. For additional technical details on optimizations performed by the compiler (including native module preloading), readers can consult the video of the talk.
The Stencil compiler can output, from the same source, any of the following and more: lazy-loading components, legacy ES5 and SystemJS components for IE11 support, bundled custom elements library, framework bindings, NodeJS hydrating script supporting server-side rendering and pre-rendering. As a primary example, Ionic provides genuine Angular components to Angular developers, and genuine React component for React developers, from the same source code.