Перейти к основному содержимому

Ломаем обратную совместимость дальше (версия 0.4.0)

· 4 мин. чтения
Lyoha Plotinka

Прошло совсем немного времени после релиза 0.3.0, и вот снова минорный релиз - 0.4.0. Да, обратная совместимость снова сломана, но причина для этого, на мой взгляд, хорошая.

Я существенно переработал то, как в коде Rattus ORM используются атрибуты. Те самые, которые types и relations. Если в прошлом релизе все изменения были связаны с названием декораторов и методов, то в этом я сделал упор на то, что для frontend-разработчиков важно, пожалуй, больше всего - размер бандла.

Что было сделано

Я заметил, что даже если вы просто создадите базу данных и добавить всего одну модель, в которой не будет ни одного ключа, в ваш бандл заедут некоторые типы и даже relations. Это наследие Vuex ORM Next.

Так получилось потому, что для проведения некоторых операций с полями модели нам нужно знать, что именно перед нами: type, relation, а иногда даже конкретный type или relation. В Vuex ORM Next это делалось с помощью проверок instanceof, а для этого, как известно, нужно иметь код конкретного класса. В версии 0.4.0 @rattus-orm/core это исправлено.

Однако это ещё не всё. Если вы не используете декораторы для описания моделей, вы знаете, что каждый type или relation - статический метод класса Model:

Код версии 0.3.0
export class User extends Model {
static entity = 'user'

static fields () {
return {
id: this.uidField(),
name: this.stringField(''),
age: this.numberField(0)
}
}
}

А это значит, что самый базовый класс всегда тянет в себе все types и relations!

В версии 0.4.0 это также переработано. Теперь для описания поля нужно вызывать не статический метод, а отдельную функцию:

Код версии 0.4.0
export class User extends Model {
static entity = 'user'

static fields () {
return {
id: createUidField(this),
name: createStringField(this, ''),
age: createNumberField(this, 0)
}
}
}

Минус здесь незначительный: нам нужно передавать в функцию контекст конструктора класса. Во всех методах это всегда первый аргумент, остальные идут в том же порядке, что и раньше.

То же касается и relations - это отдельные функции, первый аргумент которых - контекст конструктора.

Всё это приводит к тому, что мы тянем в бандл только то, что реально используется вашим приложением.

Результаты

Взглянем на результаты. Для сборки файла в этом эксперименте я использую Bun v1.1.30.

Модель без полей

Сперва посмотрим, что мы имеем вот с таким исходным файлом:

size-test.ts
import { Model } from '@rattus-orm/core'

class User extends Model {}

Давайте соберём его, используя версию 0.3.0:

v0.3.0
$ bun build size-test.ts --minify --outfile size-test-built.js > /dev/null  \
$ && npx tiny-file-size --gzip --brotli ./size-test-built.js

size-test-built.js 19.87 KB │ gzip: 5.17 KB │ brotli: 4.61 KB

Мы видим, что размер файла получился 19.87 KB без сжатия и минимальное 4.61 KB сжатый brotli.

Что же получается с версией 0.4.0:

v0.4.0
$ bun build size-test.ts --minify --outfile size-test-built.js > /dev/null  \
$ && npx tiny-file-size --gzip --brotli ./size-test-built.js

size-test-built.js 12.34 KB │ gzip: 3.77 KB │ brotli: 3.37 KB

Файл уменьшился на 37.8% в несжатом и примерно на 27% в сжатом виде. Выглядит неплохо!

Модель с единственным StringField

Теперь давайте добавим нашей модели свойство name - это будет строка.

size-test.ts
import { Model } from '@rattus-orm/core'

// v0.3.0
import { StringField } from '@rattus-orm/core/decorators'
// v0.4.0
import { StringField } from '@rattus-orm/core/field-types'

class User extends Model {
@StringField('')
public name: string
}

Соберем с 0.3.0:

v0.3.0
$ bun build size-test.ts --minify --outfile size-test-built.js > /dev/null  \
$ && npx tiny-file-size --gzip --brotli ./size-test-built.js

size-test-built.js 20.38 KB │ gzip: 5.41 KB │ brotli: 4.82 KB

И с 0.4.0:

v0.4.0
$ bun build size-test.ts --minify --outfile size-test-built.js > /dev/null  \
$ && npx tiny-file-size --gzip --brotli ./size-test-built.js

size-test-built.js 13.51 KB │ gzip: 4.21 KB │ brotli: 3.77 KB

Файл меньше примерно на 33% в несжатом и на 22% в сжатом виде.

В итоге, грубо говоря, мы видим уменьшение бандла приблизительно на треть. Естественно, если вы используете все типы данных и все связи, вы получите бандл того же размера, что получится в версии 0.3.0. Однако цель этого релиза - позаботится о тех, кто использует не всё, а только определенные части Rattus ORM.