Обновить
354.93

Веб-разработка *

Делаем веб лучше

Сначала показывать
Порог рейтинга

Как я использую ИИ в разработке

Последний год я активно использую ИИ в разработке (особенно рутинных задачах): сначала ChatGPT 4o стал достаточно умным и подсказывал куски кода. Потом я освоил GitHub Copilot в VS Code (Go и TypeScript) и Inteliji IDEA (Java). А последние полгода пишу в основном в Cursor IDE.

Cursor IDE мне очень сильно понравился своим автокомплитом. Он не просто подставляет автодополнение, а умеет переписывать большие куски кода в разных частях файла.

Последние несколько месяцев я начал чаще использовать агентский режим: это когда говоришь IDE что делать, а она бегает по разным файлам и меняет их.

И тут мой мозг начал взрываться! Агентский режим Cursor'a и интеллект ChatGPT o3-mini-high творят чудеса. В типовых задачах — это жуткая экономия времени.

(Пока писал пост, Open AI выпустили полноценную o3 и o4-mini-high 🤯).

Как я понял, Cursor + Claude 3.7 действуют по следующему алгоритму:

  1. Проходит по исходникам, собирает контекст и паттерны.

  2. Залезает в исходники библиотек и смотрит их код.

  3. Если сильно нужно — бегает в интернет и обкашливает вопросики там.

  4. Вносит изменения в код.

  5. Смотрит ошибки линтеров и компиляции (!!!).

  6. Ещё раз исправляет код и, если нужно, снова бегает по исходникам и библиотекам.

  7. Говорит, что сделал и подсвечивает измененные куски кода.

На видео выше записал, как решаю задачу таким способом.

Задача: есть код, который принимает события от Telegram. В него нужно добавить поддержку новых событий и обновить DTO.

Cursor смотрит в интерфейс, что нужно добавить. Затем смотрит в библиотеку, какие там модельки. Обновляет код. Сам фиксит ошибки, если есть. Так ещё и говорит: "DTO и так нормальные, их трогать не буду". Красота!

К сожалению, как" вайб кодить" — я пока не понял. Потому что:

  • весь код нужно сильно перепроверять;

  • на задачах с весомой бизнес логикой получается фигня;

  • пограничные кейсы не обрабатываются;

  • тесты для чего-то больше CRUDов получаются с тоннами шаблонного кода, мало переиспользования;

  • если файлов сильно много и задача в духе "пройдись по паре сотням файлов и поменяй что-то", Cursor начинает галлюцинировать и выдавать фигню.

Итого: сейчас ИИ мне сильно экономит время на шаблонных и рутинных задачах. Особенно, если задача не выходит за рамки 2-3 файлов и в проекте всё ок с тестами.

Условно, я делаю на 10%-20% меньше рутинной работы, которая раньше могла отнимать 2-3 часа в день.

Что-то комплексное или "написать проект с ИИ, не смотря код" — пока не получается (как минимум, пока что).

Но, в любом случае, уметь использовать ИИ потихоньку становится must have навыком для среднестатистических разработчиков. Разумеется, если используется не редкий язык, не специфическая сфера (типа написание ОС, где недостаточно обучающих данных) или не что-то критичное (медицина, ядерка и т.д.).

---

Если вам понравился пост или оказался полезным, поставьте, пожалуйста лайк ❤️. Это мотивирует делиться опытом из разработки. И, как полагается, у меня есть Telegram-канал, в котором я рассказываю про разработку, развитие SaaS-сервисов и управление IT проектами.

Теги:
Всего голосов 11: ↑9 и ↓2+8
Комментарии1

Автоматическое подключение локализации для веб-ассета в Joomla

Начиная с Joomla 4 в ядре реализована концепция веб-ассетов. Управление JavaScript и CSS в Joomla значительно упростилось благодаря классу WebAssetManager. Есть замечательная статья Как правильно подключать JavaScript и CSS в Joomla 4, в которой подробно и с примерами кода рассказывается об этой концепции и её применении. Например, в web asset мы можем оформить какую-нибудь готовую js-карусель или библиотеку.

Также можно оформить веб-ассетом и свой собственный js-скрипт, которому могут понадобиться дополнительные данные для работы на странице: как данные из PHP, так и языковые константы. С помощью WebAssetManager мы можем получить эти данные в момент сразу при подключении ассета. Как это сделать?

