В апреле этого года мы перезапустили tinkoff.ru. Банк превратился в финансовый супермакет. Теперь не только клиент банка, но и любой посетитель оплатит мобильный, проверит налоги и оформит ипотеку — всё на одной платформе. В этой статье я поделюсь опытом и технологическими решениями, к которым мы пришли за год разработки.
Наш стэк для фронтенда хорошо себя показал. Теперь мы решаем проблемы и адаптируемся к новым требованиям в рамках концепции архитектуры.
За год мы разработали 350 независимых интерфейсных блоков из 3000 React-компонентов. Оптимизировали загрузку страниц, потому что tinkoff.ru посещают 7 млн пользователей в месяц и число посетителей постоянно растет. Фронтенд разрабатывает 30 человек и мы постоянно ищем талантливых разработчиков.
Мы объединили функции предыдущих интернет-банков, портала и кошелька. Поэтому я сначала опишу исходные стэки, а потом расскажу, как мы пришли к текущему стэку.
Обзор предыдущих стэков
Портал и интернет-банк 2011
Первую версию мы разрабатывали внутренними ресурсами на основе коммерческого решения от голландской компании. Бекенд крутился на базе тяжелого Java/Spring приложения. На фронте из-за недостатка гибкости и подробной документации сформировался стэк из jQuery, Backbone, Handlebars.
Maven собирал фронт с бэком. Было катастрофически мало плагинов для фронта, так как Maven не подходил для сборки клиентских пакетов. Это привело нас в тупик. Благо нашли как отделить клиентскую сборку от серверной с помощью Grunt.
Использовать шаблоны на сервере и несвязанные шаблоны на клиенте со своей логикой и архитектурой считалось нормой. Приходилось поддерживать два UI-слоя: серверный UI и клиентский UI. Когда мы имеем крупное RIA – дублируется много логики, которая написана на разных языках программирования. Например: маршрутизация по страницам, логика получения данных или шаблоны с одинаковой разметкой.
В конце 2013 года стал развиваться изоморфный подход к созданию веб-приложений. И решение с дублированием шаблонов на сервере и на клиенте стало считаться концептуально неверным.
Кошелек 2014
Этот проект интересен по двум причинам:
- «Тинькофф Мобильный Кошелек» — первое приложение, которое использовали все, не только клиенты банка.
- Мы попробовали изоморфный подход на базе архитектуры MVC. Отправная точка — статья от Airbnb.
Стэк был схож с интернет-банком: Backbone и Handlebars, сервер на Node.js. Часть вью рендерилось на сервере. Приложение решало свои задачи и даже получился один UI-слой. Но стало ясно, что на большом приложении подобная архитектура принесет сложности. Появились проблемы с обогащением моделей данных в браузере. Приходилось писать отдельные контроллеры для серверной и клиентской стороны.
Следующий проект разработали по другой парадигме.
Интернет-банк 2015
Интернет-банк был отделен от внешнего сайта и представлял из себя Single Page Application. Для интернет-банка использовали фреймворк Angular.js. В итоге мы получили современный интерфейс интернет-банка.
В 2015 году бизнес изменил стратегию развития и предъявил новые требования к веб-приложению. Нам предстояло:
- обновить Tinkoff.ru,
- интегрировать на все страницы функциональность интернет-банка и кошелька,
- поддержать SEO и SMM для всех страниц, включая страницы с платежными провайдерами.
Новый интернет-банк имел UI-слой только на клиенте. Поисковые роботы пока не научились хорошо индексировать подобные приложения. И непонятно, когда это произойдет. Не получилось отказаться от серверного слоя. Мы видели несколько путей развития существовавших стэков:
- Объединить старый портал и новый интернет-банк. Портал выступал бы в качестве серверного UI-слоя, а Angular.js в качестве клиентского. Этот вариант не решил бы наши фундаментальные проблемы.
- Заменить Java приложение Node.js приложением. Это могло бы упростить поддержку, но оставалось два UI-слоя.
- Убрать Java, оставить только Angular.js. И рендерить SPA с помощью развернутых серверов с headless браузером Phantom.js. Такую схему сложно отлаживать, поэтому этот вариант не подходит для большого количества страниц.
Мы проанализировали пути развития существовавших стэков и поняли, что они не решают наших задач. В итоге выбрали кардинально другой подход.
Платформа 2016
То, что сейчас доступно на Tinkoff.ru, мы называем платформой.
За основу этой системы мы выбрали архитектуру Flux, которую предложили инженеры Facebook в 2014 году. Flux отличается от MV* тем, что в нем отсутствуют разнонаправленные потоки данных, что легче ложится на изоморфную парадигму и всё это помогает быстрее отлаживать приложение. Архитектура Flux взяла за основу модель работы с базой данных CQRS.
Мы реализовали идею изоморфного приложения с одним UI-слоем. В качестве шаблонизатора выбрали библиотеку React.js с поддержкой виртуального DOM. Благодаря которому шаблоны легко рендерятся на сервере.
Сложившийся стэк решает задачи SEO и SMM. Переиспользует код между браузером и сервером, за исключением специфичного для окружения кода, например работа с cookies. Позволяет решать весь спектр задач одной группой разработчиков, что приводит к ускорению работы. Не зависит от одного фреймворка/вендора. Приложение объединяется набором правил, выстраивается из небольших и независимых модулей. Модуль можно заменить, если будет более подходящая реализация.
Универсальное приложение
Fluxible
В качестве реализации Flux выбрали фреймворк Fluxible от инженеров Yahoo. Эта реализация ориентирована на изоморфный рендер. Выбранное решение полностью удовлетворяет нашим требованиям.
Мы стараемся не связывать приложение крупными зависимостями, поэтому используем только две библиотеки из набора:
- Routr – маршрутизация по страницам. Библиотека поддерживает express-подобные пути. Она изоморфная и быстрая: сейчас роутимся по 2000 страницам.
- Dispatchr – Flux диспетчер.
Распределение по слоям
Архитектура приложения
Сервисы. Доступ к браузерным или HTTP API, взаимодействие с внешними системами. Здесь содержится часть бизнес логики. Сервисы имеют несколько реализаций: изоморфные shared, server для node.js и client для браузера. Могут кэшировать результат.
Действия. Flux action creators, содержат часть UI и бизнес логики. Имеют доступ к сервисам.
Сторы. Модели данных, которые содержат UI логику.
Компоненты. Рендер данных из сторов в HTML.
Прогрессивная загрузка
Благодаря серверному рендеру мы получаем эффект прогрессивной загрузки и сокращение time to glass. Средний пользователь видит работающую страницу через 600 мс после запроса сайта. Через пару секунд инициализируется динамика и загружаются персональные данные.
Мы можем рендерить все данные на сервере, можем ренедрить часть. А можем полностью отключить серверную часть и использовать приложение как SPA. Чтобы сократить нагрузку на сервера, рендерим только общие данные для всех пользователей, а работу с персональными данными выполняем в браузере.
Пример кода
Что выполнять на сервере или что позволить запустить пользователю с определенными ролями, мы определяем на уровне функции создания действия:
import { ACCOUNT_LIST } from '../actions';
import { CLIENT } from '../roles';
accountList.isServer = true; // Флаг указывает на право запуска действия на сервере
accountList.requiredRoles = [CLIENT]; // Список указывает необходимые роли пользователя
function accountList(context) {
return context.service('account/list') // Каждая часть приложения имеет свой ограниченный контекст с набором методов из общего контекста. Таким образом вызываем сервисы.
.then(payload => context.dispatch(ACCOUNT_LIST, payload)); // Далее диспатчим действие с полезной нагрузкой
}
export default accountList;
В остальном коде приложения нет условий для определения окружения. Все решается на уровне контекста, который наследуется от базового класса контекста.
Переиспользование
Компоненты приходилось использовать с разными моделями данных. Их стало сложно поддерживать, тестировать и переиспользовать. Поэтому мы разделили компоненты на коннекторы и чистые компоненты:
Такой подход упростил переиспользование компонентов и тестирование.
Пример коннектора
import { LogoPure } from './LogoPure.jsx';
const UILogo = connect(
['config', 'brands'],
({
brands,
config: { brandsBasePath }
}) => ({
brands,
brandsBasePath
})
)(LogoPure);
export default UILogo;
Используем утилиту connect (схожа с коннектором из redux), которую можно использовать в виде декоратора. Первый аргумент – список сторов, в которых мы заинтересованы. Второй аргумент – функция маппинга, которая принимает состояние всех сторов и возвращает только нужные чистому компоненту данные.
Higher-order Components
Следующий подход, который мы изначально не использовали для наследования кода — компоненты высокого порядка. Переиспользовать код между компонентами помогали миксины, которые поддерживает React.createClass.
Миксины не гарантируют свое окружение. Если на компоненте использовать более трех миксинов и если они становятся зависимы, то поддержка такого компонента становится проблемой. Подробнее об этом в статье Mixins Are Dead. Long Live Composition.
Оптимизация
Оптимизация универсального приложения находится на двух сторонах: клиентской и серверной. Расскажу о наших подходах к разработке быстрого приложения.
Оптимизация на клиенте
Первое правило быстрых компонентов – как можно реже вызывать метод render. Для этого мы используем подход pure-render. Он вызывет render через переопределение метода shouldComponentUpdate, если только исходные данные изменились (props или state).
Иногда в компонент передается больше данных, чем ему нужно. Иногда меняются поля модели, данные не меняются, а ссылка на модель данных изменилась. В этом случае проверка pure-render не срабатывает. Чтобы определить количество вызовов render того или иного компонента, мы используем модуль react-perf. С его помощью получаем статистику в удобном виде:
Если находим компонент с неоправданно большим количеством ререндеров, то диагностируем его подробней с помощью нашей утилиты render-logger. Она позволяет увидеть измененные данные, которые повлекли вызов render:
Рендер произошел из-за изменения функции, переданной в свойство onClick. Это происходит при использовании bind или определении функции внутри render родительского компонента, когда при каждом вызове render создается новая функция. И из-за этого не срабатывает защита pure-render дочернего компонента.
Чтобы запретить bind в render, используем линтинг Eslint с плагином eslint-plugin-react и опцией jsx-no-bind.
Batched updates
React поддерживает изменение стратегии рендера в runtime. Мы используем стратегию пакетного обновления при первоначальной инициализации. Или при переходах между страницами, когда происходит повышенная активность приложения. Это уменьшает итоговое время рендера.
Визуальное ускорение
Следующий способ, который мы используем для ускорения клиентского экземпляра приложения, это визуальное ускорение. Считаю этот способ лучшим по соотношению затрат к результату.
Сейчас на главной Tinkoff.ru есть шапка с логотипами платежных провайдеров, которые появляются с анимацией.
В первых версиях логотипы появлялись только после загрузки клиентского пакета JS. На медленном мобильном интернете это приводило к неприятному эффекту долгой загрузки страницы. Пользователь ждал, когда серый блок будет наполнен.
Мы решили изменить стили и код компонента, чтобы отрисовывать логотипы на сервере. Благодаря отказу от ожидания инициализации клиентской части, уменьшилось время до появления логотипов.
Оптимизация на сервере
Серверный рендер компонентов React медленней простых строковых шаблонизаторов. Я расскажу о том, как мы ускоряем рендер на сервере.
- Используем ES6 Class, а не React.createClass (он медленней из-за autobinding) и не забываем NODE_ENV=production, который отключает код для отладки. Это приводит к 4х кратному ускорению.
- Минифицированная версия React. Код для профайлинга удален полностью. +2% (здесь и далее прирост относительно первого пункта)
- Трансформация кода на уровне Babel. Используем два плагина:
- transform-react-constant-elements поднимает инициализацию компонентов в верхний скоуп модуля
- и transform-react-inline-elements преобразует вызов createElement к оптимизированному виду. +10%
- Максимально используем stateless функции. На тестовом стенде замена всех компонентов привела к прибавке в 45%.
- React-dom-stream приводит результат функции renderToString к потоку, что дает уменьшение времени до отдачи первого байта (TTFB) на нашем стенде до 3-5мс. И к сокращению времени до передачи последнего байта (TTLB) на 55%.
На данный момент библиотека не поддерживает React 15. Возможно, функциональность библиотеки включат в ядро React: https://github.com/aickin/react-dom-stream/issues/18 Помимо этого, библиотека реализует интересную возможность кэширования компонентов по отдельности, что может ускорить серверный рендер.
На данный момент мы кэшируем всю страницу. Благодаря отсутствию персональных данных в HTML, нам это далось легко.
Кэш
Кэширование в приложении реализовано на нескольких уровнях:
- Nginx кэширует на короткий промежуток времени результат генерации всей страницы.
- Express-cache-on-deamand страховка от потока однотипных запросов.
- Lru-cache библиотеку используем для кэширования результатов сервисов.
С lru-cache мы используем нестандартную схему удаления данных из кэша. Любые данные при достижении TTL не удаляются из памяти, а запрашиваются у источника. Если источник ответил новым результатом – кладем значение в кэш. Такой подход повышает отказоустойчивость, когда внешние системы недоступны. Если мы единожды получили данные из внешнего сервиса, то уже не потеряем.
Есть библиотека, которая реализует похожую схему:
Сборка и деплой
Для сборки и деплоя используем CI Teamcity. Делаем два отдельных артефакта для клиента и сервера. На сборке клиентского пакета обычная конфигурация Webpack. Со сборкой серверного пакета интересней.
Сначала мы просто собирали пакет tar из исходников и распаковывали его на сервере. Когда модулей для компиляции Babel стало много, первые запросы на сервер стали проходить долго – Babel компилировал все при первых запросах.
Первое реализованное решение – процесс прогрева перед стартом, компиляция.
Затем настроили прекомпиляцию Babel при сборке артефакта, что сократило время прогрева до пары секунд.
Сейчас в момент прогрева происходит только наполнение кэшей данными из внешних сервисов. Такой подход экономит время на сборке с помощью переиспользования времени, затраченного на компиляцию Babel в клиентской сборке.
Второе решение, которое можно использовать – компиляция серверного пакета с помощью Webpack. Этот подход более функциональный, но влечет увелечение общего времени сборки.
В артефакты мы не записываем переменные окружения, а передаем их только при старте серверного экземпляра приложения. Значения переменных окружения записываются в стор и передаются на клиент через стандартный процесс передачи состояния приложения с сервера на клиент.
Для запуска и мониторинга приложения на сервере используем application runner PM2. PM2 имеет богатую функциональность.
- Для запуска приложения используем команду pm2 startOrGracefulReload processes.json, что позволяет перезапускать приложение с минимальным временем недоступности.
processes.json:
{ "name": "portal", "script": "server/index.js", "instances": -1 }
- Если ваше приложение запускается более чем на одном сервере, то между ними есть балансировка. И в этом случае балансировка между форками с помощью Node.js кластера становится ненужной. Мы убрали балансировку балансировки и переложили эту ответственность на единую точку – Nginx. Каждый экземпляр приложения на всех серверах запускается на отдельном порту и Nginx знает о всех экземплярах. Благодаря PM2 сделать это просто. При выборе порта нужно учитывать переменную окружения NODE_APP_INSTANCE: PORT: process.env.PORT + process.env.NODE_APP_INSTANCE
Завершение
Универсальное веб-приложение решает выставляемые задачи, объединяет одну ответственность в одну кодовую базу. React.js заставил переосмыслить сложившиеся практики в разработке веб-интерфейсов. Виртуальный DOM становится стандартом де-факто для шаблонизаторов. Flux упрощает разработку и отладку сложных приложений. Node.js продолжает завоевывать свое законное место на корпоративных серверах.
Если вы не разрабатывали приложения на схожем стэке, то, надеюсь, прочтение статьи сподвигнет вас на смелые эксперименты в этом направлении. Думаю, в ближайшие несколько лет не появится кардинально новых подходов и инструментов для разработки приложений, которые бы на порядок упрощали разработку. Есть смысл вложить немного своего времени в изучение React.js, Flux и присоединиться к нашей Dream Team.
Пишите о себе на best-talents@tinkoff.ru.
Делюсь фотографиями с одного планирования и обычной пятничной тусовки:
Спасибо и до новых встреч!
PS: Если вы хотите получить навык промышленной разработки веб-приложений, а также навыки создания конечных продуктов, то добро пожаловать в нашу летнюю школу FinTech. Курсы ведут наши специалисты и по итогу вы научитесь создавать финансовые продукты.
Комментарии (146)
NosFire
23.06.2016 17:20+1Ну раз обучение бесплатное, то после окончании летней школы курс выложите или это останется тайной? Просто темы интересные, а каждую неделю ездить в Москву накладно.
PhilNehaev
23.06.2016 17:20+1По мере обкатки формата подумаем над публикацией материалов.
NosFire
23.06.2016 17:27И еще хотелось бы спросить, можно ли получить задание, не регистрируясь или зарегистрироваться формально, чисто для получения задания? Челлендж ради спортивного интереса, а регистрироваться не хочется, т.к. я точно не буду проходить курсы школы.
PhilNehaev
23.06.2016 17:33Мы пока работает над очным форматом. В будущем не исключаем онлайн.
NosFire
23.06.2016 17:40Не, Вы меня не совсем поняли или я не правильно сформулировал вопрос. Я про задание вступительного экзамена.
То есть хочу поучаствовать, но уже без дальнейших действий, и чтоб не мешать остальным участникам.
prog666
23.06.2016 17:45почему-то когда из старого письма пытаешься получить выписку он говорит что ссылка устарела и предлагает перейти по новой, которая ведет на страницу авторизации, но открывается белый экран.
PhilNehaev
23.06.2016 17:54-4В ближайшее время исправим эту ошибку. Пока можете перейти на любую другую страницу сайта и авторизоваться в интернет-банке через боковую панель.
nd0ut
23.06.2016 17:59+1Ух и люблю же я подобные статьи! Ребятки, есть несколько вопросов:
Почему выбрали именно Fluxible? Я, признаться честно, впервые о нём услышал, поэтому и спрашиваю. В доках мелькает слово reducer, в статье говорится про сходство декоратора c connect из redux, из чего я сделал вывод, что они схожи. Не могли бы Вы вкратце описать разницу, плюсы/минусы?[упс, уже ответили]- Не поделитесь своим render-logger'ом?
- Откуда Вы взяли цифры в главе про оптимизацию на сервере? Бенчмарки делали или на глаз?
- Как Вы решили проблему, когда Вам необходимо передать в props метод компонента с прибитыми аргументами, но bind использовать-то нельзя? Я
нашёл выход в оборачивании метода в мемоизированный метод и прокидывании аргументов через замыкание
@memoize() foo(i) { return () => this.props.actions.bar(i); } render() { return <div onClick={this.foo(666)} />; }
Спасибо.
PhilNehaev
23.06.2016 18:17+42. Планируем выложить на github. Ссылкой поделюсь здесь.
3. Использовали бенчмарк, генерировали дерево компонентов.
4. Один из вариантов: записать значение в атрибут тега и получить в обработчике события.
DistortNeo
23.06.2016 18:01+20Не могу не поругаться. Переход на новый интерфейс сделал возможность использования интернет-банка с телефона сильно затруднительным, а использование с обычного компьютера — неудобным.
1. Чистый заход на главную страницу — 100 запросов, 9 мегабайт трафика. Если давно не заходил с телефона, а Wi-Fi рядом нет — будет медленно. Да, я очень быстро увижу странцу с информацией, логотипами, увижу кнопку входа, но она не будет работать — мне все равно придётся ожидать, пока сайт догрузится.
2. Объём файлов со скриптами — 4 мегабайта. Представьте теперь нагрузку на CPU, когда браузер их парсит и выполняет. На телефоне годовой давности неприятно подтормаживает. Эффект от выбора действий я часто вижу только через ~5 секунд.
Ожидаемый эффект: сразу после нажатия на любую кнопку интерфейс блокируется = действие принято,
Наблюдаемый эффект: ничего не происходит, через 5 секунд наблюдается реакция.
3. Интерфейс адаптирован под мобильные устройства. Для десктопа я такое считаю неприемлемым и неудобным: хочется видеть меньше интерактива и больше предсказуемости.
4. Общие неудобства интерфейса: вгоняет в ступор пункт меню «карты» — я ожидаю здесь увидеть список своих карт, а не предложения банка. Кнопки входа и выхода неочевидны.Darka
23.06.2016 18:05+4Присоединяюсь, новый интернет банк стал неюзабельным тормозом. Внезапно не все ваши клиенты имеют пару ксеонов и 10G каналы до вашего ЦОДа.
Спасибо, что хоть старую версию (2015) не отключили.
PhilNehaev
23.06.2016 18:07-1Спасибо за подробный отзыв. Мы недавно запустили новый сайт и сейчас активно работаем над оптимизацией и улучшением UX.
На данный момент главная страница со всеми ресурсами весит 3 мб в gzip, возможно ваш браузер по какой-то причине получил несжатые ресурсы.SynteZZZ
23.06.2016 18:26+233мб? Это серьезно считается адекватным размером для одной страницы сайта, который должен быть доступен с мобильного устройства?
Включите в хроме тротлинг на Regular 2G, посмотрите сколько времени займет загрузка на интернете, который может застать вас в самый интересный момент.
Я уже молчу о том сколько это будет стоить на тарифе не ориентированном на мобильный интернет.PhilNehaev
23.06.2016 18:30+4Проблему с размером решаем. Улучшаем процесс сборки клиентских пакетов, делаем динамическую догрузку скриптов.
Archon
24.06.2016 09:04+4Динамическая догрузка скриптов — это как раз тот самый вечный жёлтый прогрессбар, который не даёт ничего сделать на полностью отрендеренном сайте, пока не вздремнёшь полчасика?
Проблема у вас архитектурная, и это очевидно. Страницы просто не должны столько занимать и так долго грузиться, ни с динамической догрузкой, ни без неё. У вас не гугл-мапс, у вас интернет-банк, в котором конечному пользователю нужны полторы цифры, три кнопки и две галочки.PhilNehaev
24.06.2016 09:18Желтый прогрессбар появляется при загрузке данных из внешних сервисов. Динамическую догрузку скриптов делаем для уменьшения времени первоначальной загрузки сайта (загрузки первой страницы), чтобы заранее не грузить логику, которая не используется на запрашиваемой странице.
faiwer
24.06.2016 12:42После загрузки главной страницыDistortNeo
24.06.2016 20:57+1А теперь попробуйте ради интереса посмотреть на gmail.com и ужаснитесь ещё больше: там количество запрашиваемых скриптов вообще переваливает за 10 мегабайт!
faiwer
24.06.2016 21:52gmail-у быть огромным ещё простительно, ибо это один из лучших почтовых клиентов (т.е. серьёзное и сложное UI), плюс у него:
- есть мобильное приложение, где не требуется подгружать 10 MiB скриптов
- есть мобильная версия (5.3 KiB)
- большая часть функционала доступна напрямую сразу после загрузки
Хотя, конечно, 10 MiB и для gmail-а как-то слишком уж много, ИМХО. Не понимаю, чего они туда понапихали.
Apathetic
24.06.2016 21:56+1У Тинькофф тоже есть мобильное приложение. Причем для всех популярных платформ, включая Windows.
>большая часть функционала доступна напрямую сразу после загрузки
Скажите, пожалуйста, что значит «большая часть функционала», и после загрузки чего?faiwer
24.06.2016 22:07После загрузки SPA. Написание новых писем в один клик, чтение писем в один клик, фильтрация, зачем-то hangouts, зачем-то звонки в 1 клик, метки… Практически всё (или всё), что я в gmail знаю и использую доступно сразу после загрузки в 1 или 2 клика мыши. Без дозагрузки какого-нибудь модуля. Т.е. по сути большая часть функционала gmail-а представляет из себя один "модуль", делить который на отдельно загружаемые подмножества лишняя морока и проблемы\тормоза для посетителя. Но это тоже есть, к примеру настройки догружаются by demand. Каждый из вышеперечисленных пунктов может быть куда замороченнее, чем можно подумать на первый взгляд. К примеру написание письма содержит визивиг, загрузку файлов, какую-нибудь интеграцию с google drive-ов, словари (контакты, имейлы, ещё что-нибудь...). В общем углубляясь в нюансы, оказывается, что там довольно много всякого. И учитывая что это почтовый клиент, это всё доступно в 1-2 клика. Пользователь не ожидает дозагрузки такого функционала.
Помимо прочего gmail умеет работать без сети. Если к этому моменту он загрузился, конечно же. Он доотправит письмо, когда появится сеть. Причём самостоятельно. Если во время написания письма — не будет связи, не беда. Не будет доступен google drive, upload… Не так критично. Новые письма будут не видны. Но в целом offline работоспособность в наличии.
Не думаю, что это применимо к главной странице Тинькофф.ру. Там должен грузиться из коробки framework с базовыми потрохами, вроде роутеров, и пара модулей из главной страницы (несколько форм на главной всё таки есть). Сами модули потребуют ещё десятка (всякие нестандартные контролы, словари, ещё что-нибудь). Это всё должно легко уместиться до 1 MiB, ИМХО.
solver
24.06.2016 22:30> есть мобильное приложение… включая Windows.
Это очень условное утверждение. Формально приложение есть, но по факту, там походу теперь только баланс можно смотреть. Например при переврде с карты, надо ввести cvv код. Но поля для его ввода просто нет. Можно долбиться очень долго и непонимать, почему платеж отклоняют.
Оно не обновлялось ооооочень давно. Уже пару лет висит надпись «Мы разрабатываем новую крутую версию. Уже очень скоро, будет готово».
Походу они забили на это приложение…
Потому что этой проблемы раньше не было. Но после появления новой web версии отвалился WP клиент. Кстати, этот же глюк был и в web версии, но его поправили за несколько дней.DistortNeo
24.06.2016 22:59У меня тоже негативный опыт использования мобильного приложения: год назад оно просто падало при логине (сейчас, кстати, не падает). Но тогда я не стал разбираться с причиной, т.к. интернет-банком было пользоваться вполне удобно, а просто удалил приложение.
vitalybaev
24.06.2016 11:21+4Ну да, ребят, я сейчас на LTE ждал первичного отображения секунд 10. Как по мне, никакие технологии, украшательства и прочее не достойны такого размера.
Ronnie_Gardocki
23.06.2016 19:14+26ТРИ МЕТРА С ГЗИПОМ? О_О
Матерь божья. Я тут недавно сходил с ума от того что у нас проект весит 900кб с гзипом, пытаясь понять почему же мы так над юзерами то издеваемся, а тут трешка у интернет-банкинга! Где половина юзеров скорее всего желает зайти на сайт, залогиниться и чекнуть счет/последние операции. Я вот прям читал статью и чувствовал, что что-то тут не так.
DistortNeo
23.06.2016 21:03Хоть пользователей не ругаете — это хорошо. Если отбросить в сторону вопросы производительности, то готов ещё указать замечания по дизайну, которые, на мой взгляд, делают работу с сайтом некомфортной:
1. Постоянно присутствующие плашки, которые отнимают 1/3 — 1/4 вертикального пространства браузера. Прикручивая страницу вниз, ожидаешь, что они уедут вверх, но этого не происходит. Даже развернув браузер на полный экран, я все равно не могу видеть информационные блоки целиком — приходится постоянно скроллить вверх-вниз, чтобы ознакомиться с продуктами.
Не бойтесь, что пользователь не всегда видит меню. Пользователю естественно проскроллить страницу вверх, если нужно перейти к меню. Также пользователь при скролле ожидает естественной прокрутки страницы.
Временная полумера для меня: блокировка объектов соответствующих классов через ABP (длинный класс ui-что_то_там-fixed). Кстати, всё чаще замечаю, что использую ABP не для вырезания рекламы, а для блокировки нежелательного для меня функционала веб-сайтов. В числе последних — facebook, pin (настойчивое предложение зарегистрироваться).
2. Нелогичное поведение + элементарные баги. Например, страница https://www.tinkoff.ru/business/
В блоке «Бесплатное приложение и интернет-банк» акцент привязан к положению скролла на странице, ещё и с ошибкой.
В блоке ниже («Управляйте деньгами») — уже к фокусу мышью.
Ещё ниже — никакого акцента нет.
Я бы отказался от интерактивного акцента вообще — он раздражает и мешает получать информацию.
3. Информация на странице идёт в навал, причём нет чёткого разделения между блоками подаваемой информации. Сайт банка — не новостная лента в соцсети.
Вот пример удобной подачи информации — я считаю, что именно к нему нужно стремиться:
https://t.tinkoff.ru/documentation/
Добавьте к нему History API — люди только спасибо скажут.
4. Крупный текст. Нет необходимости плашкой на полэкрана писать, что я оплачиваю onlime. Достаточно небольшого заголовка сверху с логотипом.
vintage
23.06.2016 20:35+4Я вообще пол минуты тупил и искал кнопку входа, которая потерялась в безудержной карусели логотипов.
Статистика: http://www.webpagetest.org/video/compare.php?tests=160623_Y4_1082,160623_NZ_1083,160623_JV_1084
Видео: http://www.webpagetest.org/video/view.php?id=160623_ce3f4c6a879cc8999445944e1b96e8ef18ca4420
Да, страница появляется быстрее, но пока пройдут все анимации и закончатся скачки ею всё равно пользоваться невозможно. Но даже если закрыть на это глаза — больше трёх секунд приходится ждать, пока хоть что-то появится на экране. Для сравнения, простая форма входа может появляться меньше чем за секунду и быть сразу полностью функциональной: http://www.webpagetest.org/video/view.php?id=160515_4f193e07f4c37dc3b72dd3799dd27397551690a2
keysi
23.06.2016 20:53+2Действительно, мобильные фишки в десктопе жутко раздражают. Я ни когда не пользовался старой версией, но мне не удобно, когда вместо привычных инпутов, которые легко заполнить, появляются какие-то скрывающиеся-появляющиеся поля, причём если случайно кликнул где-то — они опять закрываются и нужно всё вводить заново. Иногда не подхватывает пароль из браузера. В общем — приходится много лишних действий совершать. Вместо излишне ускоренного входа (за который вы зачем то так боритесь?) вы создаёте пользователям проблемы с простейшей авторизацией.
А когда нужно отвлечься к документам и вернуться всего через мгновение, я снова получаю ненавистное окно ввода логина и пароля, после которого всё сбрасывается и интерфейс загружается снова.
Расположение элементов — плюс, много лишней анимации и непривычные элементы — жирный минус. Из-за этих и ещё некоторых мелочей есть желание отказаться от банка в целом, но борюсь с собой, так как понимаю — бета, надо потерпеть и надеяться на лучшее.Rampages
24.06.2016 08:35+3Это болезнь индустрии такая. По сути там хватило бы простейшего интерфейса без всех этих анимированных интерфейсов, т.к. пользователю нужно совершить простейшие операции, в которых анимация процесса дело последнее, все равно ждем SMS с информацией о транзакции.
gromka
23.06.2016 18:11+8Новый ужасен, старый был прекрасен. Зачем вы все испортили…
MaxKorz
23.06.2016 18:40+17Согласен. Старый интернет банк прямо на главной предлагал ввести логин и пароль. При включенном автозаполнении при оставалось 1 раз нажать «Войти» и все.
Сейчас мне нужно нажать Войти, ввести логин, чтобы появилось поле ввода пароля, и уже после этого нажать «войти». Ужасно.SarganSaor
23.06.2016 18:45+7Присоединяюсь, три действия вместо одного. Конечно возможно это защита от какого нибудь брутфорса, но неудобно — факт.
druf
23.06.2016 20:52+3Добавлю еще, ув. PhilNehaev, у меня перестал работать LastPass. При попытке выполнить автозаполнение хотя бы логина, поле остается пустым. Поле с паролем тем более не заполняется. Очень прошу это исправить
Atoll
24.06.2016 08:27+2Зато теперь можно пользоваться интернет-банком и без авторизации. Но я согласен, для клиентов банка процедуру входа надо упростить.
Thug21
23.06.2016 22:45+2Еще прекраснее был пред-предыдудущий. Там можно было один раз настроить то, что хочешь видеть на главной и частые операции делать в 1 клик после логина.
vikarti
24.06.2016 06:28-1поддерживаю.
надеюсь хотя бы предыдущий будет постоянно поддерживатся?(а лучще бы вернули предпредущий)
Atoll
24.06.2016 08:16+1Избранные и последние платежи доступны после авторизации в разделе «Платежи и переводы». Сейчас платформа — это не только интернет-банк. Но посыл понятен: после авторизации пользователь хочет сразу иметь возможность оплатить без перехода. А что с «Событиями»? Их интересно видеть сразу после логина?
Thug21
24.06.2016 09:59я в банк захожу всего за несколькими операциями:
1. Изменить лимиты по картам
2. Сделать платеж
3. Задать какой то вопрос в поддержку, или заказать справки(что по сути одно и тоже, так как выписки по счету делаются только по запросу)
Соотвественно,
1. Что бы изменить лимиты нужно зайти в карту и потом зайти в лимты и менять, причем часть лимтов в профиле, часть в настройках карты(например почему то платежи в интернет-банке можно править только через карту, а остальные и в профиле и в карте, пока искал долго матерился)
2. Платежи примерно также по удобству, но там мне сложно представить что нужно поменять.
3. Вопрос в поддержку для заказа справок, сейчас появилась кнопка, где можно сразу написать запрос. Как только выкатили новый банк не смог найти пункт «контакты», так как при масштабе 125% он просто исчезал(и сейчас исчезает с экрана, но остаются ...) а поддержка отвечает что работает только при масштабе 100%(прямо как во всеми любимых банках :) )
Если мне нужно рассказать других продуктах, можно же их сделать на странице банка, а не интернет банка. Может приведут примеры, но я не видел, что бы в клиент банк пытались запихнуть информацию обо всех продукты банка. О предложения или новости да, но ипотека, страхование, для бизнеса, это точно нужно в интернет банке физ лица?Atoll
24.06.2016 10:38+1В том то и дело, что это больше не интернет-банк в чистом виде. Платформа поглотила, объединила интернет-банк и портал. Теперь с её развитием все финансовые услуги будут предоставлены в одном месте.
Вас же не смущает, что в офисе банка можно не только заплатить за коммуналку, но и оформить ипотеку?
По разделу Платежи я бы мог что-то изменить к лучшему, но нужны конкретные пожелания.Archon
24.06.2016 12:02+2Вас же не смущает, что в офисе банка можно не только заплатить за коммуналку, но и оформить ипотеку?
Если при этом время ожидания в очереди в кассу повысится в пять раз, я не буду ходить в офис банка, а найду банкомат. Если же «по причине создания единой платформы» в банкомат можно будет попасть, лишь отстояв очередь в кассу, я сменю банк.
TerminusMKB
24.06.2016 11:16Старый банк, главное, работал.
В новом вообще отсутствуют «автоплатежи» в списке избранных в правой панели. В WebDeveloper видно, что список возвращается с сервера, а в интерфейсе всё чисто.
Написал в службу поддержки, объяснил девушке всё по телефону — прислали отписку в стиле КО месяц назад, а воз и ныне там.
Для работы с автоплатежами приходится заходить на старую версию сервиса.Atoll
24.06.2016 11:28Если я правильно понял проблему, то постараюсь помочь.
В панели справа отображаются все платежи. Избранные имеют пометку в виде звезды. Автоматические имеют пометку в виде круга с буквой «А».
Другой вариант увидеть платежи — зайти в раздел «Платежи и переводы». И в самом верху под шапкой мы видим список платежей. Заголовок кликабельный и позволяет выбрать «Последние», «Избранные» или «Автоматические» платежи. Этот выбор кстати не слишком интуитивен, хотим его заменить другим решением.
Если не удастся найти нужные платежи, пишите в личку, обязательно разберемся.TerminusMKB
24.06.2016 11:36> Автоматические имеют пометку в виде круга с буквой «А».
Да, я в курсе, как оно должно быть (служба поддержки и скриншот прислала для образца), но их там нет :)
В разделе «Платежи и переводы», где положено, их тоже нет. Можно добавить новый, а посмотреть созданные ранее (еще в старой версии банка) нельзя.
Ситуация была мной полностью описана и получен отличный ответ: «Информация проверена. На текущий момент, создавать автоплатеж можно сразу по оплате, а можно по уже имеющемся шаблонам. При первом варианте, автоплатеж в личном кабинете не отображается.»
В старом банке было предложение создания автоплатежа (типа банера), которым я и воспользовался. Уже не знаю, первый это вариант, или второй из перечисленных в ответе :)
vdonich
23.06.2016 20:30+1Смотрели ли на Polymer (https://www.polymer-project.org/) и если смотрели, то почему отказались?
PhilNehaev
23.06.2016 20:33Да, смотрели. На сервере нельзя рендерить. На нем есть реально работающие сложные приложения в production?
vdonich
23.06.2016 20:44> На сервере нельзя рендерить.
Ок, но кстати зачем? SEO?
http://stackoverflow.com/questions/33643670/pre-render-polymer-js-on-server-side-for-better-so
Но в целом да, мысль ясна.
> На нем есть реально работающие сложные приложения в production?
Есть куча разного на https://builtwithpolymer.org/, но наверное из больших/сложных — https://gaming.youtube.com/
Кстати, спасибо за инфу и вообще — было любопытно почитать.Apathetic
23.06.2016 20:47>Ок, но кстати зачем? SEO?
SEO + UXvdonich
23.06.2016 20:57Не подумайте что доколупываюсь, но что имеется ввиду под UX? Любопытно.
А то из того, что приходит в голову первым, на сервере рендерят либо для очевидного SEO, либо чтоб не слать данные на клиента по какой-то причине.
Ну или graceful degradation — если вдруг хотим поддерживать сильно старые/медленные браузеры, которым только html и минимум JS и CSS уровнем пониже, хотя ИМХО для таких случаев проще не усложнять а сделать совсем отдельный сайт.Apathetic
23.06.2016 21:51+2То и понимается. Впечатление о скорости загрузки сайта — это ведь тоже UX? Конкретно в данном случае я говорю о том, что информация на сайте становится доступна пользователю намного раньше, чем загружается сайт. Не было бы серверного рендеринга — пришлось бы ждать.
vdonich
23.06.2016 22:41+1Ок, не будем углубляться в дебри терминологии. Speed включать в UX — и ладушки.
Я просто тут оставлю:
https://developers.google.com/speed/pagespeed/insights/?url=Tinkoff.ru
ИМХО рендерить на сервере один из способов, и возможно не самый дешевый. Грузить и рендерить то, что видно в первую очередь было бы не сильно медленней, но это уже на вкус и на цвет.Apathetic
23.06.2016 22:44Скорость загрузки страницы не влияет на пользовательский опыт взаимодействия?
vdonich
23.06.2016 22:56+1Уоу, уоу, полегче.
На пользовательский опыт влияет все — и размер окна, и какая погода и прочее.
Просто обычно (ИМХО) под UX поднимают мета-штуки, типа «меньше больших квадратных кнопок лучше чем больше круглых».
А чисто технические метрики — скорость, размер, отзывчивость, потребление памяти и прочее, идут отдельным пунктом, потому как любой UX-исследователь даже не задумаясь скажет, в какую сторону должны графики смотреть.
ИМХО UX — это «мы две страницы объединили в одну чтоб уменьшить количество кликов для достижения цели», а не «мы два запроса объединили в один, чтоб быстрее было».
Я, вроде, сказал ИМХО?
alek0585
24.06.2016 00:51+1Что-то странно как-то считает этот гуглспид, мне всегда казалось что вконтакте довольно таки удобный и быстрый. А оказывается что только удобный
https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fnew.vk.com%2Fdm&tab=mobile
58 / 100Скорость
98 / 100Удобство для пользователейvdonich
24.06.2016 01:12Эм, кхм, по первому пункту (99/100 Удобство) — вроде как говорили о скорости, не?
По этому параметру, мягко говоря, нужно работать. (47 и 60, мобила и десктоп)
> странно как-то считает этот гуглспид
Да на здоровье, мне не жалко — спрашиваем гугл про page speed и вперед:
http://www.webpagetest.org/result/160623_SH_193K/
12 секунд на полную загрузку и 4 секунды на начало рендера.
Быстро это или нет? Какова роль пре-рендера на сервере? Вопросы, вопросы…
Тот же new.vk.com, кстати, всего лишь в два раза быстрее.alek0585
24.06.2016 23:19Я написал про удобство и скорость. Сравнил с new.vk.com. Заметил, что баллы не сильно отличаются. Отметил это как странное. А вы тут огород городите… в котором бузина, а в Киеве дядька.
Кому-то из разработчиков попадется задача по ускорению загрузки. Всего лишь.
Diverclaim
24.06.2016 01:01+1Страница отрендеренная на сервере (хотя бы частично) быстрее отобразится в браузере клиента.
alek0585
23.06.2016 21:28Сторы. Модели данных, которые содержат UI логику.
Я аж вспотел.
Честно говоря ожидал что-то большее в архитектуре чем это
Может быть я туповатый, но ни картинка, ни описание под ней не дали мне достаточного понимания архитектуры. Хотя вот же она. Или подождите… не совпадают с картинкой тамошние идеи «Stores contain the application state and logic.»
Но стало ясно, что на большом приложении подобная архитектура принесет сложности. Появились проблемы с обогащением моделей данных в браузере. Приходилось писать отдельные контроллеры для серверной и клиентской стороны.
Самое интересное как всегда обошли стороной. Какие проблемы, почему писать отдельные контроллеры, какие еще сложности, как и почему решали… Ну интересно ведь?
Раз уж вы на джаваскрипте бакенд запилили, то Вы наверняка встретились с некоторыми особенностями этого языка при применении его в банковской логике. Тоже интересно. Как складываете числа в джаваскрипте? А база данных какая?
P.S. Хотел оплатить ТСЖ с сайта тинькофф, а там нет моего ТСЖ… И перевода по произвольным реквизитам нет(или не нашел?). В общем по юзабельности пока далеко до альфы, но примерно на уровне сбербанка. Хотя последние готовят тоже свою версию этого онлайн сервиса.
P.P.S. Всё вышенаписанное является субъективным мнениемApathetic
23.06.2016 22:00+1На JS написан только тот бекенд, который крутится на ноде и рендерит UI. На 99% это тот же код, что и на клиенте. Банковской логикой заправляют совсем другие бекенды =)
Razaz
24.06.2016 00:11Я так и не понимаю этих выкрутасов с серверной нодой, что бы рендерить вьюхи на серваке :) Не выгоднее ли рендерить вьюхи чем то пошустрее?
Aingis
24.06.2016 01:15+1А можно конкретнее, чем-то пошустрее это чем? Не забывайте, что JS компилируется на лету, и найти удобный для разработки язык, который работает значимо шустрее очень сложно. А ещё более интересен вопрос, где вы найдёте программистов на этот язык, за какие деньги и в какие сроки они будут разрабатывать.
Razaz
24.06.2016 08:33Уже есть бэкенд на Java/C#. На C# точно есть у Тинькова. Значит есть и разработчики. Программистов они ищут через тот же Luxsoft. Так что для них это не проблема.
Использование ноды там, где все упирается не в IO — странный выбор. Тем более в банке. В принципе я против смешивания фронта и бэка, так как у каждого свои особенности. А всю эту ересь с общим кодом уже прошли на Silverlight и Java Applets много лет назад.
Просто навскидку — вcю node_modules перед релизом проверяете? ;) Или хотя бы чексуммы пакетов храните?
PhilNehaev
24.06.2016 08:41Модули контролируем с помощью npm shrinkwrap.
Фронт и бэк мы не смешиваем, у нас full stack front-end.Razaz
24.06.2016 08:561. Модули храните в репозитории? Аудит кода модулей?
2. Если на сервере надо что-то поставить то это уже затрагивает кучу всего — балансировка, аутентификация, развертывание. При том что профит сомнительный судя по отзыву ниже.
Как вариант — микросервисы+сайты. Набор небольших подгружаемых приложений + ссо для безшовной навигации. Сможете даже фронт как микросервисы обновлять частями.PhilNehaev
24.06.2016 09:051. Есть локальное зеркало и приватный репозиторий NPM на базе Sonatype Nexus. Аудит по необходимости делаем, новые модули добавляем редко.
2. Развертывание сервера с приложением – процесс несложный. Аутентификация происходит на внешних API. Сейчас фронт tinkoff.ru работает с 5 банковскими сервисами.
Diverclaim
24.06.2016 09:10+3Объясните как рендерить вюьхи для SPA приложений на C#/Java? Я сам пишу на C#, но не знаю ни 1 фронтендовой библиотеки которая легко рендерится на сервере без ноды. Я вижу только один вариант — подключить V8 и рендерить через него (то есть по сути тоже самое что nodejs).
Aingis
24.06.2016 09:20+1А почему вы решили, что на Java/C# вьюхи а) будут рендериться быстрее, б) это будет вообще чем-то лучше?
alek0585
24.06.2016 23:35-2Немного пофантазирую… Буду считать, что разработчиков на всех языках завались.
а) Предположим, что js медленнее. Скорее всего просто докупят оперативки и делов-то)) Клиентов не так уж и много, это ж не соц сеть. А разработка гораздо быстрее, веселее и не пахнет бабушкой.
б) На сишарпах и джавах уже столько всего понаписано, а на джаваскрипте — нет. Таким образом, разрабатывая на жаваскрипте можно расширить горизонты в принципе и получить необычный опыт в частности. Так что и этот пункт за жабаскриптом, тем более что результат вроде бы даже и работает.
Итого со счетом 2:0 выигрывает жаваскрипт.
Аплодисменты и фейерверки!
Хотя с другой стороны…
а) в синтетическом тесте N выигрывает C#, значит и рендер будет быстрее
б) в сишарпах и джавах есть суперские классы, интерфейсы и вообще нет таких фич, как потеря this, и прочее. В общем по-человечески сделаны языки, а не на коленке за пару недель.
В итоге выигрывает сишарпы с разгромным счетом 0:2.
Ура!
Тут можно было бы привести аксиому эскобара… Но я не уверен, что она тут 100% подходит. Есть идеи?alek0585
26.06.2016 20:24Жду комментарии минусующих.
Razaz
26.06.2016 20:391. Количество оперативки не ускоряет ваш код :) Его ускоряют эффективные алгоритмы, многопоточность, работа с памятью, низкоуровневые оптимизации и тд.
2. На JS то же много чего понаписано. И?
3. TechEmpower вполне красноречиво отражает положение дел. Уверяю вас, обычный код, который будет на проде будет еще хуже.
4. Суперские класс и тд. делают жизнь JIT или AOT компилятора гораздо проще, позволяя использовать больший спектр оптимизаций.
Что бы понять уровень оптимизаций, которые можно проводить на том же C#, советую посмотреть это шикарное видео:
ASP.NET Core Kestrel: Adventures in building a fast web server — Damian Edwards, David Fowler
Kestrel еще недавно выдавал 700к в секунду. Послле всех оптимизаций — в районе 500kk.alek0585
29.06.2016 22:46-11. Сравните сервер с 512мб памяти и 512гб памяти. Наверняка будет быстрее там где больше.
2. На js не написано столько бекенда как на остальных языках по объективным причинам.
3. Что это вы написали даже не знаю к чему относится. Рендер у с# медленнее или что?
4. Тоже не понял что это: опровержение того, что в джаве есть классы, фабрики, интерфейсы, а в js нет, или что. в огороде бузина, а в киеве дядька.
Razaz
30.06.2016 14:45+11. Вы прикалываетесь?
2. Не пишут, потому что инструмент не подходящий.
3. Там видна разница между производительностью Node и JVM/JAVA. C# там бесполезно смотреть из-за старой реализации на тормозном Mono.
4. Видимо вы не очень понимаете основы. Я надеюсь вы знаете почему 'use strict' положительно сказывается на производительности?
В целом думаю вам стоит начать с основ, что бы хотя бы составить представление чем вы пользуетесь.
Razaz
25.06.2016 15:031. Многопоточный рендеринг.
2. Настроенный JVM даст прикурить 95% платформ по производительности. Особенно если написать эффективный код с низким GC pressure.
3. Можем докинуть F# и тут будет очень интересно поглядеть. В свое время на нем реализовали NDjango.
Лучше-хуже — зависит от потребностей. Но может я не сталкивался и не понимаю всей прелести рендеринга на ноде со стороный сервера. Что такого надо нарисовать в UI на JS, что бы это рендерить на серваке.
Могу предположить, что могут быть случаи когда хочется получить готовый шаблон а не тянуть шаблон и данные на клиента, но не проще тогда взять любой шаблонизатор на текущей инфраструктуре бэкенда, и использовать его для создания вьюх?
Это отчасти ответ-размышоение к вопросу Diverclaim: Прекомпилированный partial-view через RazorEngine чем не вариант?
Aingis
25.06.2016 15:111. Есть PoC?
2. Ничто не мешает писать такой же оптимизированный JS. По затратам даже дешевле.
3. См. п.1
проще тогда взять любой шаблонизатор на текущей инфраструктуре бэкенда
Современные шаблонизаторы сейчас на JS.Razaz
25.06.2016 15:211. asp.net core + razor. Каждый запрос может рендериться параллельно.
2. Не согласен. Вот binary-trees
Это простая адаптация GCBench. В compute JS не особо конкурент JVM/CLR языкам. Он бы мог потягаться на задачках с асинхронным io и минимумом многопоточности.
3. https://github.com/Hill30/NDjango
Можно пример убер быстрого современного шаблонизатора на JS?Aingis
25.06.2016 16:191. М-да, одна из первых ссылок в поиске: вопрос на SO: «Razor in asp.net core is very slow».
http://stackoverflow.com/questions/37725256/razor-in-asp-net-core-is-very-slow
2. Причём тут шаблонизация? Единственный пример, который я там вижу на JS, использует преобразование типов, которое с большой вероятностью вызывает деоптимизацию. Не показательно, я говорил про оптимизированный код.
3. Как и в первом пункте,?где тесты производительности с аналогичными решениями на других языках?
Любой современный шаблонизатор не является узким местом в рендеринге страницы. Как правило, он порядка 100 мс и меньше. Даже, если это в два и более раза медленнее оптимизированного кода на C++, пишется это гораздо проще, быстрее и дешевле. Нужны примеры настоящих сайтов, чтобы говорить о «шустрости».Razaz
25.06.2016 16:411. Это не релиз. Там есть баги с линуксовыми либами как раз по части работы со строками. На WinServer летает. Вопрос был про многопоточность.
2. Покажите как JS уделает Java на этом тесте. Бинарные деревья вполне здоровый бенч. Потому что тот же парсинг может использовать деревья выражений и тд. Я вот вижу что Node медленнее почти в 5 раз.
3. Вы хотели пример парсера на F#?
100мс на шаблонзатор? Это вы так пошутили? :) У меня в проекте сервер обрабатывает запрос за 20-25 мс включая парсинг и это на связке WebApi2 + RazorEngine.
С++ кстати быстрее в 13 раз на обработке бинарных деревьев. Но это ведь все не показатели, и однопотоный сервак будет всегда быстрее многопоточного, с производительным GC, оптимизациями, нормальной моделью памяти и тд и тп.
Предлагаю продолжать эти дискуссии в личке, после того как вы сможете написать оптимально тест на бинарные деревья используя JS и отстав от C++/gcc7 всего в два раза :)
Я выше уже сказал — JS — однопоточный асинхронный код для легких сервисов. В Compute JS в принципе не конкурент.
Дак покажите современный убер быстрый парсер то?Aingis
25.06.2016 17:213. Вы хотели пример парсера на F#?
Нет, я хотел подтверждение утверждению, что рендерить вьюхи заметно выгоднее и пошустрее не на ноде. К сожалению, в ответ есть только общие слова, не подтверждённые даже релевантными тестами. Бремя доказательства лежит на утверждающем, поэтому я и спрашиваю про примеры у вас.
Этот вопрос задавался много раз. Если вы сможете продемонстрировать реалистичный пример, многие будут благодарны. Пока никто такого не показал, зато на JS все отлично пишется.
А ведь это не только вопрос быстродействия. Это вопрос гибкости, как быстро и легко можно вносить изменения. Хардкорный язык вроде C++ этому уже не удовлетворяет. Это вопрос цены, во сколько обойдутся такие программисты. Почему-то бекендщики просят денег гораздо больше фронтендеров. А ещё сразу возникает вопрос взаимодействия между бекендорами и фронтендерами: сколько накладных расходов будет на него уходить и как это скажется на разработке, ведь на каждый чих надо привлекать бекендера.
Увы, на все вопросы обсуждение не дало ответа. Поэтому, действительно, продолжать его нет смысла.Razaz
25.06.2016 17:461. ViewEngine — это парсинг дерева выражений, обработка и форматирование выходных данных(конкатенация строк).
Все эти задачи можно сделать эффективнее на Java, C#, F#. С++ и в самом деле дорого.
Многопоточность — реалистичный пример тут даже считать не надо.
Просят денег не просто так. Потому что это разные области и просто знания языка — мало. Проблема не в языке/платформе, а в том, что вы считаете возможным затыкать дыры в штатном расписании теми, чья специализация отличается. Можно легко переучить с C# на Java или даже на Go или Erlang если есть понимание общих принципов.
Фронт и бэк разделяются и все взаимодействие через апи. Один является потребителем другого, но первый должен строить апи исходя из необходимости второго.
А в целом перфоманс ноды хорошо виден на TechEmpower.
Сейчас вы мне напоминаете тех парней, который тащили серверные языки в браузер. Сейчас тащат браузерные штуки на сервер, с теми же лозунгами. Исход ИМХО будет одинаков. JS шикарен для UI. Но для бэкенда есть более здравые опции(хотя бы тот же Go).
alek0585
29.06.2016 23:09Мне кажется он вообще не понял нас и будто ведет переписку сам с собой игнорируя большую часть сообщений и коверкая смысл. Главный смысл — бекенд должен быстро работать, всё остальное от лукавого. Есть самый быстрый штук под названием urweb-postgres. На языке Ur.
fun equal [ts ::: {Type}] (eqs : $(map eq ts)) (fl : folder ts) (r1 : $ts) (r2 : $ts) : bool = @foldR3 [eq] [ident] [ident] [fn _ => bool] (fn [nm ::_] [t ::_] [r ::_] [[nm] ~ r] isEq x y acc => acc && @eq isEq x y) True fl eqs r1 r2
Мне больше всего вот этот кусочек нравится
[[nm] ~ r]
Atoll
24.06.2016 01:02+1Перевести можно Юридическому лицу в разделе Организациям.
Банковская логика реализована в отдельных системах, работа с которыми идёт через API.alek0585
24.06.2016 23:42Вот спасибо добрый человек, реально так и есть. Смог найти через поиск, а в нативном мобильном клиенте оно еще удобнее. Здорово, что нет комиссии, прям не могу понять почему так — у других же есть.
dmitrmax
01.07.2016 00:56-2Очевидно, чтобы вас привлечь. Не думаю, что такое счастье ещё долго продолжится. Лесенки со вкладами уже почикали.
Iskin
23.06.2016 23:57А что на CSS?
Какие плагины PostCSS используете, кроме Автопрефиксера?PhilNehaev
24.06.2016 08:29Используем LESS, кроме автопрефиксера есть CSSO.
Iskin
24.06.2016 11:20А чем линтите CSS и инлайните картинки?
PhilNehaev
24.06.2016 11:31Инлайнит Webpack, линтинга для CSS нет.
Iskin
24.06.2016 13:43Я просто спрашиваю, так как обычно Автопрефиксер усиливают линтером Stylelint (у Фейсбука и ГитХаба он есть) и postcss-assets или postcss-inline-svg (инлайн SVG со сменой цвета). Но понимаю, что вы пока решили сосредоточится на JS.
ekubyshin
26.06.2016 10:47-1«воу воу воу, помедленнее, я записываю...» — послышалось, где-то в офисе ткс
Ronnie_Gardocki
24.06.2016 06:16+2Вы вообще проверяли как работает ваш новый чудосайт на плохом интернете или у людей из других стран? У меня до России RTT 300-400мс. В итоге видимо из-за того, что вы юзаете изоморфный рендеринг, при навигации по сайту у меня получается вот такое вот издевательство:
10/10 UX Would Visit AgainPhilNehaev
24.06.2016 08:43Это не из-за изоморфного рендера. После первоначальной загрузки сайт работает как одностраничное приложение, без запроса HTML с сервера. С проблемой разберемся.
sintez
24.06.2016 15:48Извиняюсь, что вопрос не по теме поста. Подскажите, пожалуйста, а каким инструментом вы создали такую гифку?
Ronnie_Gardocki
24.06.2016 16:18+1На винде — ScreenToGif 2
На маке то ли licecap, то ли какая-та другая прога, я уже забыл.
imater
24.06.2016 07:08+5Спасибо, что выложили обзор своих выстраданных решений, пока другие компании сидят и тихо скрывают свои военные тайны.
Anderson
24.06.2016 08:34Если все проекты на единой платформе, то почему страхование требует отдельной регистрации? Или данный проект все-таки отдельно?
dmitrmax
28.06.2016 08:191) Потому что СК должна быть отдельной от банка компанией.
2) Чтобы не позорить банк свой тупой работой. Говорю как клиент обоих ресурсов.
Archon
24.06.2016 08:58+11. Вижу, появление кнопки «Войти» через 10 секунд вы исправили. Молодцы. Но уберите уже из-под неё иконку оплаты коммуналки, незанятого места на экране вагон, а вы её загнали прямо под самую нужную кнопку главной страницы.
2. Жутко. Невероятно. Медленно. Старый банк летал на любых устройствах, этот же тупит на любом интернет-соединении, включая проводное. Однажды попробовал зайти в новый банк с мобильника, пожалел об этом сразу, т. к. в этом храме имени Вечного Жёлтого Прогрессбара не удалось сделать вообще ничего.
3. Где сумма задолженности по выписке, самая нужная цифра кредитного счёта? Как я, тупой пользователь, должен догадаться, что она спрятана под кнопку «Пополнить», если раньше она всегда разворачивалась по клику на сумму общей задолженности?
4. Если шариться по банку, не разворачивая браузер на весь экран, всплывашки заезжают под правое меню, в слове «дополнительную» буква «ю» улетает на следующую строку. Тестируйте на всех вариантах ширины, а не только типовых.
5. По виду контролов вообще непонятно, что это. Поля ввода ужасны. Если не знать, что при смене пароля надо ввести пароль дважды, об этом хрен догадаешься, потому что второе поле выглядит как надпись.
6. Размер элементов настолько невменяемый, что даже простейшие операции теперь требуют скролла. Раньше операции в интернете (пожалуй, самая часто дёргаемая галочка) включались и выключались легко и просто, теперь их ещё и поискать надо, потому что они где-то внизу страницы настроек, под Офигенно Важными Услугами «смс-банк» и «страхование долга».
Короче, ни одного плюса в новом банке мной не замечено. А вот минусов — хоть отбавляй.dmitrmax
24.06.2016 15:01+1> Короче, ни одного плюса в новом банке мной не замечено. А вот минусов — хоть отбавляй.
Зато технофильству раздолье )
ITweb
24.06.2016 09:42Блин, сделайте текстбоксы с логином и паролем, чтобы были видны одновременно, а не по очереди, неудобно получается работать с хранилками паролей.
dmitry_dvm
24.06.2016 10:29+1А мне нынешний вариант понравился. Анимации подтормаживают в эдже на ноуте с i7, но зато повторить предыдущий платеж стало очень легко и удобно. Пароли от банка в браузере не храню, поэтому проблема с автозаполнением для меня не актуальна. Анимации бы правда пошустрее сделать.
Кстати, на люмии 1520 тоже хорошо работает.
vaeum
24.06.2016 11:04+1Привет, новый дизайн мне нравиться, только есть замечание, можно при наведении на телефон в футере сделать курсор в виде руки, а то не понятно можно кликнуть или нет. Спасибо.
uniqm
24.06.2016 11:06+2По оценке интерфейса (раз уж стали сравнивать новую и старую версию), оставлю здесь очень простые, но вполне рабочие критерии сравнения:
0. Интерфейс должен решать задачу пользователя. Если не прошли этот пункт, дальше можно не оценивать.
1. Скорость, с которой решается задача пользователем. Количество кликов, капч, окон с вопросами и тд.
2. Количество ошибок на пути решения. Расположенные рядом кнопки удалить и запостить, вводящие в заблуждение подписи к полям и тд.
3. Скорость обучения пользователя работе с интерфейсом. Сначала привычка: стандартные контролы и подходы повышают скорость обучения. Логичные и заточенные под задачу клиента интфейсы так же повышают скорость.
4. Общая удовлетворенность пользователя от интерфейса. Вопрос привычки, ощущений и тд.
Впервые увидел эти(или подобные) критерии, кажется, у В.Головача. И с тех пор использую в работе и жизни. Без лишнего холивара прохожусь по критериям, сравниваю принимаю решение. Пункты 1-4 могут рассматриваться в любом порядке.
Scf
24.06.2016 12:29+1В плане UX идеалом я считаю вконтакте:
- Весь рендер выполняется на сервере, динамика реализована путем POST запросов, которые возвращают HTML, вставляемый в нужное место.
- Никаких библиотек, всё написано на чистом яваскрипте.
- Никакой минимизации и объединения ресурсов, система навигации умеет подгружать скрипты и стили динамически по необходимости
- Серверная часть написана на С, что обеспечивает минимальное время отклика
- поддерживается как навигация через ajax, так и полностью серверный рендер. Т.е. при навигации с сервера подгружаются куски HTML в нужные места DOM, но если обновить страницу, то она придет сразу целиком. Идеальное решение для SEO.
Из минусов:
- клиентский яваскрипт представляет из себя жуткий спагетти, написанный без внимания к каким-либо стандартам и даже без use strict
- серверная часть тоже должна быть весьма, весьма сложна...
NINeOneone
24.06.2016 15:30Красиво. Технологично. Неюзабельно.
Ок, надо вам маркетплейс на исходной странице — да пожалуйста. Но сделайте просто интернет-банк на другой. Не надо эти свистелки и перделки тем, кто и так ваш клиент.
Мы знаем о них. Правда. Знаем.
Нам всего лишь надо воспользоваться тем, за что уже заплатили, а не смотреть анимашки на мелком экране смарта с edge-интернетом.
gusakovdmitry
25.06.2016 09:26+3я старый клиент, и считаю этот банк лучшим, но блин каждый интернет банк хуже предыдущего, а этот меня заставляет страдать. я знаю, вы самые крутые и сможете победить эти тормоза и глюки, буду держать за вас пальчики, и спасибо, за такую открытость, думаю такие отзывы как мой откроют вам глаза и помогут в результате, сделать, что бы не сбоило и летало.
ekubyshin
26.06.2016 10:43+1молодцы! получилось неплохо.
Но где инновации? что делают все эти 30 человек на фронте? Это статья о том как вы умеете пользоваться stackoverflow, запускать webpack и рендерить react на сервере?
Если вкратце, то весь этот текст можно было заменить на одно предложение: «мы почитали документацию реакта, поизучали npm на наличие пакетов и научились рендерить react на сервере под express.»
Есть, чем можно поделиться с сообществом? кодом? какой-то новой либой? новым подходом? все, что тут описано не несет никакой инновации, просто переиспользование готового.
Все таки в команде 30 фронтендеров, можно уже начать что-то изобретать, как это делают другие разработчики (airbnb, yandex (bem и не только) и др.), а не просто использовать готовое. Например, тот же backbone или redux, разработали не 30 человек, а всего лишь один.
А что сделали вы?
ekubyshin
26.06.2016 10:57кстати, если уж убиваться, по инновациям и новомодным подходом, то почему вы все таки выбрали express, а не более современный и перспективный koa? или допустим hapi?
почему все таки не webcomponents, вроде это еще щас моднее и прогрессивнее?
dmitrmax
28.06.2016 08:22Скажите пожалуйста, каким образом у вас сделан чат с поддержкой, что он упорно не хочет работать в браузере из под Linux и при этом, если я случайно нажал на него, то это окошко с вращающимся кругом уже не закрыть?
PhilNehaev
28.06.2016 08:42Отправьте на fb@tinkoff.ru скриншот и подробное описание проблемы (браузер, на какой странице, авторизованы или нет).
dmitrmax
01.07.2016 00:43Уже отправлял. Ещё раз, конечно, отправил, но чё-то не верю что вы запаритесь из-за линуксоидов. В принципе интересен не сам чат, а то как вы умудрились сделать так, чтобы он работал в зависимости от платформы )
itsoft
28.06.2016 13:02-2Когда API будет? Фронтэенд нам ваш нафиг не нужен, а вот выписки импортировать без участия человека нужно до зарезу. Сколько можно мартышкиным трудом заниматься.
xorax
28.06.2016 13:24Почитал ругань на размер и тормоза. Моя догадка по поводу виновника: ES6 + Babel. Скажите, зачем вы решили писать на ES6, если оно еще такое сырое и порождающее столько проблем? Могу предположить, что год назад этот выбор казался логичным, так как вы ожидали, что за год поддержка ES6 сильно улучшится. Но этого не произошло. Если так, что что бы вы выбрали сейчас?
PhilNehaev
28.06.2016 14:39Размер складывается не из-за ES6 и Babel. Это вопрос сборки модулей. Сейчас выбрали бы тоже ES6.
Scf
28.06.2016 15:10Это всё библиотеки. react + диспатчер + underscorejs какой-нибудь + прочие плюшки — вот скомпилированный js и вылез за мегабайт.
ktulhu
28.06.2016 18:06Любопытно, когда люди обсуждают привлекательность «свистелок и перделок», а я уже неделю не могу посмотреть выписку по кредитке (пишут, что «нет операций»), причем по допкредитке все операции видны. Вчера хотел заплатить взносы в ПФР. А вот фиг вам! КБК должен быть 20 символов, ввожу верный КБК (руками, копи-пастой, чертом-в-ступе) — нет, неверный у вас КБК, он должен быть 20 символов, а у вас 20.
По мне так пусть на голом хтмл, но работает. А оно не работает. И это только два больших косяка.
Atoll
29.06.2016 10:47Посмотрел регулярку на это поле: ^(0|\d{20})$
И ваше значение проходит проверку.
Можете прислать в личку данные платежа, кроме личных? Я проверю платеж.ktulhu
29.06.2016 14:03Вам не нужны данные платежа. Просто введите 39210202140061100160 в поле КБК — этого достаточно.
Atoll
29.06.2016 15:30Дело в том, что я пробовал. На своем боевом аккаунте. Заполнил только поле КБК, нажал оплатить, поле КБК валидно.
Поэтому и пытаюсь уточнить детали.ktulhu
29.06.2016 18:56Я делаю тоже самое. Могу сбросить видео (уже сделал) через службу поддержки. На всяк пожарный, проводку пытаюсь сделать здесь — https://www.tinkoff.ru/payments/legal/transfer-taxes/.
Atoll
30.06.2016 12:43+1Теперь понятно. Для такого перевода следовало выбрать перевод «Организациям / В бюджетные организации»: https://www.tinkoff.ru/payments/legal/transfer-nontaxes/
Спасибо за выявление проблемы. Мы сделаем предупреждение о том, что поле КБК не подходит для данного вида перевода. И в дальнейшем будем работать над объединением таких переводов в один универсальный.
wuoten
28.06.2016 20:04Абсолютно на всех сайтах использую новые версии, если появляется даже бета, но у вас новая версия просто кошмар. Впервые хожу по ссылкам на старую версию. Что это за мода везде адаптировать под мобайл? Такое ощущение, что сайт делали для слабовидящих. Слониный шрифт, куча пустого места, чтобы что-то найти нужно 10 метров проскролить. В общем, надеюсь, старую версию не прикроют.
SSar
28.06.2016 22:27Полностью согласен с коллегами выше, ваш очередной новый Интернет-Банк 2016 просто эпикфейл и при этом еще хватает… трезвонить везде какие мы молодцы, что каждые полгода-год меняем интерфейс на менее удобный для пользователя.
Вы видимо не понимаете, что пользователь в большинстве своем консервативен, и что даже небольшие изменения пагубно сказываются на понимании интерфейса, а уж Такие… ну да пофиг с этим саппорт разбираться будет (с непониманием клиентов), Мавр свое дело сделал.
Такое впечатление, что разрабатывался интерфейс под локальную гигабитную сеть и для мониторов разрешением 4K не меньше, а на остальных просто… забили, ну как ваш шеф любит говорит… на нищебродов.
Вы вообще в курсе, что во многих конторах, особенно не с миллиардной выручкой или из-за жесткого бюджета не то что 4K мониторы до сих пор в офисе на 720p сидим и ваш мегадизайн тупо не помещается в него да и грузится в браузерах неахти (причина выше уже описана).
Резюмируя, выражаю респект за пополнение лексикона с перечнем крутых буржуйских терминов, но не более.
Jeditobe
29.06.2016 14:57Банк у вас замечательный, но новый интерфейс абсолютно оивратительный. Пользуюсь старым и друзей всех на него перевел.
kamushken
30.06.2016 15:33-1(очередной коммент про UX-погрешности в очередной новой версии интерфейса Тинькофф банка)
ждём следующих версий интерфейса.
нам нравится раз в квартал переучиваться пользоваться вашим интерфейсом!
подпись: ваши клиенты(
dmitrmax
01.07.2016 01:01Зашел выбрать новые категории повышенного кэшбэк. Искал интуитивно в действиях по карте (вроде в старом ИБ было там). Не нашел, облазил всё. Полез в рассылке искать письмо, чтобы пойти по ссылке. А оказывается это в «Бонусы» засунули. С какой стати? Ну ладно.
Захожу туда и мне на полном серьезе предлагают выбрать категории для апреля, мая и июня. Во-первых, уже первое июля, во-вторых, эти категории я уже давно выбрал и изменить их нельзя (вроде как), зачем предлагать ещё раз? Едва заметил, что есть две «как бы вкладки», обе с одинаковым названием «Активные категории», переключился на вторую — слава яйцам, там новые категории.
Ребята, вы где такое обновление интуиции скачали?
dmitrmax
01.07.2016 01:04Ещё один вопрос. Не про ИБ, а про мобильный клиент. У вас нет в планах сделать возможность эмитировать карту для NFC в том случае, если это доп. карта? Понятное дело речь про смартфон не владельца счёта, а владельца доп.карты.
hose314
А что со сторами, почему не redux? Спасибо.
PhilNehaev
Год назад redux не был таким популярным. Сейчас мы не испытываем необходимости в нем, чистый Flux нас устраивает.
Сторы представляют из себя обычные классы, наследуют EventEmitter.