0.6
License change to MPL
Mandatory disclaimer: I am not a lawyer and this is not legal advice.
After some discussion this release has switched from LGPL-3.0 to the Mozilla Public License version 2.0. LGPL is the GNU License intended for libraries that's not as restrictive as the actual GPL, however its wording makes it problematic to use when a library is statically linked as commonly happens in Rust.
In practice the switch to MPL-2.0 means that you can freely use Kobold in projects that themselves use different licenses, including closed-source proprietary projects, as long as any changes to Kobold itself are made open-source under MPL-2.0.
Keywords
The big breaking1 change in this release is the introduction of keywords for { expressions }
in the view!
macro. The keyword is always the first token inside the curly braces, currently 4 of them are defined:
for
makes an iterator into aView
. Replaces theListIteratorExt::list
method.ref
turns on diffing by reference (rather than value) for strings. Replaces theStrExt::fast_diff
method.static
disables diffing and prevents updates to the DOM after initial render of the value. Replaces theStringify::no_diff
method.use
disables diffing and eagerly sets the value in the DOM on every render. This is a new functionality mostly intended to work with thefence
function.
All keywords are defined as raw-identifier functions in the new kobold::keywords
module (e.g.: the static
keyword maps to kobold::keywords::r#static
) for discoverability. In addition to the documentation in the module itself, they are properly spanned and interact nicely with rust-analyzer:
The fence
function
This release adds the kobold::diff::fence
function that guards some inner View
-producing closure against renders unless its guard
value has changed. Signature:
pub const fn fence<D, V, F>(guard: D, render: F) -> Fence<D, F>
where
D: Diff,
V: View,
F: FnOnce() -> V;
Example:
Fencing a view can be a great optimization, especially when combined with the previously mentioned use
keyword:
use kobold::prelude::*;
use kobold::diff::fence;
struct User {
id: usize,
name: String,
email: String,
}
#[component]
fn UserRow(user: &User) -> impl View + '_ {
fence(user.id, || view! {
// This row is only re-rendered if `user.id` has changed
<tr>
<td>{ user.id }</td>
// Assuming that `name` and `email` are always different
// for different users, we can disable diffing here.
<td>{ use &user.name }</td>
<td>{ use &user.email }</td>
</tr>
})
}
Note: while the use
keyword is always safe (it won't cause UI bugs), the performance trade-off only makes sense when used with another mechanism that prevents superfluous renders, such as fence
here.
Internals
There has been a substantial refactoring done to the internals of Kobold, few things have moved around and the way attributes are rendered and how elements are mounted has changed. These are mostly implementation details.
In practice everything is more type-safe and extendable while reducing the size of the produced Wasm file even further. The gzipped Wasm file of the TodoMVC example is now down to 17.16kb (was 18.08kb).
Footnotes
-
The old methods added by extension traits are still supported with deprecation warnings and will be removed in the 0.7 release. ↩