Для веб ассетов в Joomla создаётся файл joomla.asset.json, в котором описываются url подключаемых файлов, версии, их зависимости друг от друга, собираются пресеты для подключения пачкой и т.д. В нём можно указать пользовательский класс WebAssetItem, который будет выполнять нужную работу для вашего ассета. Для этого определите свойства namespace и class для всего файла или же для каждого ассета.

{
  "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
  "name": "com_example",
  "version": "4.0.0",
  "namespace": "Joomla\Component\Example\Administrator\WebAsset",
  "assets": [
    {
      "name": "foo",
      "type": "script",
      "class": "FooAssetItem",
      "uri": "com_example/foo.js"
    },
    {
      "name": "bar",
      "type": "script",
      "namespace": "MyFooBar\Library\Example\WebAsset",
      "class": "BarAssetItem",
      "uri": "com_example/bar.js"
    }
  ]
}

Ассет foo будет работать с классом Joomla\Component\Example\Administrator\WebAsset\FooAssetItem, а ассет bar с классом MyFooBar\Library\Example\WebAsset\BarAssetItem. Если namespace не указан, будет использоваться Joomla\CMS\WebAsset по умолчанию. Ну и сам класс должен находиться по указанному неймспейсу.

<?php
/**
 * Класс WebAssetItem для подключения данных для работы веб ассета
 */

namespace Joomla\Component\Example\Administrator\WebAsset\AssetItem;

\defined('_JEXEC') or die;

use Joomla\CMS\Document\Document;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\WebAsset\WebAssetAttachBehaviorInterface;
use Joomla\CMS\WebAsset\WebAssetItem;

class FooAssetItem extends WebAssetItem implements WebAssetAttachBehaviorInterface
{
    /**
     * Method called when asset attached to the Document.
     *
     * @param   Document  $doc  Active document
     *
     * @throws \Exception
     *
     * @since   1.0.0
     */
    public function onAttachCallback(Document $doc)
    {
        Factory::getApplication()->getLanguage()->load('com_example');

        // Add my-js-script.js language strings
        Text::script('COM_EXAMPLE_LANGUAGE_STRING_FOR_FRONTEND');

        /** @var array $data Данные для фронтенда, чтобы получать их
         *  в js через Joomla.getOptions('com_example.foo.js.data';)
         */
        $data = [
            'any' => 'data',
        ];
        /** @var bool $merge Whether merge with existing (true) or replace (false) */
        $merge = true;
        $doc->addScriptOptions('com_example.foo.js.data', $data, $merge);
    }
}

Таким образом для нашего js-скрипта мы получили и локализованные стринги сообщений (как? - пост на Хабре) и дополнительные данные из PHP для фронтенда (статья на Хабре - в середине). Теперь когда вы где-то в любом месте Joomla подключаете веб ассет с помощью $wa->useScript('foo') - автоматически подключится всё необходимое для его работы.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

🗓 4.04 - World Webmasters Dаy [вехи_истории]

🗓 4.04 - World Webmasters Dаy [вехи_истории]
🗓 4.04 - World Webmasters Dаy [вехи_истории]

4 апреля отмечается День веб-мастера (World Webmasters Day) – праздник всех, кто разрабатывает, поддерживает и совершенствует сайты. Веб-мастера — это программисты, дизайнеры, SEO-специалисты, администраторы и многие другие профессионалы.

Выбор даты не случаен: 4.04 ассоциируется с известной ошибкой 404 «Страница не найдена». Это своеобразный символ работы веб-мастеров, ведь их задача — следить, чтобы сайты всегда работали гладко и без сбоев, но не всегда получается)

С момента появления первых веб-страниц интернет сильно изменился. Если раньше веб-разработчик отвечал за всё — от написания кода до оформления, то сегодня сфера веб-разработки включает UX/UI-дизайн, поисковую оптимизацию, маркетинг и кибербезопасность.

🩵 Поздравляю всех веб-разработчиков. Пусть ваши сайты падают реже)

YouTube | RuTube | Telegram | Pikabu

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Совет по Joomla: dot-нотация для доступа к значениям вложенных массивов.

Позволю себе немного ребячества ))

Наткнулся на пост в одном из php-шных каналов о том, как в Laravel можно использовать нотацию "точка" для доступа к значениям вложенных массивов. И тем самым упростить доступ к многомерным массивам с помощью одной строки, разделенной точками.

