Если мы рассматриваем ситуацию, когда бэк только отдаёт API, а фронт это SPA, самое очевидное — сайт перестаёт работать без JS, пользователь вынужден разрешать на своём устройстве remote code execution и подвергать себя в худшем случае риску безопасности (дыры в песочницах и сторонние каналы никто не отменял), в лучшем случае майнингу бетховенов (утрирую, но суть вы поняли)
Так как бэк вряд ли станет делать эндпоинт, который отдаст всю нужную странице информацию за раз — фронт вслед за хотелками фронтендеров станет отправлять стопицот ajax-запросов на каждый чих: тот же Хабр при открытии комментов отправляет 7 ajax-запросов, хотя теоретически ничего не мешало бы уложиться в один запрос и сэкономить время (и трафик, потому что всё вместе наверняка сожмётся лучше). И нет, отмазки наподобие «можно сперва быстро загрузить и показать основной контент страницы, а уже потом подгружать менее важные части» здесь не прокатят: во-первых, загрузка и запуск JS сами по себе потратят сколько-то времени, а во-вторых, браузеры умеют показывать страницу ещё в процессе загрузки, так что пользователь может сразу начать читать основной контент вообще без использования JS и даже не дожидаясь окончания загрузки этого основного контента — это ВСЕГДА будет быстрее чем рендеринг контента через JS
Если бэк не озаботится чем-то вроде GraphQL — он будет отдавать в том числе ненужную информацию и впустую тратить трафик: тот же Хабр при открытии комментов зачем-то отдаёт полные тексты постов, которые при этом никогда не отображаются
Браузер начинает выполнять двойную работу: сперва он тратит энергию на парсинг json, а потом на преобразование этого json в DOM по замудрёным алгоритмам — это ж какой углеродный след получается, куда только экоактивисты смотрят? А парсинг html никуда не девается, потому что регидратация и потому что на том же Хабре тексты постов всё равно приходят в html (и при этом завёрнутые в json, ага). А устройства у пользователей далеко не новые, и всё это дело успешно тормозит. Всё это можно было бы не только быстро сделать на высокопроизводительном бэке (особенно если взять столь же высокопроизводительный язык, но Rust это же экономически невыгодно ага), но и закэшировать на том же бэке (хотя бы для отдельных частных случаев) и не тратить миллионы часов и ватт пользовательских устройств на бессмысленное повторение одних и тех же действий
А уж как бесит криво сделанная гидратация на некоторых сайтах: сперва за несколько секунд подгружается обычный html, я начинаю его читать, а потом он ВНЕЗАПНО пропадает и заменяется на экран загрузки, чтобы потратить ещё несколько секунд и процентов заряда батареи на преобразование json в тот же самый html! Хочется бить ногами за такое
Ну и ещё не совсем про техническую часть, а скорее про дисциплину — часто фронт оказывается избалован одностраничностью и начинает плевать на семантику. Так как ничего не заставляет использовать родные браузерные механизмы — разработчики фронта начинают велосипедить свои собственные механизмы, которые работают хуже чем родные браузерные и приводят к появлению проблем, которых изначально не появилось бы, если бы фронт не выпендривался. Зачем делать нормальную форму с нормальной кнопкой отправки, если можно просто повесить onclick на div? Пофиг, что форма перестала отправляться по энтеру, будет много жалоб — добавим onkeypress. Зачем делать ссылки через тег <a>, если можно просто повесить onclick на подчёркнутый span? Ну и что, что Ctrl+клик перестал открывать псевдоссылку в новой вкладке, этим пользуются всего 0.00001% пользователей, добавлять обработку event.ctrlKey экономически невыгодно, использовать нормальный <a> ещё более невыгодно
На многостраничных сайтах тоже никто не запрещает использовать JS и сделать богатый UX, это не взаимоисключающие вещи
такой подход позволил разделить компетенции разработчиков на frontend и backend части и разработку их отдельно друг от друга
И ничего хорошего в этом нет, по множеству разных причин это лишь приводит к ухудшению качества сайтов
фронты могут быть web, mobile, smart tv и прочее
Иронично, что в реальности всё происходит наоборот — все всё запихивают в веб, и многие «нативные» приложения являются всего лишь обёртками над webview
Но независимо от этого — ничто не мешает использовать один и тот же api для многостраничного сайта и для нативного приложения, лишь бы было желание нормально организовать структуру бэкенда
Примерно любой сайт до ~2010-го — в те древние времена ещё считалось хорошим тоном обеспечивать работоспособность сайта без JS
Можно глянуть какие-нибудь выжившие старые форумы на «классических» движках вроде PhpBB или MyBB — без JS отвалится какая-нибудь мелочь вроде кнопочек форматирования в редакторе, но вся основная функциональность останется рабочей
Жаль, что нынешнее поколение веб-разработчиков разучилось так делать, вон комментатор ниже даже не представляет как можно жить без API
Лично для меня любая декларативность наоборот повышает сложность, так как приходится тратить дополнительные усилия на то, чтобы понять, как же оно там реально работает внутри. А с императивностью всё просто сразу на виду без лишних абстракций
однострочный миксин в определении класса все же проще
Нет, явный вызов конкретной функции всегда проще и понятнее, чем прятать всё за миксином, который переопределяет непонятно что непонятно в каком порядке (я не желаю гулять по всей иерархии классов, чтобы выяснить, да что же блин происходит в моём коде, и поэтому не использую CBV в своих проектах, кстати удачи с ромбовидным наследованием)
Но код, написанный автором, мне тоже не нравится: автор зачем-то использовал класс, продолбал аннотации типов, разделил фактически идентичные get и post и из-за этого оказался вынужден обмазаться функциями-хелперами, от которых можно было бы спокойно избавиться:
def comment_form(request: HttpRequest, post_id: int) -> HttpResponse:
post = get_object_or_404(Post, pk=post_id)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect(post)
else:
form = CommentForm()
return render(request, "form.html", {"post": post, "form": form})
Это паттерн, который я использую в своих проектах и который даже совпадает с тем, что написано в документации Django — код не только в два раза короче, но и, по моему субъективному мнению, НАМНОГО проще для понимания и дальнейшей поддержки. Не надо скакать по иерархии классов, не надо даже скакать по функциям — всё на виду и максимально очевидно
Все базовые параметры лежат готовые в репозитории/шаблоне, а для локального окружения он скопировал local_settings.example.py в local_settings.py
Потом неделю правил INSTALLED_APPS.
Он лежит готовый в репозитории/шаблоне
Потом два дня воевал с ALLOWED_HOSTS.
В вышеупомянутом local_settings.example.py уже прописано всё готовое для локалхоста
Потом переписывал DATABASES под дев, тест и прод.
Тест лежит готовый в репозитории/шаблоне, прод лежит готовый у админов (и простой разработчик не должен иметь доступ к проду), дев лежит готовый в local_settings.example.py, разве что пароль свой вписать если он есть
Потом поймал баг, потому что написал DEBUG="yes".
Не поймал, потому что django-stubs сразу подсветил ошибку
Потом завёл .env и сказал, что «всё по best practices».
Не завёл, потому что с local_settings.py тоже живётся хорошо
если мы дорабатываем существующий проект: минута на git clone, минута на создание local_settings.py, ну может ещё пара минут на apt install mysql — $1.25 на всё про всё
если мы делаем новый проект: просто скопировать всё вышеупомянутое из любого существующего проекта или сгенерировать из заранее подготовленного шаблона — пусть условно ещё $1.25
Мы все, включая автора оригинала, прекрасно понимаем, зачем defer нужен, но это не отменяет того, что сам факт существования defer является недоработкой языка
А ещё можно сделать так, чтобы сетевой коннект закрывался автоматически вообще без всяких Close, представляете? Зачем напрягать программиста ручным вызовом Close, если можно не напрягать?
Или вы не отключили уведомления (а я определённо не хочу получать по уведомлению на абсолютно каждое блин сообщение во флудилке, но определённо хочу видеть число сообщений в этой же флудилке), или у нас два принципиально разных neochat'а
Для «ладно потом отвечу» в любом приличном мессенджере есть функция «Отметить как непрочитанное», достаточно иметь хотя бы капельку дисциплинированности
Справедливости ради с того же pypi.org можно скачать tar.gz, в котором «всего» пара сотен файлов
Много букв
Если мы рассматриваем ситуацию, когда бэк только отдаёт API, а фронт это SPA, самое очевидное — сайт перестаёт работать без JS, пользователь вынужден разрешать на своём устройстве remote code execution и подвергать себя в худшем случае риску безопасности (дыры в песочницах и сторонние каналы никто не отменял), в лучшем случае майнингу бетховенов (утрирую, но суть вы поняли)
Так как бэк вряд ли станет делать эндпоинт, который отдаст всю нужную странице информацию за раз — фронт вслед за хотелками фронтендеров станет отправлять стопицот ajax-запросов на каждый чих: тот же Хабр при открытии комментов отправляет 7 ajax-запросов, хотя теоретически ничего не мешало бы уложиться в один запрос и сэкономить время (и трафик, потому что всё вместе наверняка сожмётся лучше). И нет, отмазки наподобие «можно сперва быстро загрузить и показать основной контент страницы, а уже потом подгружать менее важные части» здесь не прокатят: во-первых, загрузка и запуск JS сами по себе потратят сколько-то времени, а во-вторых, браузеры умеют показывать страницу ещё в процессе загрузки, так что пользователь может сразу начать читать основной контент вообще без использования JS и даже не дожидаясь окончания загрузки этого основного контента — это ВСЕГДА будет быстрее чем рендеринг контента через JS
Если бэк не озаботится чем-то вроде GraphQL — он будет отдавать в том числе ненужную информацию и впустую тратить трафик: тот же Хабр при открытии комментов зачем-то отдаёт полные тексты постов, которые при этом никогда не отображаются
Браузер начинает выполнять двойную работу: сперва он тратит энергию на парсинг json, а потом на преобразование этого json в DOM по замудрёным алгоритмам — это ж какой углеродный след получается, куда только экоактивисты смотрят? А парсинг html никуда не девается, потому что регидратация и потому что на том же Хабре тексты постов всё равно приходят в html (и при этом завёрнутые в json, ага). А устройства у пользователей далеко не новые, и всё это дело успешно тормозит. Всё это можно было бы не только быстро сделать на высокопроизводительном бэке (особенно если взять столь же высокопроизводительный язык, но Rust это же экономически невыгодно ага), но и закэшировать на том же бэке (хотя бы для отдельных частных случаев) и не тратить миллионы часов и ватт пользовательских устройств на бессмысленное повторение одних и тех же действий
А уж как бесит криво сделанная гидратация на некоторых сайтах: сперва за несколько секунд подгружается обычный html, я начинаю его читать, а потом он ВНЕЗАПНО пропадает и заменяется на экран загрузки, чтобы потратить ещё несколько секунд и процентов заряда батареи на преобразование json в тот же самый html! Хочется бить ногами за такое
Ну и ещё не совсем про техническую часть, а скорее про дисциплину — часто фронт оказывается избалован одностраничностью и начинает плевать на семантику. Так как ничего не заставляет использовать родные браузерные механизмы — разработчики фронта начинают велосипедить свои собственные механизмы, которые работают хуже чем родные браузерные и приводят к появлению проблем, которых изначально не появилось бы, если бы фронт не выпендривался. Зачем делать нормальную форму с нормальной кнопкой отправки, если можно просто повесить onclick на div? Пофиг, что форма перестала отправляться по энтеру, будет много жалоб — добавим onkeypress. Зачем делать ссылки через тег <a>, если можно просто повесить onclick на подчёркнутый span? Ну и что, что Ctrl+клик перестал открывать псевдоссылку в новой вкладке, этим пользуются всего 0.00001% пользователей, добавлять обработку event.ctrlKey экономически невыгодно, использовать нормальный <a> ещё более невыгодно
Опять эта пачка заезженных мифов)
На многостраничных сайтах тоже никто не запрещает использовать JS и сделать богатый UX, это не взаимоисключающие вещи
И ничего хорошего в этом нет, по множеству разных причин это лишь приводит к ухудшению качества сайтов
Иронично, что в реальности всё происходит наоборот — все всё запихивают в веб, и многие «нативные» приложения являются всего лишь обёртками над webview
Но независимо от этого — ничто не мешает использовать один и тот же api для многостраничного сайта и для нативного приложения, лишь бы было желание нормально организовать структуру бэкенда
Можно отметить, что этот файл появился в 2012-м, а раньше как-то жили и без него)
Примерно любой сайт до ~2010-го — в те древние времена ещё считалось хорошим тоном обеспечивать работоспособность сайта без JS
Можно глянуть какие-нибудь выжившие старые форумы на «классических» движках вроде PhpBB или MyBB — без JS отвалится какая-нибудь мелочь вроде кнопочек форматирования в редакторе, но вся основная функциональность останется рабочей
Жаль, что нынешнее поколение веб-разработчиков разучилось так делать, вон комментатор ниже даже не представляет как можно жить без API
Лично для меня любая декларативность наоборот повышает сложность, так как приходится тратить дополнительные усилия на то, чтобы понять, как же оно там реально работает внутри. А с императивностью всё просто сразу на виду без лишних абстракций
Нет, явный вызов конкретной функции всегда проще и понятнее, чем прятать всё за миксином, который переопределяет непонятно что непонятно в каком порядке (я не желаю гулять по всей иерархии классов, чтобы выяснить, да что же блин происходит в моём коде, и поэтому не использую CBV в своих проектах, кстати удачи с ромбовидным наследованием)
Но код, написанный автором, мне тоже не нравится: автор зачем-то использовал класс, продолбал аннотации типов, разделил фактически идентичные get и post и из-за этого оказался вынужден обмазаться функциями-хелперами, от которых можно было бы спокойно избавиться:
Это паттерн, который я использую в своих проектах и который даже совпадает с тем, что написано в документации Django — код не только в два раза короче, но и, по моему субъективному мнению, НАМНОГО проще для понимания и дальнейшей поддержки. Не надо скакать по иерархии классов, не надо даже скакать по функциям — всё на виду и максимально очевидно
Все базовые параметры лежат готовые в репозитории/шаблоне, а для локального окружения он скопировал
local_settings.example.py
вlocal_settings.py
Он лежит готовый в репозитории/шаблоне
В вышеупомянутом
local_settings.example.py
уже прописано всё готовое для локалхостаТест лежит готовый в репозитории/шаблоне, прод лежит готовый у админов (и простой разработчик не должен иметь доступ к проду), дев лежит готовый в
local_settings.example.py
, разве что пароль свой вписать если он естьНе поймал, потому что django-stubs сразу подсветил ошибку
Не завёл, потому что с
local_settings.py
тоже живётся хорошоПодробнее: Как сделать несколько конфигураций (settings.py) для проекта Django?
Итого:
если мы дорабатываем существующий проект: минута на git clone, минута на создание
local_settings.py
, ну может ещё пара минут на apt install mysql — $1.25 на всё про всёесли мы делаем новый проект: просто скопировать всё вышеупомянутое из любого существующего проекта или сгенерировать из заранее подготовленного шаблона — пусть условно ещё $1.25
Продать django-cfg для меня у вас не получилось
Мы все, включая автора оригинала, прекрасно понимаем, зачем defer нужен, но это не отменяет того, что сам факт существования defer является недоработкой языка
GIL не предотвращает вклинивание,
+=
не «атомарная» операцияНакостылировал через greenlet
Мой внутренний перфекционист отказывается считать это поддержкой asyncio
Но в любом случае непонятно, зачем считать размер промежуточных артефактов отладочной сборки
Линуксовый бинарник LightCycle, собранный с профилем release и strip="symbols", весит 10 МБ (всё ещё больше чем 7 КБ, но всё-таки)
Я чёт не понял, это к чему? Хелловорлд на wgpu подтягивает 117 крейтов, весит 1.1 гигабайта и компилируется примерно те же полминуты
Звонки не с кем тестить 🙃
А найти/поставить сервер с нужным модулем не проблема
Вы пропустили последние десять лет развития джаббера, там уже есть и server side history, и работающая передача файлов
Замечаем, что картинка какая-то подозрительно шумная, достаём младшие биты, видим S6KB и идём за паяльником
Хотя в общем-то даже замечать не надо, можно автоматизировать и просканировать вообще все картинки
А ещё можно сделать так, чтобы сетевой коннект закрывался автоматически вообще без всяких Close, представляете? Зачем напрягать программиста ручным вызовом Close, если можно не напрягать?
Если вы не обманываете, то очень странно
Или вы не отключили уведомления (а я определённо не хочу получать по уведомлению на абсолютно каждое блин сообщение во флудилке, но определённо хочу видеть число сообщений в этой же флудилке), или у нас два принципиально разных neochat'а
А по существу никто ничего толком не опровергнул до сих пор
Весь Go сплошной детсад, пропустить и забыть 🌚
Для «ладно потом отвечу» в любом приличном мессенджере есть функция «Отметить как непрочитанное», достаточно иметь хотя бы капельку дисциплинированности