😎 Joomla тоже так может!

use Joomla\Registry\Registry;
$data = [
        'user' => [
                'name' => 'John Doe',
                'email' => 'john@example.org',
        ]
];

$data = new Joomla\Registry\Registry($data);

$name = $data->get('user.name');
dump($name); // 'John Doe'

Чат русскоязычного Joomla-сообщества.

Upd. И коллеги сразу решили дополнить:

Преимущество джумлы перед ларой в этом плане:

  • можно так обращаться не только к массивам, но и к объектам и даже к json'у

  • можно дополнять

  • можно выполнять merge. Причём, как на весь объект, так и на отдельные его вложенности

Недостатки:

  • нужно сначала создать новый объект

  • нет вот такой нотации get('*.key'), т.е. чего-то похожего на array_column()

Теги:
Рейтинг0
Комментарии1

Как заговорить с сетевиками на одном языке? 😎

В Академии Selectel появился бесплатный курс «Погружение в компьютерные сети». Он поможет разобраться в принципах работы, понять ключевые термины и уверенно ориентироваться в основах. Всего час — и сложные вещи станут простыми.

Курс подходит новичкам, которые хотят разобрать тему по полочкам. Но и опытным специалистам будет полезно: с этими материалами вы восполните пробелы в знаниях и вспомните все, что забылось со временем.

Начните обучение в Академии Selectel прямо сейчас ➡️

Теги:
Всего голосов 5: ↑5 и ↓0+8
Комментарии0

ОТП Банк дважды стал лауреатом премии Finnext 2025

ОТП Банк стал двукратным лауреатом премии Finnext 2025. Итоги подвели 27 марта в Москве. В рамках этого престижного события, учрежденного ИД «Регламент» и порталом FutureBanking, банк был признан победителем в двух ключевых номинациях: «Лучший кейс в технологиях работы с данными банка» и «Лучший кейс инноваций в маркетинге банковских продуктов».

Лучший кейс инноваций в маркетинге банковских продуктов

Награда была присуждена ОТП Банку за лучший кейс инноваций в маркетинге банковских продуктов. Проект по AI персонализации для холодного трафика на сайте банка позволил значительно улучшить взаимодействие с клиентами.

Используя платформу Sales Ninja, ОТП Банк перешел от ручных A/B тестов к автоматическим предиктивным персонализациям на основе искусственного интеллекта, что позволяет в режиме реального времени подстраивать сайт под каждого пользователя. Даже если он зашел на сайт в первый раз.

«Мы смогли не только «пробить потолок» классических подходов к работе над сайтом, но и улучшить ценность для наших клиентов. Персонализация — это не только про метрики, но и про то, что мы говорим с клиентом на понятном для него языке»,подчеркнул Вадим Валиуллин, product owner сайта ОТП Банка.

Лучший кейс в технологиях работы с данными банка

Проект «Data Governance: управление данными как активом в ОТП Банке» направлен на совершенствование культуры работы с данными. Николай Шевцов, директор по управлению данными ОТП Банка, отметил, что «данные в банке теперь воспринимаются как стратегический актив, а управление ими стало частью корпоративной культуры».

За последний год команда внедрила систему Data Governance и интегрированную с ней платформу автоматизированного контроля качества данных с элементами AI, обучила более 400 сотрудников работе с ней и интегрировала стандарты безопасности данных на всех уровнях организации. Результатом стало снижение ошибок при формировании отчетности, повышение доверия к качеству данных и улучшение процесса принятия бизнес-решений.

Он пояснил, что проект по внедрению культуры Data Governance играет ключевую роль в повышении эффективности, прозрачности и конкурентоспособности банка. «Глубокий анализ качественных клиентских данных позволяет персонализировать продукты и услуги, снижается вероятность ошибок в расчетах. А это значит, что коммуникации и предложения для клиентов становятся максимально индивидуальными», - подчеркнул Николай Шевцов.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

К рекламе на сайтах все давно привыкли. Наверное, все так же понимают, что рекламные баннеры - это способ заработка для сайта, поэтому просьбы "отключите пожалуйста блокировщик" - это вполне понятно.

Но почему на некоторых сайтах, не будем ни на кого показывать пальцем, простая операция блокировки рекламы не только убирает какие-то там дополнительные картинки, которые можно было бы считать элементом дизайна и даже украшением - но еще и снижает загрузку CPU примерно в 8 раз?

Это что, показ картинки НАСТОЛЬКО процессор грузит? Какая-нибудь игра типа Quake c "живой" графикой - и то меньше ресурсов жретъ.
Или её попиксельно рисуют джваскриптом?
Или это не в картинке проблема?

А что, если (ну так, в порядке предположения) владельцы вебсайтов посмотрят внимательнее, что и как там у них работает, и будут просто показывать рекламные картинки без всех этих прилагающихся к ним тормозов и жора памяти - может быть тогда люди будут меньше пользоваться всякими адблокерами?

Или эту мысль надо доносить до рекламодателей, в лице их SMM-щиков?

Теги:
Всего голосов 11: ↑11 и ↓0+13
Комментарии11

Регулярно на Хабре выходят статьи с рекомендацией использовать moment.js. В комментариях обязательно начинают советовать какой-нибудь dayjs или js-joda, но не потому, что они чем-то сильно лучше, а потому, что первый задепрекейчен авторами.. в пользу luxon.

Что за мания такая у JS-еров использовать раздутые тормозные библиотеки? Есть же быстрый и миниатюрный $mol_time с гораздо более удобным и функциональным API, почти полностью поддерживающим ISO8601, в отличие от всех остальных библиотек.

Бенчмарки говорят сами за себя
Бенчмарки говорят сами за себя

Что мотивирует людей довольствоваться не самым лучшим решением в индустрии? Я, наверно, странный, но я не могу этого понять.

Теги:
Всего голосов 18: ↑7 и ↓11-2
Комментарии39

Sketch-Programming: Минималистичная парадигма для проектирования кода (LLM transpiler)

(https://github.com/DmitryOlkhovoi/vscode-sketch-programming)

Удалось за вечер написать расширение под VS Code, которое на onSave траспайлит псевдокод (так называемый sketch код) и сохраняет.
Пока это POC и не полностью автоматизированный, но в качестве теста уже интересно

// @sketch:reactComponent

Component Count

props add = 0
state count = 0

<div onclick="count += add"> Add {add} </div>
<div>
    Current count: {count}
</div>

Превращает в

import React, { useState } from 'react';

interface Props {
    add?: number;
}

const CountComponent: React.FC<Props> = ({ add = 0 }) => {
    const [count, setCount] = useState<number>(0);

    const handleClick = () => {
        setCount((prev: number) => prev + add);
    };

    return (
        <div>
            <div onClick={handleClick}>Add {add}</div>
            <div>Current count: {count}</div>
        </div>
    );
};

export default CountComponent;

Следуя загруженным в векторное хранилище правилам (OpenAI)
https://github.com/DmitryOlkhovoi/Sketch-programming/blob/main/ReactComponentAskedModelToAddMoreRulesItself.md

К понедельнику постараюсь написать статью и более детально раскрыть тему

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Представлен оналайн‑ресурс под названием «Утраченное искусство логарифмов», в котором исследуется полезность, история и повсеместность этого чудесного изобретения, логарифмы, включая то, что они, такое; с некоторыми демонстрациями их основного исторического применения в плоской и сферической тригонометрии.

Проект находится в разработке, но там уже есть основные начальные главы.

Теги:
Всего голосов 5: ↑5 и ↓0+6
Комментарии0

Как не надо использовать Assert, если реализуете подход Design by Contract

Использовать Assert вместо if err != nil { return err}

Одно из неправильных применений Assert — это замена им проверки, которая действительно должна быть и на которую нужно реализовать реакцию в коде.

Выполнять вычисления при вызове Assert

Еще одна распространенная и трудно выявляемая ошибка — это выполнение вычислений и присваивание значений переменным прямо при вызове Assert, которые могут быть упразднены при оптимизации кода компилятором:

  •  e.g. Assert(i++ > 0, “осторожно, не факт, что в релизе i увеличится”),

  •  Assert(call_to_f1(), “осторожно, не факт, что call_to_f1() будет вызвана в релизе”).

Удалять Assert, несмотря на то, что это часть описания контракта

Непонимание, что Assert — это реализация контракта, может привести к тому, что разработчик, незнакомый с DbC, захочет просто удалить проверку. Однако нужно всегда помнить, что срабатывание Assert говорит о нарушении контракта одной из сторон. То есть, если срабатывает Assert, надо прежде всего найти баг и пофиксить. А уж если контракт действительно должен быть изменен, Assert подскажет, где находятся участки кода, на которые нужно обратить внимание.

Например, вызывающая сторона может полагаться на некоторое поведение вызываемого кода. И если вызываемый код существенно изменился и контракт не выполнен, то вызываемая сторона тоже должна быть существенно переосмыслена.

В реализации пакета Go 1.23 fmt-функция Printf всегда возвращает err = nil. И практически все игнорируют возвращающееся значение ошибки, тогда как могли бы проверять постусловие assertion.Assert (err == nil). Так, рано или поздно в последующих версиях можно научить код реагировать на err, отличный от nil.

Как правильно применять assertions, если реализуете подход Design by Contract для улучшения производительности кода в продакшене? Читайте в статье →

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Собственные макеты вывода для пользовательских полей Joomla

Мы привыкли использовать механизм переопределения макетов Joomla: скопируй нужный тебе файл макета в папку html шаблона и твори там что хочешь. Это в полной мере относится и к пользовательским полям Joomla.

Joomla ищет макеты рендера всех пользовательских полей в следующем порядке:

  • Есть ли файл templates/[template name]/html/layouts/[component name]/fields/render.php , переопределяющий макет вывода полей для конкретного компонента? Да - используем его.

  • Нет? Есть ли файл components/[component name]/layouts/fields/render.php в папке компонента? Да - используем его.

  • Нет? Есть ли файл templates/[template name]/html/layouts/com_fields/fields/render.php, переопределяющий вывод полей для com_fields? Да - используем его.

  • Нет? Используем файл components/com_fields/layouts/fields/render.php Это механизм поиска переопределений файлов макетов.

Вчера столкнулся с тем, что если поле вставлено в текст материала с помощью шорт-кода (кнопкой редактора) вида {field 25}, то переопределения не сработали. Поэтому стал вспоминать как сделать свой макет для поля Joomla.

Выбор пользовательского макета для рендера поля Joomla
Выбор пользовательского макета для рендера поля Joomla

Файл components/com_fields/layouts/field/render.php копируем в templates/YOUR_TEMPLATE/html/layouts/com_fields/field/etapy-raboty-nad-proektom.php. Обратите внимание, что мы файл переименовали, чтобы в настройках поля видеть его в выпадающем списке. После этого всё заработало как надо.

Благо, переводил уже раньше статью Как происходит рендер пользовательских полей в Joomla?. Потом, порывшись по своему же переводу увидел, что эта особенность работы Joomla в статье уже в ней описана 😂. А также напомнил себе о возможности указывать макет поля прямо в шорт-коде, через запятую: {field 25,etapy-raboty-nad-proektom}.

Теги:
Рейтинг0
Комментарии0

Стоит ли идти во фронтенд сейчас? Честный ответ разработчика

Артем несколько лет в сфере (вот его история). Сейчас он разработчик в крупном финтех-проекте. Вот его мысли:

— Да, фронтенд перенасыщен. Фреймворков много, технологии постоянно меняются. Все говорят об одном, но пишут по-разному. Но именно это и держит в тонусе — приходится регулярно обновлять знания. Сожалею ли я о своем выборе? Нет. Всегда любил погружаться в математические задачи, а фронтенд затягивает. Можно сутки биться над багом, ненавидеть его, плеваться… А потом решить — и словить кайф. В такие моменты код полностью поглощает, заставляя забыть о сне и еде.

Стоит ли идти во фронтенд сейчас?

— Никогда не поздно. Да, путь у каждого свой, и рынок сейчас нестабилен. Но при глубоком погружении за год можно набрать нужные скиллы и попасть на коммерческий проект.

🔥 Открыт набор на новый марафон!

Сейчас в Clevertec проходит марафон для начинающих фронтенд‑разработчиков. Это возможность погрузиться в профессию, получить реальный опыт и, возможно, стать частью команды. Участие бесплатное. Успей зарегистрироваться!

Теги:
Всего голосов 3: ↑1 и ↓2-1
Комментарии1

Ближайшие события

После выхода Firefox 136 оказалось, что разработчики значительно испортили переработали стартовую страницу (about:newtab). В комментарии к новости о релизе я уже поделился своим решением, но по мере того, как подмечал новые детали, решил завести под это дело отдельный пост и время от времени допиливать его. Коротко о том, что мы исправляем: сетку с шорткатами сделали слишком узкой, слишком высокой, а при наведении курсора подпись «прыгает».

Прежде всего, для этой задачи не помогут аддоны типа Stylus, потому что по соображениям безопасности им запрещён доступ к стилизации внутренних страниц. Нам понадобится папка chrome в профиле FF. Под Windows это \AppData\Roaming\Mozilla\Firefox\Profiles\profile\chrome. Если вы хотите подправить что-то в интерфейсе (стилизовать тулбар, например), создайте там файл с именем userChrome.css. Например, так можно удалить недавно появившуюся кнопку для показа всех вкладок:

#alltabs-button
{
display: none !important;
}

Но нам нужно поменять содержимое стартовой страницы, поэтому создадим в той же папке файл userContent.css.

Сетка стала узкой и высокой, потому что кто-то из дизайнеров поменял местами промежуток по горизонтали (20px → 0) и вертикали (0 → 20px). Будем надеяться, что хоть сознательно.

Вернём всё как было (ну, или можете установить свои значения):

ul.top-sites-list
{
column-gap: 20px !important;
row-gap: 0 !important;
}

Длинные заголовки при наведении мыши прыгают потому, что включается (при наведении, да!) режим переноса по словам. Пожалуйста, никогда так не делайте в пользовательских интерфейсах. Я не страдаю эпилепсией, но даже меня затошнило. Что уж говорить о более сенситивных личностях.

Исправляем:

.top-sites-list .top-site-outer .title .title-label
{
white-space: nowrap !important;

-webkit-line-clamp: none !important;
}

Ну и, наконец, шорткат можно сделать чуть побольше. Размеры его элементов рассчитываются на основе переменной, которая имеет значение 32px. Если добавить 4 пикселя, шорткат будет выглядеть, КМК, поприятнее:

:root
{
--size-item-large: 36px !important;
}

P.S. Пользуясь случаем, хочу попросить рекомендаций: чем вы пользуетесь в качестве главной страницы? Чтобы там были шорткаты (с полноценными preview, которые зачем-то убрала Мозилла), погода, калькулятор и что-нибудь ещё? Думаю, не запилить ли свой аддон со всем этим блэкджеком.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии2

$mol_hack: finality

Вот и подошёл к концу первый хакатон по $mol, где нужно было переписать не хитрое научное оупенсорс приложение (Github, Online) на самый инновационный веб-фреймворк. Так что встречайте финалистов:

🥁🥁🥁 🥁🥁🥁

  1. ₽150K получает PavelZubkov (PR, Online). Он сделал не только наиболее полное и качественное решение, но и не большой PR в $mol.

  2. ₽75K получает reatailret (PR, Online). Он прислал достойное оригинальное решение в виде PWA приложения, но оно всё же не дотягивает до лидера по многим факторам: от неработающей авторизации, до расположения файлов не по фен-шую.

  3. ₽50K получает Lyumih (PR, Online). Его решение было самым ранним, но, как ни печально, так и осталось недоработанным. Даже не смотря на часть кода взятую у PavelZubkov.

✨✨✨ ✨✨✨

Решение dukinm (PR) существенно основано на некорректно расположенных файлах от PavelZubkov, а правки носят в основном косметический характер. Однако, он единственный, кто написал хоть немного тестов и комментариев!

Сводная таблица с анализом решений

Спасибо всем участникам за хорошую битву. Те, кто ещё не умеет в $mol, нервно грызут ногти из-за упущенной возможности.

Теги:
Всего голосов 7: ↑3 и ↓4+1
Комментарии0

Запускаем бесплатный онлайн-марафон по фронтенд-разработке. Будет как в «Рокки» 

Спринты, дедлайны и финальный тест-бой. Кто пройдет с нами три месяца подготовки — получит шанс на титул. Без метафор — мы реально ищем таланты и готовы взять их на стажировку.

Как записаться?

Заполни анкету по ссылке в профиле и скинь другу. Заявки принимаем до 26 марта.

Что будет?

Интенсивный 3-месячный тренинг. Это бесплатно. По сути, ты будешь поэтапно с дедлайнами писать приложение. Каждый спринт проверяем с помощью автотестов. Плюс будет поддержка менторов, наших крепких разработчиков. Это реальная прокачка твоих навыков и готовый проект в резюме.

Это уже четвертый марафон — после каждого наша команда фронтенд-разработчиков растет.

Кого ждём?

Начинающих веб-разработчиков (JS, React), которые уже изучали теорию и хотят прокачаться на практике в условиях, максимально близких к реальному проекту. Главное — желание кодить. Подойдут:

- студенты профильных вузов

- выпускники курсов

- самоучки

Важное условие: приглашаем участников из Беларуси и России.

Что дальше?

После 26 марта отправим на почту инструкции и первые задания. Старт марафона 1 апреля (это не шутка). До связи, Рокки. 

Теги:
Всего голосов 4: ↑3 и ↓1+4
Комментарии0

Как мы сокращали количество запросов по фичам в API

Контекст: я отвечаю за разработку конструктора Telegram-приложений. Начинались мы как конструктор кликеров (еще до хомяка). Со временем эволюционировали в конструктор курсов, сообществ, визиток, мероприятий и любых других приложений

Одна из основных сущностей в коде — это BotUser. То есть пользователь, который появился в приложении (зашёл хотя бы раз), имеет имя и Telegram ID

За ~полгода проекта у нас добавилось много фич, привязанных к пользователю. Практически все сопоставляются 1 к 1 по ключу User ID. Например, квизы, бонусные дни, купленные страницы, купленный карточки апгрейдов, тариф и т.д.

Раньше для каждой новой фичи мы добавляли новый запрос в API с фронтенда. И вот мы заметили, что на каждый заход пользователя стало уходить >10 запросов в API ⚠️.

Примерно вот так:

GET /users/user
// Response
{
  "tgUsername": ...,
  "tgId": ...,
  ...
}

GET /users/features/quizzes/completed
// Response
{
  "completedQuizzes": ...,
}
   
GET /users/features/pages/bought
// Response
{
  "boughtPages": ...,
}
   
GET /users/features/rates/rate
// Response
{
  "userRate": ...,
}

При этом, на каждый запрос мы проверяли авторизацию. В Telegram это делается с помощью хеша от Telegram + проверка подписи токеном бота

Следовательно, на каждый запрос мы делали JOIN пользователя, брали бота (сущность Bot) из кэша и мэтчили подпись (+ логгировали). Это лишняя нагрузка

Сейчас подсобрали все фичи в один запрос. Теперь, на каждый заход пользователя получается только один GET /app/account/data, который возвращает данные пользователя вместе с данными фичей:

GET /app/account/data

// Response
{
  ...
  "user": ...,
  "completedQuizzes": ...,
  "boughtPages": ...,
  "currentRate": ...,
  ...
}

За одно перепроверили, что:

  • не подгружаем связанные сущности, где не нужно (one-to-one, one-to-many);

  • если подгружаем сущности, всегда делаем это одним JOIN'ом (а не бегаем по 2-3 раза в БД, как любит делать Hibernate);

  • берём общие часто запрашиваемые данные из кэшей.

Это позволило снизить нагрузку на сервер и БД. К посту прикрепляю график загрузки части наших серверов по CPU до и после оптимизации.

---

Если вам понравился пост или оказался полезным, поставьте, пожалуйста лайк ❤️. Это мотивирует делиться опытом из разработки. И, как полагается, у меня есть Telegram-канал, в котором я рассказываю про разработку, развитие SaaS-сервисов и управление IT проектами.

Теги:
Всего голосов 5: ↑3 и ↓2+1
Комментарии0

В Joomla 4 и Joomla 5 появилась концепция Web Assets и WebAssetManager, с помощью которого можно управлять подключениями css, js файлов, подключением. Все css и js файлы включаются в общий реестр ассетов, затем выстраивается граф зависимостей и в итоге на генерируемую страницу подключается только то что нужно на данной странице.

Поскольку веб-ассеты можно добавлять с помощью плагинов (ссылка на статью ниже) - можно сказать, что появилось новое направление для плагинов - веб-ассеты. Вы можете устанавливать плагины, включающие веб-ассеты и использовать их как зависимости в самых разных местах Joomla: в шаблоне, в макетах модулей и плагинов.

Одним из таких плагинов веб-ассетов является WT JSwiper.js. Плагин добавляет в Joomla Web Assets Registry ассет популярного скрипта swiper.js, который потом легко можно использовать в коде:

use Joomla\CMS\Factory;

$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
// Локальный файл
$wa->useScript('swiper-bundle')->useStyle('swiper-bundle'); 
// Подключение из CDN
$wa->usePreset('swiper-bundle-remote'); 

😐 Например, было: иконочный шрифт могут использовать 2 разных модуля. CSS обычно подключается в шаблоне и он грузится везде, даже там, где не надо. Если же подключать CSS в одном модуле, а в другом нет - на странице стиль есть ровно до тех пор, пока опубликован модуль с этим подключением.

👍 Стало: теперь в макетах расширений мы просто пишем $wa->useStyle('my.style'); и за необходимостью подключения нужного ассета (в данном случае CSS с иконочным шрифтом) следит Web Asset Manager. Если мы снимем один модуль с публикации, то нужный ассет подключит другой модуль.

Поскольку плагин - расширение Joomla - его можно обновлять обычным для Joomla способом и всегда иметь самую свежую версию любимого js-скрипта или веб-ассета на всех своих сайтах и сайтах ваших клиентов.

В этой версии, кроме обновления собственно ассета до версии 11.2.5 к нему добавился пока что частичный перевод документации Swiper на русский язык.

Также будет полезно:

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Представлен проект Scroll Buddy — анимация на полосе прокрутки.

«Вместо скучной полосы прокрутки я подумал, что было бы забавно иметь анимированную фигурку, которая ходит вверх и вниз по краю страницы, когда вы прокручиваете. Это первый прототип, который я сделал. Собираюсь сделать скейтбордиста, скалолаза или белку следующим», — пояснил авто проекта.

Теги:
Всего голосов 2: ↑2 и ↓0+3
Комментарии2

В начале года я опубликовал статью про гибридное кэширование.

Гибридное кэширование в ASP.NET Core
В .NET 9 появилась новая библиотека для кэширования — HybridCache . В статье расскажу, что это такое...
habr.com

Прошло уже больше месяца, а стабильная версия nuget-пакета Microsoft.Extensions.Caching.Hybrid так и не вышла.

Я не делаю прогнозы по датам выхода, но хочу порассуждать на тему того, чего ожидаю от стабильной версии. И чего — точно нет.

Начну с последнего — каких изменений я не ожидаю

Изменение состава и сигнатур текущих методов. Если следить за выходом новых версий пакета Microsoft.Extensions.Caching.Hybrid, можно заметить, что методы объекта HybridCache не меняются уже давно. Из этого можно сделать вывод, что в стабильной версии мы увидим тоже самое, что наблюдаем сейчас.

Какие изменения я ожидаю увидеть

Удаление объекта из кэша по тегам. На момент написания статьи метод RemoveByTagAsync вообще не имел реализации. Сейчас в версии 9.2.0-preview.1.25105.6 он реализован и вполне себе работает, так что в релизную версию явно войдёт.

Не удивлюсь, если изменится логика присваивания тегов. Сейчас для многих она может быть неочевидной. Разберём пример:

  await cache.GetOrCreateAsync(
    "someKey",
    async ct => await SomeFuncAsync("someKey", ct),
    options,
    ["tag1", "tag2", "tag3"],
    cancellationToken);

  await cache.GetOrCreateAsync(
    "someKey",
    async ct => await SomeFuncAsync("someKey", ct),
    options,
    ["tag1", "tag4"],
    cancellationToken);

Представим, что метод GetOrCreateAsync вызывается несколько раз с одним и тем же ключом, но разным набором тегов. Теги будут присвоены только при первом попадании объекта в кэш, то есть в момент его извлечения из хранилища. Когда проектируем приложение, не всегда заранее известно, в какой из вызовов GetOrCreateAsync объект будет извлекаться из кэша, а в какой — из хранилища. Оно и логично — метод специально создали так, чтобы мы не задумывались об этом. Соответственно, сейчас при вызове этого метода мы не можем определить, какой из наборов тегов ляжет в кэш.

И тут у меня два варианта развития событий: или логика поменяется и теги будут перезаписываться всегда — независимо от того, берётся объект из кэша или хранилища. Или при написании программы нужно будет следить, не передаём ли мы разные наборы тегов.

Теги:
Всего голосов 3: ↑2 и ↓1+3
Комментарии0

Вклад авторов