Pull to refresh

Comments 473

Насчёт браузера не знаю, но в качестве MSHTML движка было бы интересно увидеть. :)
Дело хорошее. В конце концов, nginx сожрал apache.
Только польза от учитывания ошибок, ИМХО, сомнительная:
1. Стимулирует писать некрасиво: и так сойдёт;
2. Заставляет тратить время на поддержку возможности писать некрасиво, потенциально порождая баги;
3. Этакая криво написанная страница, простимулированная таким парсером, ещё и сломает кучу других парсеров, написанных строже;
Яндекс, Гугл даже в простом html стараются придерживаться XML, видимо, именно по причине 3.
Игнорирование и исправление ошибок HTML было начиная с первых браузеров, и некоторые способы исправления даже задокументированы в стандартах, если я не путаю. Что касается тега <p>, стандарт разрешает не ставить закрывающий тег.
Погодите. Например парсер от Google толерантен к ошибкам в html.
UFO just landed and posted this here
UFO just landed and posted this here
Я предлагаю изменить стандарт. Поэтому и подчеркнул ИМХО :) по тексту это всё понятно: автор сначала ссылается на стандарт, а потом раскрывает. Значит, такой стандарт. И это печально…
UFO just landed and posted this here
Но если вам понадобится сверстать форматированную html-страницу с двумя картинками и парой абзацев текста — вам зачем это всё?

Насколько это типичный кейс?
Да, раньше подругому не было.
Но сейчас страницы так никто не делает и сделать так ничего толкового нельзя.
Дольше всех продержался IoT, но даже там уже не актуально и практически никто уже не верстает странички в блокноте.
UFO just landed and posted this here
Уже пробовали, был такой XHTML больше 10 лет назад, который не прижился именно из-за его строгости.
Если хочется строгого четкого стандарта — всегда можно использовать XML.

И самый важный момент, если парсер браузера не будет поддерживать не строгий стандарт, на котором написаны уже миллионы сайтов, причем еще с 90-х, то зачем такой браузер, который не покажет большую часть веба?

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

UFO just landed and posted this here
Судя по всему вы «в теме» про багованные ХТМЛ.
Существует стандарт по парсингу и исправлению ХТМЛа с ошибками?

Лет 10 назад я написал свой парсер хтмл и рендер машину, и тогда с обработкой ошибками был полный аут, все пытались делать как у микрософта, но он никому ничего не рассказывал и поэтому у всех был свой велосипед.

С тех пор что-то изменилось?

Всё описано в спецификации. Там есть чудный алгоритм adoption agency algorithm, а так же reconstruct the active formatting elements.


Смотрим как оно работает в описании.


Следует помнить, что сайт заблокирован, под руку попали когда телеграмм блокировали.

Спасибо. Но я чуть про другие баги.

Есть ли например принцип, по которому «живые» тэги, попавшие например в незакрытый !--, «вытаскиваются» и обрабатываются.

Или ХТМЛ в котором 2+ BODY каждый со своими парметрами; style где то по середине и тому подобная хрень.

IE это все обрабатывает, но как именно я так и не понял.
который тащится и порождает проблемы, усложняющие разработки и поддержку веб-движков

Есть бенчмарки которые говорят, что парсинг HTML это самое тяжелое место?

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

Хотите изменить — изменяйте. Есть же комитет по стандартизации. А делать движок не по стандарту — это плохо. С ИЕ уже проходили.

UFO just landed and posted this here
Так ведь в HTML5 это пофиксили. Там можно не указывать слеш перед закрытием. Но да, если слеш есть его игнорят.
UFO just landed and posted this here
Это не ошибка, это часть стандарта XHTML, в соответствии с которым каждый тэг должен быть закрыт. Допустимо писать как <img></img>, так и, чтобы было короче и красивее, <img />.

Жаль, что этот стандарт не получил развития.
UFO just landed and posted this here

Это не ошибка:


Then, if the element is one of the void elements, or if the element is a foreign element, then there may be a single U+002F SOLIDUS character (/). This character has no effect on void elements, but on foreign elements it marks the start tag as self-closing.

Движок, только выходящий на рынок, не может быть строже, чем существующие. Если хром поддерживает незакрытые теги (а он поддерживает), но и новый движок должен. Иначе сайты, "простимулированные" хромом, не будут открываться.

Это не криво написанная страница, а стандарт. Сейчас, валидная страница html вообще должна содержать только доктайп, остальное — по желанию.
Яндекс — Гугл построены на одном движке — Хромиум, который выведет даже содержимое текстового файла с расширением html без доктайпа и тегов.
Яндекс-то к чему приводить в пример? Такой же клон Хрома, как Opera, Maxthon, SlimJet и сотни других. И не то чтобы он был особо популярен.
Скоро будет: это очевидный основной кандидат на роль импортозамещающего браузера. По крайней мере, если конкурс или что там будет будет более-менее объективным.
Но он при этом, когда я его тестил года в 2015, тормозил сильно сильнее Хрома (во многом благодаря навороченному UI), и сам интерфейс был менее удобен, и слишком уж контрастен. Напоминал нынешний дефолтный UI Firefox 57+, который чёрно-белый.

Если он стал лучше — то супер, но я почему-то не уверен :)
Здравствуйте!

Могу я попросить Вас привести более страшный пример кода с умными указателями? Моя проблема заключается в том, что я не увидел страшного кода по приведённой Вами ссылке.

Поддерживаю. Что страшного? Разве что много вложенных шаблонов, но это в принципе на С++ зачастую так, даже без умных указателей.


RefPtr<HTMLCollection> { downcast<Document>(ownerNode()).allFilteredByName(name) }

Это какой-то свой умный указатель вебкита?


Вообще, идея отказа от умных указателей выглядит очень сомнительной. Не думаю, что именно из-за них браузеры такие тяжелые, зато они помогут не так часто выстреливать себе в ногу утечками памяти. Я немного поискал: 1, 2


  • unique_ptr не имеет оверхеда по памяти и имеет оверхед по производительности в конструкторе.
  • shared_ptr имеет оверхед по памяти на счетчик, оверхед по производительности в конструкторе, деструкторе, операторе присваивания. Зато разименование без оверхеда.
  • По результатам у обоих в конструкторе с включенной оптимизацией небольшой оверхед.
UFO just landed and posted this here
Спасибо за такое внимание к деталям. USVString я как-нибудь поправлю. Теперь на данный момент, c помощью вашего тонкого юмора у меня хорошее настроение, хотя некоторые люди из комментариев могут мне пожелать и плохое.

UPD: Читаю ваш комментарий еще раз и снова смеюсь со свои «ошибочек»
Самый главный вопрос. Нафига нужен этот очень тонкий враппер над std::string?

Главный вопрос C++ программирования и всего такого: а писал ли ты свою реализацию строк/враппер над ними? Вот мужики теперь похвастаться могут.
Здравствуйте!

Мне хватило ужаса от приведённых ранее ссылок, а Вы ещё больше пугаете.

Мои варианты ответа на вопросы:
2. Я бы постарался уменьшить количество таких inline методов в определении класса в принципе. Во-первых, это значительно усложняет понимание интерфейса класса, т.к. необходимо в куче кода выловить прототипы функций-членов. Во-вторых, если код не идеален и приводит к генерации предупреждений компилятора, то для каждого файла, в который включен заголовочный файл с определением класса, эти предупреждения будут генерироваться, что сделает сами предупреждения полностью бесполезными. Я с такой проблемой сталкивался, когда работал с H3D: включение заголовочных файлов H3D приводило к генерации 1500-2000 предупреждений.
6. std::find?
7. Можно поиграться со SFINAE, но в простейшем варианте я бы сделал так:
template<class ValueType> 
void fromValue (ValueType i_value) {
    data_ = std::to_string (i_value);
}
UFO just landed and posted this here
UFO just landed and posted this here

Или, как вариант, memchr(string+offset).

Круто!
А есть ли у вас режим редактирования?
Почему спрашиваю: есть всем известные движки html, со всеми наворотами, но совсем нет удобных WYSISYG редакторов более легких форматов — таких как Markdown, FB2/FB3 и т.д. Или их делают на основе движков html типа Webkit и тащат вместе с движками кучу лишнего, т.е. написание такого редактора сводится к затыканию дыр и возможностей вставить в редактор то что там не должно быть. А чего-то простого и минималистичного, не завязанного на браузерных монстров — нет.
Не поймите меня неправильно, но из того, что написано, я понял примерно следующее.
На данный момент ваш движок поддерживает парсинг HTML и кое-как парсинг CSS? Т.е. по сути он не умеет вообще ничего и на данном этапе совершенно бесполезен как таковой?

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

В целом, желаю удачи в этом нелёгком начинании. Был бы заинтересован помочь, если дело сдвинется хотя бы до рендера страничек :)
Спасибо большое. До рендера страничек еще пару to-do листов, а после рендера я сделаю интерактивное выделелние и поддержку contenteditable.
Просто люди любят глазами. Представьте, что вы приходите к потенциальным инвесторам и заявляете, что пишете новый супер браузер, который будет лучше, быстрее и вообще качественней, чем все остальные. Инвесторы заинтересованы, вы рассказываете им о вашем крутом парсере, который соответствует всем стандартам и показывает просто невероятные цифры в бенчмарках. Но инвесторам всё-равно, они постоянно твердят вам: «а где посмотреть?»

В данном случае инвесторов можно свободно заменить на читателей. Почитать это хорошо, но хотелось бы чего-нибудь наглядного — какие-нибудь тесты, пусть даже глуповатые типа «парсим миллион тегов в секунду». Это было бы куда более привлекательно, как мне кажется.
Да дело даже не в любви, а просто для браузера визуальный рендеринг страниц — это тот основной функционал, ради которого всё и затевается. Если его нет (ну хоть в каком-то виде) — нет и браузера, есть только набор вспомогательных кирпичей.
А я немного не согласен, очень часто может пригодится headless движок, если надо заниматься парсингом информации с сайтов.
Парсинг — это парсинг, не браузер.
А браузер, даже headless, всё равно обязательно подразумевает рендеринг (просто headless не показывает результат на экране).
Рендеринг и компоновку я еще успею сделать, а вот api, css каскадирование, и прочее нужно обязательно сделать. Мы же хотим интерактивную страницу, а не просто статичная нарисованная картинка.

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


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

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

Движков не 4, а куда больше, десятки если не сотни.
Парсинг HTML/CSS это меньше 5% от задачи даже с учетом расчета параметров. Хотя все параметры все равно не посчитать — многие от редеринга зависят.

5% расчет реальных параметров тегов (зависящих от дисплей и их наследование)
5% рендер имиджей (включая динамические и background всех мастей)
5% разбивка и рендер текста
5% рендер с учетом параметра flow
15% рендер таблиц
10% веселуха с импут котролами
5% форматирование после ресайза
5% движение по документу (скрол линки и т.п.)
10% борьба с чарсетами, иероглифами и поломанным блин UTF
5% динамическая загрузка мегабайтных документов и как следствие перефарматирование всего предыдущего
10% печать документа и особенно инпут контролов :)
3% доводка для тестовых ХТМЛ (есть где то для проверки стандарта)
6% обработка багованных ХТМЛ

и уже не помню, что там еще из время затратного
Моя версия TODO:

  1. API для DOM (выполнено)
  2. Основное API для CSS OM (выполнено)
  3. Парсеры и сериализаторы всякие (выполнено)
  4. Взвешивание селекторов и проверка элементов на соответствие селекторам (выполнено)
  5. Каскадирование стилей (выполнено)
  6. Генерация контента с помощью псевдо элементов css (выполнено)
  7. Метрика стилей и компоновка
  8. CSS OM API для элементов DOM (ну там, страницу прокрутить)
  9. Рисование всего этого на экран с учетом прокрутки
  10. Возможность выделять страницу
  11. Нативные контролы
  12. Ивенты для псевдо классов CSS
  13. Виртуальная машина JavaScript и события
  14. SVG 2.0
  15. Скачивание самой страницы по HTTPS
  16. А там дальше ваши Canvas, WebGL, Video, XHR, Fullscreen requrest-ы, ...
  17. А, про DevTools забыл, но инспектор dom со стилями думаю будет несложно сделать
UFO just landed and posted this here
Рендерин это без сомнения тяжко, но когда на рендеринг накладывается селектирование, переходы по тексту, изменение размера браузера, обработка тега INPUT, вывод на принтер. Вот это веселуха по взрослому.

И все равно это даже не 20% браузера. Надо будет вечность дописывать например, систему загрузки файлов, систему post/get, различные шифрования, поддержку сотен других инструментов.

ИМХО, нафиг — это все дорого и бесперспективно.
Имхо, загрузка файлов — не такая сложная задача (как и менеджер загрузок), шифрование решается с помощью сторонней библиотеки (например, OpenSSL), базовая поддержка HTTP — или кодится ручками путём привлечения новых энтузиастов, или берётся что-то существующее типа Apache Commons, опять же.
UFO just landed and posted this here
Так он справа налево и парсит, ведь существуют еще комбинаторы, которые меняют контекст селекторов перед собой. Заметь, перед собой, а не после. Поэтому надо парсить справа налево. Ну и вообще это в стандарте указано.
Можно сделать умнее и парсить в обе стороны, а начинать с фрагмента с решёткой (поиск элемента по id). Сильно сэкономит время :)
Вот непонимаю, почему крупные заинтересованные компании (Google, Microsoft, Apple, Amazon, и т.п.) не соберутся и не переизобретут велосипед создадут замену для технологий, применяемых сейчас в вебе. HTTP, HTML, CSS имеют столько исторически сложившихся недоразумений, что проще сделать что-то новое, с учетом современных реалий. Тот же Google может запросто добавить поддержку новой технологии в свой браузер. А по прошествии периода адаптации, объявить старый стек технологий небезопасным/устаревшим, как они уже делали с Flash, HTTP.
Глядишь, и не нужно будет трать столько усилий на написание и поддержку браузерного движка.
На большинство таких вопросов легко ответить: посчитайте, сколько это стоит. И сколько прибыли это принесет :) В случае с HTTP люди уже пытаются что-то сделать, однако прошло уже три года, а воз и ныне там. Люди вообще не любят менять то, что «итак работает», да и невыгодно это.
То же самое говорили про компилеры, например про gcc, внезапно аспирант Chris Lattner плюнул и написал офигенную LLVM, её купил Apple, за пару лет запилили компилеры кучи языков, а щаз на Clang + LLVM перешли кучи проектов и компаний.

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


phantom-code предлагает заменить весь существующий веб на какую-то новую технологию.

Чтобы разные проекты — завязанные на gcc — перешли на Clang, нужны причины! И про LLVM вначале говорили, что он не влетит — а затем, что жизнь его лишь в границах Mac OS X, а затем…

Резюме: временами полезно переписывать с нуля оси, компилеры, браузеры и иные базовые вещи нашего мира. Но бросая всем вызов, лучше быть всё же аспирантом американского универа! ;-)
остальным участникам не нужно ничего менять.
Хе, ну скомпилируйте Linux kernel чем-либо кроме gcc! Apple лишь за пару лет перевёл свою инфраструктуру на LLVM! Аналогичные принципы, компилер — браузер, а веб-ресурсы — программы.
Андроид, начиная с версии 8 использует clang для сборки всего. Включая ядро.
UFO just landed and posted this here
Насколько я помню, сам Линус не принимал PR, в котором фиксились UB, которые являются compiler-specified для gcc. То есть то, что оно там на llvm скомпилилось скорее совпадение нежели результат.

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

Они копировали compiler-specific поведение gcc только ради Линукса? Если так, то снимаю шляпу, конечно.

Так ваш пример про аспиранта, а не про корпорации. Корпорации намного инертнее одного человека. Может за 20 лет и поменяют, почему нет?

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

Они просто улучшают текущие технологии, не меняя основную идею. HTTP до сих пор использует отдельное TCP соединение для каждого нового запроса (я в курсе о гугловском SPDY), а информация передается в текстовом виде. Это конечно человекочитаемо и удобно, не спорю, но на практике все сводится к избыточному потреблению электроэнергии, ресурсов компьютера и пропускной способности канала.

у них мировая аудитория. Они допиливают до удобоваримого состояния внедренное, параллельно разрабатывая новое на будущее.

UFO just landed and posted this here
Ну вот меня они всем устраивают, например. И что? Как убедить всех подряд, что HTTP/1.1 не торт и пора бы его заменять на HTTP/2, который объективно может быть сколь угодно лучше, а финансово катастрофически невыгоден? HTTP/2 уже 3 года с лишним, а он всё так же нечасто встречается на просторах интернета. Просто возьмите и сами посмотрите запросы к любым сайтам. hbar.com — HTTP/1.1, yandex.ru — HTTP/1.1. У крупных (особенно зарубежных) компаний и брендов HTTP/2 встречается (google, twitter, instagram), но у всяких мелких сайтов 1.1. Есть уже куча готовых сайтов, которые придётся обновлять и вбухивать миллионы для переезда на «новые» технологии, которые попросту не дадут никакого видимого результата.
Три года могут показаться «не такими большими», но за 3 года Angular потихоньку поменялся на Electron, а C++14 на C++17. В мире ПО 3 года достаточно, чтобы возникла новая технология и тихо умерла. Так что жить нам с HTTP/1.1 еще очень и очень долго :) И поддерживать его.
HTTP/2 объективно очень плохой протокол и не является заменой HTTP/1.x. Нет у него будущего.
Это был своего рода абстрактный пример для донесения мысли, я не очень хорошо знаю веб и до HTTP/2 мне мало дела. Работает? Хорошо, пусть работает. Мы можем придумать XXXUBERTTP/9001.0 и любой другой мега-хороший и супер стандарт. Но только толку от него, если HTTP работает, и миллионы (если не миллиарды) сайтов успешно работают так, как есть сейчас. В компьютерах всё строится на очень своеобразных решениях, которые диктовались спецификой требований тех лет, легаси коде и костылях. Это везде, не только в вебе или HTTP. Посмотрите на Xorg, Linux Kernel и gcc. Хотя бы на них. Это просто клады легаси кода и поддержки уже давно несуществующих или слишком малозначимых платформ. Люди вон до сих пор находят вакансии на RPG, Delphi и PHP, хотя все они признаны мёртвыми. Ну не денемся мы никуда от легаси.
P.S. Кстати Xorg пытались выпилить Вэйлендом, но не взлетело, впрочем примерно понятно, почему. Да и сам Вэйланд почти целиком эмулирует Xorg.
Учитывая, что все дистрибутивы потихоньку переползают на вейленд — странно писать о том, что он не взлетел.

Не стоит путать легаси с надежным, проверенным временем решением. Должна происходить постепенная эволюция, а не революции с майданами. Когда горячие головы, терзаемые NIH-синдромом без десятков лет опыта за плечами, приходят с лозунгами: «а давайте всё перепишем!» — ничего хорошего на выходе не получается.

Достаточно коротко и ясно происходящее описал легендарный Poul-Henning Kamp в своей заметке: queue.acm.org/detail.cfm?id=2716278
Я бы не сказал, что все дистрибутивы на него «переползают». Как максимум — предоставляют возможность использовать. Ubuntu вон так успешно ввела Wayland, что аж откатилась назад к Xorg в 18.04. Впрочем, учитывая специфику ОС и мира открытого ПО, поставить его может кто угодно и когда угодно, и собрать его можно попытаться подо что угодно. Включение пакета в репозиторий или возможность установить что-то еще не показывает, что он таки взлетел. Максимум находится в том же положении, что и HTTP/2.0
Но это всё мелочи, мы сходимся в базовом аргументе — нельзя просто взять и сделать новый Интернет, уже слишком поздно для этого. А всё остальное — холивары :)
UFO just landed and posted this here
но новый интернет уже делается, когда вместо сайта в браузере телефона открывается приложение этого же ресурса, которое взаимодействует с сервером оптимально, а не прогружая почти каждый раз весь интерфейс и данные через HTTP/HTTPS при переходе в другой раздел :)
UFO just landed and posted this here
UFO just landed and posted this here
HTTP до сих пор использует отдельное TCP соединение для каждого нового запроса
И это правильно, так и должно быть. А от того ужаса, который вышел в виде SPDY и HTTP/2 ещё долго придется плеваться. И да, в результате в SPDY и HTTP/2 гораздо больше накладных расходов.
Я не говорил, что SPDY или HTTP/2 не имеют проблем. Однако, одно соединение на один запрос довольно избыточно. В чем, по вашему, правильность данного метода? Даже для реализации «сессии» пришлось придумывать костыли. Теперь каждый второй сайт уведомляет о том, что он использует cookie и просит понять и простить. А все из-за того, что «это правильно, так и должно быть».
Однако, одно соединение на один запрос довольно избыточно.
В чем заключается избыточность?
В чем, по вашему, правильность данного метода?
В том, что TCP это протокол транспортного уровня и проблемы транспортного уровня должны решаться на транспортном уровне. Один запрос — это один поток данных. Один поток данных — одно независимое TCP соединение. Это правильно, это позволяет применять flow control на уровне каждого потока, а также роутить эти запросы независимо друг от друга. Они могут обрабатываться разными серверами, они могут идти разными маршрутами. Всё это позволяет лучше масштабировать нагрузку и лучше справляться с ошибками.

Даже для реализации «сессии» пришлось придумывать костыли.
В чем заключаются костыли? HTTP — это stateless протокол, благодаря этому он очень хорошо масштабируется, с помощью него можно реализовать удобный и красивые RESTfull интерфейсы. Не будь он stateless, костыли бы пришлость расставлять повсюду.

Теперь каждый второй сайт уведомляет о том, что он использует cookie и просит понять и простить. А все из-за того, что «это правильно, так и должно быть».
Смешались в кучу кони, люди, мухи, котлеты… Каждый второй сайт уведомляет об использовании cookies согласно новому закону евросоюза. Это не имеет никакого отношения к протоколам, а является законодательным актом.

Более того, работа с cookies и сессиями, как и вся остальная семантика HTTP — совершенно одинаковая, что в HTTP/1.1, что в HTTP/2 и SPDY.

Работу с сессиями вероятно можно было бы улучшить, но это никак не связано с количеством TCP соединений, и ни HTTP/2, ни SPDY — вообще ничего в этом отношении не улучшают.
В чем заключается избыточность?
Установка соединения (SYN->ACK->ACK) с передачей cookies для каждого запроса дает лишнюю нагрузку на сервер и на канал. Для одного клиента она не существенна, но когда клиентов тысячи, она внезапно начинает играть свою роль. А если мы вспомним, что внутри у нас plain text, то становится еще грустнее.

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

HTTP — это stateless протокол
Мое исходное сообщение было не про «улучшение» HTTP или HTML, а о полном переосмыслении всего веба. В текущем состоянии эти технологии обладают большой гибкостью, но нещадно жрут ресурсы.
Возьмем к примеру QML. По сути QML реализует связку HTML+CSS+JavaScript (безусловно после определенной доработки), но при этом быстрее и выглядит на всех устройствах одинаково. Не требуется для каждой страницы подтягивать портянки bootsrap/jquery/etc (я понимаю, что браузеры кешируют данные, это всего лишь пример).

Более того, работа с cookies и сессиями, как и вся остальная семантика HTTP — совершенно одинаковая, что в HTTP/1.1, что в HTTP/2 и SPDY.
Доработки и улучшения — это хорошо. Но я говорю о «попробовать спроектировать с нуля исходя из текущего опыта». Я понимаю, что это не быстрый процесс и его внедрение может занять многие годы. Но иногда требуется отбросить обратную совместимость и дать дорогу чему-то принципиально новому.

С сжатием уже не plain text. Да, остаются еще заголовки, но есть WebSocket.


но при этом быстрее и выглядит на всех устройствах одинаково.

Он быстрее ровно настолько, насколько оптимизирован Qt. При этом там так же есть свои нюансы. Например под iOS нет JIT компилятора для QML.

С сжатием уже не plain text. Да, остаются еще заголовки, но есть WebSocket.
На сжатие/распаковку требуются ресурсы процессора (как сервера, так и клиента).

Он быстрее ровно настолько, насколько оптимизирован Qt. При этом там так же есть свои нюансы. Например под iOS нет JIT компилятора для QML.
Конкретно QML был всего-лишь примером.

На шифрование-дешифрование тоже требуются ресурсы процессора. Может тогда от HTTPS отказаться тоже? А неизмеримо бОльшие ресурсы требуются на поддержание электрического или беспроводного подключения сетей, и эта мощность лишь частично коррелирует с трафиком. И львиную долю трафика составляется не текстовый контент (в конце концов способность человека воспринять текст ограничена физиологически), и даже не код скриптов (и кстати, подумайте, как его передавать бинарно и при этом не навредить разнообразию скриптовых механизмов, гарантирующему их развитие, а также безопасности их выполнения), а видео и фото, которые сжаты максимально. Я думаю, вы сейчас не ту задачу решаете.
Установка соединения (SYN->ACK->ACK) с передачей cookies для каждого запроса дает лишнюю нагрузку на сервер и на канал. Для одного клиента она не существенна, но когда клиентов тысячи, она внезапно начинает играть свою роль. А если мы вспомним, что внутри у нас plain text, то становится еще грустнее.
Нагрузка от TCP хэндшейка просто смешная по сравнению с дополнительной нагрузкой, которую дает реализация ещё одного пакетного слоя для мультиплексирования и ещё одного flow control внутри соединения. Для работы HTTP/2 требуется больше накладных расходов и больше пересылать TCP-пакетов, а также расходуется больше памяти и больше процессорных ресурсов. А внутри по сути такой же plain text, который также нужно парсить.

Безусловно. Только сами cookies появилсь, чтобы сервер мог хоть как-то хранить на клиенской машине информацию и различать сессии между собой. Исторически, это был именно костыль.
А как нужно их хранить и где по вашему? В чём же заключается «костыль» и кто мешает хранить простой ключ сессии, как в общем-то многие и делают?

Но иногда требуется отбросить обратную совместимость и дать дорогу чему-то принципиально новому.
Наверное такие решения должны прорабатываться, обсуждаться и приниматься с особой осторожностью, чтобы не сломать то, что работает годами, не сделать хуже. А сейчас мы видим то, что большие корпорации проталкивают свои протоколы в своих корыстных целях, при этом заставляя всех остальных страдать. Как в своё время было с Microsoft и IE, сейчас то же самое происходит, только в руках одной мегакорпорации оказались, как самые популярные браузеры так и самые посещаемые веб-ресурсы, а потому они в результате затачивают веб под себя, наплевав на остальных. Имея при этом большие маркетинговые ресурсы, они всё это подают под соусом улучшений и инноваций, легко одурачивая основную массу, которая плохо себе представляет работу сетевых протоколов и повторяет из статьи в статью одни и те же заблуждения касательно HTTP/1 vs 2.
А как нужно их хранить и где по вашему? В чём же заключается «костыль» и кто мешает хранить простой ключ сессии, как в общем-то многие и делают?
Я бы хранил все данные на сервере и отдавал клиенту только его ID или ID сессии. Костыль заключается в том, что сначала был разработан stateless HTTP, а уже потом появилась необходимость различать сессии/клиентов, в результате чего появились cookies. Конечно, если рассматривать stateless как преимущество, то это уже не костыль. Лично я не вижу особой необходимости в stateless протоколе, но готов поверить вам, т.к. в данном вопросе не имею достаточно опыта.

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

Так собственно, в большинстве случаев все так и работает — сервер хранит все у себя, а клиенту отдает ID в виде одной куки.


Вообще, кука в любом случае нужна, ибо мир не идеален, и сессии могут рваться. В вашем случае — клиент переподключается и получает новую сессию. А если он хочет восстановить старую — ему опять же нужна кука в каком-то виде.

Или его личный уникальный ID, который он сообщает серверу.
Ну вот этот самый личный уникальный ID и будет кукой. Суть то не меняется.

И опять же, тут возникают вопросы — если этот ID придумывает сервер — то это совершенно ничем не отличается от куки.

Если ID выбирает клиент — то как гарантировать уникальность? Как защититься от перебора? Надо что-то типа GUID, и то GUID не гарантирует защиту от перебора. Нужен более длинный идентификатор. Дальше — один GUID для всех серверов? Так нельзя, потому что тогда юзера можно трекать по всему Интернету без особых проблем. Значит нужно генерить GUID для каждого сайта.

Тут возникает вопрос с поддоменами. a.example.com и b.example.com — это разные сайты или один? На самом деле может быть и так и так.

В общем случае — разные, значит будут свои GUID. Значит, нельзя трекать авторизацию между подсайтами. Например, если я хочу оставить комментарий на user1.livejoural.com — мне надо логинится. Если потом хочу оставить комментарий на user2.livejournal.com — надо логиниться снова, потому что GUIDы будут разные и сайт не узнает что я — это я. С куками проще. Сайт выдает куку для *.livejournal.com и все.

Ну и самое страшное — уже писали сверху. Веб становится строго stateful и значит резко усложняется горизонтальное масштабирование. Грубо говоря, в куку можно запихнуть id пользователя, подписать ее и тогда любой сервер кластера будет знать что вы — это вы, даже без синхронизацию через общую базу.
Нагрузка от TCP хэндшейка просто смешная по сравнению с дополнительной нагрузкой, которую дает реализация ещё одного пакетного слоя для мультиплексирования и ещё одного flow control внутри соединения.
Она по нагрузке на ЦП, может, и смешная, а вот по времени и оверхеду данных, особенно для маленьких файлов — настолько несмешная, что бандлинг JS и CSS сейчас почти везде используется по умолчанию. И это я ещё молчу про тайлинг картинок.
В том, что TCP это протокол транспортного уровня и проблемы транспортного уровня должны решаться на транспортном уровне. Один запрос — это один поток данных. Один поток данных — одно независимое TCP соединение.

Звучит правильно, но… но… ведь так можно оправдать дизайн протокола FTP :-)

А что с ним? Если не учитывать неактуальные уже фичи типа перекодирования байтов, и неактуальные на момент создания протокола вопросы безопасности, он прекрасен своей простотой и тем, что работает. Просто работает. И понятно куда смотреть, если не работает как ожидалось.

Насколько я читал в старенькой книжке середины нулевых, там со скоростью передачи всё плохо (по каким-то неведомым причинам, которых я не понял).

Наоборот :) команды передаются по tcp в похожем на http текстовом виде, а данные — в отдельном tcp соединении, просто байты без мультиплексирования, оверхеда на какие-нибудь заголовки и переконвертирование. То есть передача файла работает всегда с максимальной скоростью, сколько можно выжать из tcp в данном канале. Но многие реализации серверов имеют упоротые лимиты и дефолтные настройки, например размеры буферов, поэтому можно наблюдать тормоза на ровном месте.

информация передается в текстовом виде
Информация давно уже передаётся в сжатом виде, а текстовый оставлен только для совместимости.
А разработка нового стандарта породит два рода проблем:
1) Производителям браузеров все равно прийдется поддерживать старые стандарты, так как на них написано уйма сайтов, которые обновляться не будут, но которые могут быть важны отдельным пользователям.
2) Надо переучиваться всему сообществу веб разработчиков, выпускать новые книги, новые учебные курсы и т.п. — это встретит большое сопротивление!
На самом деле не совсем, вот есть у нас например всякие телеграмм, whatsup, fb мессенджеры. Ими пользуются сотни миллионов людей, под них уже сейчас пишутся боты для интерактивного взаимодействия системы и человека. С таким же успехом, как выпустили fb мессенджер, facebook может сделать зеркало своего сайта на новой технологии и выпустить для него браузер и сказать «Люди, пользуйтесь, пилите свои сайты вот на этом новом html10». И поставят люди себе декстопный клиент под facebook, и начнут программисты писать сайты в том числе и под новый стандарт(а скорее всего система сборки будет и под новый и под старый собирать сама). Так что старый легаси вообще не проблема, будет просто у людей браузер для старых сайтов и для новых. Проблема думаю в том, что люди которые понимают как это сделать, не видят в этом смысла, потому что в конце концов получится такой же монстр.
Да, так можно, но только это не будет браузер для Веба — это будет браузер для facebook.
И вот такое расщепление веба на внутренние стандарты — это худше что можно для него придумать…
UFO just landed and posted this here
угу. Нахрена тратить время на C++, если проблемы языка очевидны настолько, что целые языки придумывают под браузеры. Тот же раст например.
Не завидую я этим инженерам. Писать не что-нибудь, а браузер — программу, где полным-полно связанных списков и деревьев, на языке, в котором даже нет полноценного ООП, и многие паттерны проектирования реализуются через тонны костылей — это ж врагу не пожелаешь…
UFO just landed and posted this here

Я писал дерево отрезков, Фенвика, декартово и много других структур данных. И каждый раз это примерно 2 шаблонные структуры. В Расте такое делается также без проблем.

UFO just landed and posted this here
А что не так с его состоянием? Вроде работает шикарно.

Думаю, если бы он действительно работал шикарно уже сейчас, то заменил бы Gecko в Firefox.

Нововведения из Servo и так постепенно переносят. Servo же целенаправленно и разрабатывается как замена Gecko.
Только не замена, а тестовый полигон. Имеено для обкатки новых частей, которые потом переносят. Хотя в итоге и может всё прийти к, по сути, одному двужку — такой цели никто не заявлял.
UFO just landed and posted this here
UFO just landed and posted this here

Привет!


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


1) Каким спецификациям соответствует парсинг HTML? Я так понял, что вы из головы написали парсер. Штука эта давольно сложная, тем более чтобы написать её правильно с заделом на будущее. Судя по вот этому о скоростях мечтать не приходится. Это действительно весь HTML парсер? Это тоже странно выглядит.


2) Каким спецификация соответствует парсинг CSS? Опять же, судя по коду никаким. Вы просто взяли из головы то, что знаете о CSS и сделали для этого парсинг. Вообще, CSS раздербанить ни фига не простая задача. Уж поверьте моему опыту.


3) У вас не верно сделана сериализация HTML. Точнее сказать, она сделана из каких-то ваших соображений. В спецификации чётко описано поведение сериализатора.


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


А теперь попугаю, немного :).


У вас исходники всего этого дела занимают 312КБ. Чтобы хоть как-то оценить насколько ничего нет: в проекте lexbor один только html парсер занимает 1.8МБ. DOM, в котором почти ничего нет, только минимум для создания и удаления нод, элементов, атрибутов 100КБ.


Чтобы понять масштаб того, что надо делать посмотрите мой roadmap, и это процентов 10 от полноценного браузерного движка.


Ваши бы силы да в нужное русло.
Поправьте меня если я где-то ошибся.

Насчет размера.

Я не понял, важнее функционал или размер исходников?
Дмитрий, важен не размер, нет.

Важно, чтобы ожидания сходились с заявлениями. У вас, к сожалению, нет парсера HTML, CSS, у вас нет сериализаторов. Да и странно заявлять о сериализации даных. Куда важнее заявить о парсинге чанков, парсинге фрагментов. У вас нет работы с неймспейсами. Не знание HTML спецификации сразу кинулось в глаза после фраз о кавычках, это самое стандартное поведение, зачем это оговаривать отдельно? У вас есть что-то, что вы сами придумали и назвали это парсером HTML, CSS.

Я никак не пытаюсь «наехать». И я искренне обрадовался когда прочитал заголовок, но по факту у вас пустышка + непонимание базовых вещей. Если вы хотите, то можете написать мне, что нибудь да обсудим.

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

Чанки (chunks) — фрагменты.
Браузеры процесят хтмл кусками. Прилетело по сети 4к данных, эти данные идут на парсинг и так далее. Данные могут быть прерваны в любом месте, соответственно и продолжить обработку надо уметь с того места где закончил. Но, тут магии нет, если ты посмотришь на спецификацию то поймешь, что она написана так, чтобы это работало "из коробки". Токенизатор на вход принимает codepoint (unicode) по одной штуки и решает куда дальше рулить. Это обычная стейт машина.


Фрагменты — парсинг хтмл фрагментов очень важен. Это так называемый innerHTML. Штука эта довольно тяжелая для выполнения. Как оно должно работать так же описывает спецификация. Тяжелая она потому, что для неё необходимо создавать новый парсер, новый Document объект и root element + всякая логика.


Сделать, хотя бы, парсинг хтмл быстрым задача тоже интересная.


Ты, конечно, молодой и активный. Но прежде чем делать громкие заявления изучи как устроены текущие браузеры, посмотри почему они все отрабатывают страницы одинаково (спецификации).
Конечно, фигачить из головы куда интереснее. Делать что-то по спецификациям нудное занятие.
Чтобы что-то сделать лучше необходимо понять текущие проблемы. Нужен опыт. У тебя, к сожалению, опыт отсутствует как в программировании так и в понимании браузерных движков.


Но шуму ты наделал много.

Эх, вы либо вообще не понимаете о чём я пишу, либо, я даже не знаю. В общем, удачи вам.

UFO just landed and posted this here
Ну, всё равно. За отвагу большой плюс.
Я ему уже выше писал, что если захочет то пусть пишет мне лично, расскажу, что знаю.
А мне объясните пожалуйста, зачем для фрагментов создавать новый рут и новый парсер? Это же ресурсов дофига жрать будет, и будет дико тормозить. Можно пример сценария, где это реально необходимо (фреймы и айфреймы — не в счёт, тут без вопросов)?

Ну, а как вы создадите ещё одно дерево? Понятно, что парсер можно создать один раз и держать его при себе. Всё остальное прийдется создавать каждый раз. Потому, что во время парсинга всё это используется/необходимо. Думаю, напишу статью о том как всё устроено в хтмл. Можете посмотреть в спецификацию: https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments


Собственно, по этому innerHTML крайне дорогая штука в браузерах. innerHTML — это и есть парсинг фрагмента. Всегда лучше пользоваться напрямую через интерфейсы.

UFO just landed and posted this here

Нет. Не быстрее.


Дорого звать из js функции движка. innerHTML быстрее если нафигачить туда много HTML. Если сделать чистый тест по одному тегу, к примеру


<div>Текст</div>

и покрутить в цикле с реальным добавлением в текущий документ, то innerHTML проиграет в 3-4 раза.


Более того, если в innerHTML отдать сразу 1000 тегов и тоже самое создать с помощью дом то время выполнения будет почти одинаковое.


Но если в innerHTML зафигачить сразу кучу хтмл-а то он отработает быстрее. Потому, что он сразу передаст всё в движок и не будет делать вызовы по Н раз.


Отсюда, надо понимать, что и как использовать.


Код для примера:


1-2 mc


<div id="aaa"></div>

<script>
    let aaa = document.getElementById("aaa");

    let t0 = performance.now();
    let node;

    for (let i = 0; i < 1000; i++) {
        if (node) {
            aaa.removeChild(node)
        }

        node = document.createElement("div");
        let text = document.createTextNode("Text " + i);

        node.appendChild(text);
        aaa.appendChild(node);
    }

    let t1 = performance.now();

    let res = document.createTextNode("Time: " + (t1 - t0) + " milliseconds.");
    aaa.appendChild(res)
</script>

7-8 mc


<div id="aaa"></div>

<script>
    let aaa = document.getElementById("aaa");

    let t0 = performance.now();

    for (let i = 0; i < 1000; i++) {
        aaa.innerHTML = "<div>Text " + i + "</div>";
    }

    let t1 = performance.now();

    let res = document.createTextNode("Time: " + (t1 - t0) + " milliseconds.");
    aaa.appendChild(res)
</script>
UFO just landed and posted this here

Я ну пойму, вы что хотите доказать?


Я вам доказал, что innerHTML внутри отрабатывает дольше на простом примере. Зафигачте 1000 элементов через innerHTML:


var html = "<div>Текст 1</div>...<div>Текст 1000</div>"
aaa.innerHTML(html)

B попробуйте создать те же самые элементы в цикле через дом добавляя их по одному в aaa.appendChild(node).


Скорость будет почти одинаковая. Это как доказательство, что основное время уйдет на оверхед.
Я опроверг ваше заявление:


Но innerHTML и DOMParser.parseFromString отрабатывает быстрее, чем постройка дом-дерева через методы DOM API по отдельности.

Опять же, выше я вам объяснил где будет выигрывать innerHTML.


Что это за синтетический тест, с измерением перфоманса на создание 1-2 дом узлов, когда один из них текстовый? Зачем это нужно делать через парсер адекватному человеку?

Вполне себе хороший тест. Показывает, что innerHTML медленнее. А точнее то, что вы не правы со своим заявлением, что он быстрее.


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

Простите, но добавляйте сами, что хотите. Простым примером вам было показано как оно отрабатывает. Я хорошо знаю как оно устроено внутри и могу создать тесты там где inner выиграет и проиграет. Но выше я создал именно голые тесты, равные условия, чтобы показать, что вы не правы.


При этом я дописал, что:


Отсюда, надо понимать, что и как использовать.
UFO just landed and posted this here

Вы специально искажаете всё? Читайте комментарий выше.
Я говорил, про 1000 элементов, а вы тут тестите 100000 тысяч.


Да, я выше написал, что innet будет выигрывать если ему много сразу зафигачить. Потому, что оферхеда не будет на вызов функций из js.


Но, даже при этом, при вашем тесте с котором я согласен был даже выше, что innet будет выигрывать если ему много дать, построение дом проигрывает всего в два раза. При вызове 100000 функции которая сходит в движок.

UFO just landed and posted this here
Я не увидел там главного: drafts.csswg.org/selectors-4/#grammar

Чувак, реально, ты тратишь силы в пустую. Это круто для опыта, но толку от этого никакого. Хотя, скорее всего, в твоём возрасте толк и не нужен, я хз.
Слушай, ну никто в тебя тапками кидать не собирается.
Нет, не то. Твоя ссылка это не синтаксис. Я привел ссылку на граммар. То есть, то как надо парсить токены которые создает синтаксический парсер css ( drafts.csswg.org/css-syntax-3/#tokenization ). В парсере css ты получаешь токены, не байтовый поток и не юникод. Читай ссылку.
Я вот тоже пилю свой браузер. Точнее пока что браузер внутри браузера, а когда обкатаю алгоритмы, то уже нативной реализацией займусь. Только моя мысль в том, что нет смысла реализовывать весь тот легаси, что накопился за десятки лет, а ограничиться какой-то своей простой гибкой спекой, так что сайты, написанные с учётом этой спеки, получат все преимущества новой лёгкой, быстрой и гибкой реализации, а остальные будут просто открываться во встроенном chromeframe.

Вообще, я тут создал чат в телеграме. Присоединяйтесь, будем обмениваться идеями :-) t.me/dev_browser
О каком легаси вы пишете? В спеках всё довольно логично и понятно. Есть, конечно, шероховатости, но в целом всё ясно.
Как вы поймёте, что сайт «нормально» отображается с помощью вашего движка? Что это будет за урезанная спека которая сможет предоставить весь нужный набор опций для верстки и будет лучше чем сейчас?
Чтобы вам хоть как-то попытаться пропихнуть свою спеку вам надо стать гуглом, и то не прокатит.

Есть стандарт который все знают и поддерживают, опираются на него. Идея написать свой движок, но если чего отдавать на отрисовку гуглу за гранью разумного.
Да хотя бы даже фривольности с незакрытыми тегами в HTML. Можно ограничиться XHTML парсером, чем значительно упросить и ускорить реализацию. От разработчиков обеспечить совместимость с xhtml не составит труда. Кучу устаревших css свойств, вендорных префиксов и прочего барахла можно смело выбросить, опять же описав что использовать не следует, а что следует использовать вместо.
Определять просто — специальным флагом в коде разработчик явно берёт на себя обязанность соблюдать более строгие требования. Подумать о том, как можно было улучшить текущий стек, я и предлагаю подумать. У меня, разумеется есть куча идей разной степени тяжести.
И давайте вы свой пессимизм оставите ведру с крабами. Возможно тот же гугл заинтересуется проектом, когда он покажет свои преимущества. Глаза боятся — руки делают. А если вам страшно так, что руки немеют — так вас никто не заставляет. Каждый сам решает чем ему интересно заниматься.

Никто не знает веб стандарты в полной мере. Это одна из бед этого переусложнённого бардака.
Судя по вот этому о скоростях мечтать не приходится. Это действительно весь HTML парсер? Это тоже странно выглядит.

Там кстати можно применить оптимизацию habr.com/post/166201
У html тегов длиннее 9 символов начальные части не пересекаются, поэтому их можно отбросить при вычислении хэша.
Тот кусок вообще нужно выкинуть, зачем его оптимизировать? Тем более так спичечно
Насколько я понял из первых абзацев, вы считаете, что умные указатели — это зло?
Хм, интересная точка зрения. И деструкторов в классах я что-то тоже не вижу, очень интересно)
Garbage collector у меня в to-do, можете не переживать по этому поводу.
Может проще было взять язык со встроенным GC? Тот же D — отлично бы подошёл.
UFO just landed and posted this here

Вы уверены, что GC это добро?

Без рендера неинтересно — это самое сложное. А парсеры может написать почти кто угодно, особенно если не соблюдать стандарты и не делать оптимизаций

JS нет. Рендеринга нет. DOM-дерево не оптимизировано. Точнее автор даже не доказал, что оно оптимизированное и корректное. Что его модель вообще будет рисоваться и ложиться на GPU. Что там корректный байт-код или он собирается строки гонять на каждый кадр.

Мне кажется, заявлять о «полноценном браузерном движке с нуля» можно будет начинать, только когда рендеринг появится. Хотя перечисленное в комменте тоже нужно, на данный момент говорить по-моему ещё не о чем

Какие все злые. Сами бы не сделали и доли того, что сделал автор. Потому что сложно, лень, никому не нужно, всё равно будет не по спецификациям и т.д. Разве это всё важно? Задумка интересная, автор молодец.

>Сами бы не сделали и доли того, что сделал автор

Аффтар НИЧЕГО полезного не сделал, сколько бы строчек ненужного кода он в этот проект не накидал. Ибо, как активно делающий web scrape на java, авторитетно заявляю, даже если ему ещё 20 студентов (что маловероятно) дать в помощники, они не будут успевать. И уж точно это не будет самый быстрый и «архитектурно правильный» движок.

Самый продвинутый headless browser под java — HtmlUnit пилит команда из человек 5, причём безбожно проигрывают в гонке. Если 4 года назад можно было почти всё скрейпить, сейчас чуть ли не каждый второй сайт с авторизацией выпишет облом.
При этом безголовый браузер это далеко не полноценный браузер. Нужна лишь навигация по DOM.

В общем, через много лет это будет в самом лучшем случае что-то вроде chromium с выключенным js. Но в хроме я, когда сильно хочется, жму кнопочку «включить js», а у них такой волшебной кнопочки не будет.
Так автор обещал поддержку JS. Это вообще самое простое из всего. Я JS интерпретатор написал в январе-феврале этого года за 5-6 недель. Он покрыт юнит-тестами, и работает, не нарушая стандартов (хотя кое-где ведёт себя лучше и логичнее существующих JS движков на мой взгляд). Да, он не будет работать быстрее V8, там нет JIT. Но не пофиг ли? Я ставил цель сделать браузер хотя бы уровня IE7 по возможностям и скорости рендеринга, в те времена джитами и не пахло ещё.

P.S. Часть фич ES6 мой интерпретатор, кстати, умеет, включая стрелочные функции, block-scope variables и Promises.
А он у вас выложен в опенсорс? Интересно было бы взглянуть.
Не выложен. Я не очень дружу с Git, поэтому даже не знаю, может проще архивом куда-то будет залить :) Так-то мне поделиться не жалко, просто не очень хочу позориться, не уверен, что мой код настолько хорош.
UFO just landed and posted this here
Да я знаю, что там можно хоть через веб-интерфейс всё загрузить. Просто пока я единственный разработчик — это как-то очень криво будет выглядеть.

У меня уже стоит Tortoise SVN, и я коммичу каждое небольшое изменение на старый вузовский сервер. Я пробовал ставить параллельно Tortoise Git, он мне мало того, что показался менее стабильным, так они вдвоём ещё и немного конфликтуют… Прямо хоть под другой ОС его ставить, я не знаю. Или использовать консольную версию Git.
UFO just landed and posted this here
Посмотрел. Интерфейс симпатичный. Но XP и Vista не поддерживаются (причём даже в первых версиях от середины-конца 2013-ого года!). Так что в любом случае надо ставить его под другой ОС (Win 7 например) — а в этом случае меня и Tortoise Git устроит, тем более, более новые версии должны были стать стабильнее и проработаннее.
Еще можно на bitbucket.org — там есть что использовать — git или mercurial. Я вот даже не знаю, кто мне больше нравится git или mercurial, в некоторых вещах — меркуриал нравится больше, как минимум из-за отслеживания, что файл был скопирован и в него внесены изменения, ну и Tortoise Hg как-то адекватнее себя ведет, чем Tortoise Git.
Но с репозиторием SVN можно работать и через Git. Получается, в целом, не плохо. Я работал с SVN через меркуриал (hgsvn) и git-svn. В целом, git-svn поудобнее, но бывали проблемы с клонированием SVN репозитория — если он большой, то клонируется очень долго, и иногда падает — приходилось подбирать параметры. С hgsvn такого не было, но он и не клонировал репозиторий, это фактически было в одном каталоге два репозитория — SVN и меркуриал, а утилита hgsvn позволяла их синхронизировать. Это было менее удобно, но позволяло не вытягивать при помощи hgsvn всю историю, а пользоваться историем SVN.
Не знал, что SVN можно использовать не только через клиенты для SVN)

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

Когда ставил Git, пытался делать разные ветки на разные добавляемые фичи, потом их сливать — в итоге действий было много (а по факту ветка не жила дольше 1-2 коммитов), и не всегда делалось то, что я хочу (то есть меня даже GUI не спас).

Может, попробовать какой-то вариант примерно как у вас был, с автосинхронизацией и подтягиванием истории из SVN? Только я хотел бы синхронизировать с Git, а не с Mercurial, и чтобы оно сразу при коммите в SVN на GitLab бы отправлялось.

Работа с Git/Меркуриал подразумевает большее количество шагов — добавить в "индекс", сделать локальный коммит, отправить коммит на сервер.


Если Вы работаете с репозиторием один, то использование практики ветка-на-фичу, мне кажется излишней — потренироваться работать с ветками — да, пожалуй, но на постоянной основе — особого смысла нет. Это дает преимущества когда над проектом активно работает несколько человек. В этом случае удобно использовать ветки, чтобы не вливать сырые изменения в основную (trunk/master).


Я использовал связку, так как в процессе работы мне было удобно делать локальные коммиты и отправлять промежуточные результаты работы в отдельный hg-репозиторий (потом git-репозиторий). Срок выполнения задачи был большим, поэтому я делал коммит каждый день с тем на чем закончил, иногда делал дополнительные ветки, чтобы попробовать какой-нибудь альтернативный вариант решения. После того как задача решена, объединял все коммиты в один и отправлял в SVN.


К сожалению одной командой отправить изменения в SVN и другой git-репозиторий не получится. Не зависимо, что Вы выберете git-svn или hgsvn сценарий будет примерно такой:


  • внести изменения в индекс (stage)
  • сделать локальный коммита
  • отправить изменения на сервер SVN
  • отправить изменения на сервер Git (Меркуриал)
Окей, спасибо. Но возможно есть какой-то софт, автоматизирующий отправку коммита в несколько репозиториев? Например, локальный Git коммит + Push в Git на гитлаб + коммит в SVN. Ну или в простейшем случае — батник написать какой-нибудь, я почти уверен, что это реализуемо.
Да, конечно, это можно сделать. Это можно батник (из него вызвать git commit и если код возврата 0, то отправлять изменения на сервера последующими командами). Еще можно попробовать посмотреть на локальные хуки гита, которые будут срабатывать после комита (не уверен, можно ли из них отправить изменения на сервер).

Кажется, что tortoise git как раз и делал отправку изменений на сервер сразу после комита, но могу ошибаться. Я не очень люблю клиенты для git, так как в них очень легко можно наворотить что-нибудь не то, а потом придется разгребать. С этим сталкивался не раз, поэтому предпочитаю работать с консолью — выше осознаность действий.
В хуках вы можете делать всё, что угодно.

tortoise git сам ничего не пушит, но он позволяет это сделать в один клик после коммита.

Через консоль сломать git репозиторий куда легче, чем через гуй. У mecurial с этим получше.
А что, если вызывать консольную команду git в качестве post-commit хука в Tortoise SVN? Только там наверное нужны будут две команды — для коммита и для пуша. И опять же, если по какой-то причине я буду держать ещё и Tortoise Git параллельно (можно конечно его держать, но отключить интеграцию с проводником, чтобы не было конфликтов с Tortoise SVN в виде «борьбы за иконки») — я вот думаю, может тем же батником сперва и копирование в отдельный каталог делать, можно даже на другом логическом диске, а в Git пушить уже оттуда (то есть локальный Git репозиторий держать отдельно от рабочей копии SVN).

С копированием я разберусь, а вот как через консольный Git сделать сразу коммит и пуш на гитхаб, не подскажете?
UFO just landed and posted this here
А комментарий к коммиту где тут указать? Я хочу, чтобы оно было прямо совсем автоматически в идеале. В Tortoise SVN там окно открывается для комментария, тут я в принципе готов вручную даже его ввести (возможно, я не каждый коммит в SVN буду отправлять в Git), просто интересно, куда его вводить, если нет клиента с GUI. В консоль?
UFO just landed and posted this here
git commit -m
Уже почитал в статье про введение в Git (точнее, в руководстве по загрузке проекта на гитхаб). С текстовым редактором — имхо это какая-то странная механика, особенно как для Windows. Как программа поймёт, что файл готов? Мониторит файловый дескриптор, отслеживая закрытие текстового редактора?
UFO just landed and posted this here
По завершению процесса. Поэтому с многодокументными редакторами могут быть проблемы, да. Надо обязательно, чтоб умел отдельную копию запускать.
Я использую старую версию GridinSoft Notepad (2.8), там вообще нет мультидокументного режима, каждый документ — новый процесс. А по дефолту у меня вообще Блокнот используется. Когда текст комментария пишешь, синтаксис вроде подсвечивать не нужно. Нужные же типы файлов у меня вручную в реестре проставлены ассоциациями, плюс для них добавлен пункт в контекстное меню проводника («Редактировать»).
К слову, мой движок (его render-компонента) уже умеет работать с z-index и контекстами наложения (в целом всё строго по стандарту, исключая момент с opacity, это надо будет доделать потом), корректно выводит float элементы (включая float сбоку от float, float + clear под float и т.д.), и сегодня он научился выводить элементы с pre-run контентом (пока поддерживаются только элементы списков, и пока только маркированные, нумерованные пока не сделал).

Но есть и проблемы...
Это, к сожалению, не делает его менее багнутым. К примеру, после полного построения структуры элементов, выполнения layout и render, при полной очистке и добавлении элементов заново внутри методов-тестов — всё ОК, но если очистить не всё, а только содержимое одного из блоков, и начать добавлять контент для теста туда — то остаются полупрозрачные «следы» старого контента, и ни один из методов очистки не помогает это убрать (что странно). Причём таких следов не будет, если закомментировать первый вызов render (до вызова тестового метода, в коде main метода). То есть рисуемое не всегда корректно очищается (иногда нормально, судя по тому, что в ряде других тестовых методов оно работало как надо — опять же, «работало» не значит «работает», нужно проверять по новой, я мог что-то и поломать).
Выложил исходники в открытый доступ.

Должен сказать, что пока ещё очень многое не реализовано: нет поддержки фреймов, таблиц, элементов форм. Даже box-sizing пока реализовать руки не дошли (по умолчанию расчёты ведутся в режиме border-box ради удобства отладки и наглядности).

Однако на днях я реализовал в JS движке методы Promise.all и Promise.race, реализовал там же корректные вычисления с бесконечностями (раньше бесконечности просто не поддерживались в принципе), сделал нумерованные списки нескольких видов в рендер-движке (включая нумерацию римскими цифрами и латинскими буквами). Также ввёл в JS-движке скрытие возвращаемых значений при установке таймеров, чтобы не засорять вывод (однако, его можно активировать с помощью статического поля класса в несколько доработанном виде).

github.com/popov654/tinybrowser
UFO just landed and posted this here
В поведении некоторых тригонометрических функций (где в результате по логике должно быть NaN, а текущие реализации выдают просто некое число), и в поддержке некоторых конструкций, запрещённых в текущих реализациях (например, инкремент и декремент с числовым литералом).
UFO just landed and posted this here
А что на счёт поведения этих функций говорит стандарт?

Надо почитать. За стандарт не скажу (не читал), но когда у нас с точки зрения математики результат вычисления — плюс или минус бесконечность, то это скорее NaN (особенно если нет специальных констант, как в Java), чем непонятная фигня с плавающей точкой, которая проверку isNaN() не проходит (возвращает false).

Кстати, оказывается, в JavaScript ещё есть функция isFinite() (стыд и позор мне, не знал про неё). Так вот, внимание — isFinite(tan(Math.PI / 2)) возвращает false! Стандарты стандартами, но здравый смысл подсказывает, что это бред.

То есть 5++?

Именно так. Не то чтобы в этом был практический смысл… Но если есть возможность отличить -1 от --1 (по числу минусов) и ++3 от +3 (по числу плюсов) — то нет особого смысла падать с ошибкой, если можно посчитать выражение по тем же правилам, что и в случае переменной (только сайд-эффектов не будет).
Если есть возможность отличить -1 от --1 (по числу минусов) и ++3 от +3 (по числу плюсов)

5++-5 — это (5++)-5 или 5+(+(-5))? Ведь +-5 в js — валидная операция.
+-5

Хм. Не знал про такой нюанс. Но писать +-5 смысла даже ещё меньше, чем 5++: поменяли два раза знак и получили то же, что было. Причём у нас заведомо integer (потому что литерал), а не, например, boolean, поэтому это даже для преобразования типа в данной ситуации бесполезно.

И вообще — писать код, не ставя пробелы — ужасно дурной тон. Напишите 5++ -5, и вопросы отпадут сами собой. Мой парсер смотрит код посимвольно, а пробел — гарантированный признак конца токена.

Текущая же реализация парсера именно при вашей форме записи воспримет это именно как (5++)-5, потому что скобок нет, а анализ идёт слева направо.
писать код, не ставя пробелы — ужасно дурной тон.

Минификация же.
А, ну да, разумно. Ну и ок — просто не использовать такие конструкции, если планируешь использовать минификацию. Не такая большая проблема. Я кстати никогда код не минифицировал, не вижу в этом смысла. Особенно его не вижу, если на сервере включен GZIP, который и так всё сожмёт одинаково хорошо (или почти одинаково, но разница там совершенно мизерная).
Разница от минификации может быть в несколько раз, он не только пробелы уберет, но и пожмет все названия переменных и функций до 1-2ух символов, удалит неиспользуемый код, выделит повторяющиеся паттерны строк в отдельные переменные и много чего еще. И тот факт что Вы его не используете ни о чем не говорит, минификацию используют на сегодняшний день почти все (и правильно делают), что толку от вашего JS-интерпретатора, если он сможет открывать только Ваши сайты (не минифицированные).
но и пожмет все названия переменных и функций до 1-2ух символов

Я знаю об этом.

минификацию используют на сегодняшний день почти все (и правильно делают)

Нет, не правильно. Из-за этого код становится намного сложнее анализировать (хотя для людей, его писавших — это даже плюс, но я не про них сейчас, а про всех прочих). Ценность же анализа просто огромна для самообучения и развития.

Насчёт выгоды от уменьшения размера после минификации — она вовсе не так велика, как вы говорите. Даже вк до перехода на новый дизайн не минифицировал свои скрипты (можете даже посмотреть сами на wayback machine, если что).

Опять же, GZIP прекрасно справляется с тем же самым: заменяет наиболее часто используемые паттерны (включая длинные повторяющиеся имена переменных) на специальные байтовые последовательности, причём чем паттерн встречается чаще, тем его код короче. Это в сто раз лучше и грамотнее, чем ваша минификация.

Не говоря уже о том, что для очень маленьких сайтов, где все скрипты весят меньше 800-1000 Кб, вообще можно не использовать ни минификацию, ни сжатие: каналы сегодня быстрые, а часть данных — кэшируется браузером и не будет загружаться при каждом запросе повторно. При грамотно же настроенном кэшировании на стороне сервера можно и вовсе получить гарантию кэширования всей статики на N часов или суток.
Что вы несёте? Какой анализ минифицированного продакш кода? Анализируйте исходники на здоровье, или вы также сидите и анализируете байт-код джавы после компиляции? Анализируете нативные ассемблерные инструкции с кода?

Выгода от минификации колоссальна в масштабах всего интернета, если вы этого не понимаете, да ещё и утверждаете обратное, то и говорить не о чем.

Давайте разделим на 2 части.
1) Удаление неиспользуемого кода.
Все модные инструменты вроде вебпака НЯП это делают всегда.
2) Сжатие имен переменных, выделение общих частей строк и т.д.
Мне тоже непонятно, почему минификатор сделает это лучше чем Brotli.

Так не надо пользоваться вебпаком, и не будет проблем. И потом, зачем вообще писать/подключать неиспользуемый код?

Наоборот, вебпак решает проблему неиспользуемого кода.
Такой код берется очень просто.
Пусть libfoojs умеет делать операции foo и bar.
Но мне нужна только foo. Значит код для бар будет неиспользуемым.
Если говорить про С, то там тоже при линковке избыточный код выбрасывается. У других ЯП, я думаю, ситуация такая же.

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

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

Что вы несёте?

Пожалуйста, давайте без хамства.

Анализируйте исходники на здоровье, или вы также сидите и анализируете байт-код джавы после компиляции?

До вас серьёзно не дошло, что речь про проекты, где в открытом доступе нет исходников?

А даже если где-то они и есть отдельно — в браузерном инспекторе (когда они не минифицированы) их читать намного быстрее и проще, чем идти на гитхаб и выкачивать оттуда, либо читать там.
Разница от минификации может быть в несколько раз

После сжатия не может.


пожмет все названия переменных и функций до 1-2ух символов

выделит повторяющиеся паттерны строк в отдельные переменные

Сжатие именно это и делает. Причём не только для имён переменных, а для любых повторяющихся подстрок.


удалит неиспользуемый код

Зачем его вообще добавлять тогда?


много чего еще

Ага, например:


  • Усложнит отладку на проде вплоть до невозможности что-либо понять.
  • Может сломать релизную сборку своими предположениями об эквивалентности преобразований.
  • Замедлит деплой, порой в несколько раз.
  • Сделает стектрейсы с прода бесполезными.
Сжатие именно это и делает. Причём не только для имён переменных, а для любых повторяющихся подстрок.


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

Ради простого примера:

function zip(arrays) {
  ...
}

function split(string) {
  ...
}


превратиться примерно в

function c(c) {
  ...
}

function cc(c) {
  ...
}


Что гораздо лучше сжимается чем исходный код любым алгоритмом сжатия. Причем алгоритмы минификации устроены таким образом, что результирующий код был compression-friendly.

Зачем его вообще добавлять тогда?


Например в зависимости от конфигурации могут получаться разные условия?

Усложнит отладку на проде вплоть до невозможности что-либо понять.


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

Может сломать релизную сборку своими предположениями об эквивалентности преобразований.


Не может (если вы следуете стандарту).

Замедлит деплой, порой в несколько раз.


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

Сделает стектрейсы с прода бесполезными.


Смотри пункт про отладку
минификатор специально заменит почти все функции и переменные на одно-двух буквенные вариации

Что даст максимум 10% после сжатия, офигеть какая разница.


Например в зависимости от конфигурации могут получаться разные условия?

Так в зависимости от конфигурации и добавляйте. Зачем добавлять, а потом надеяться, что оно может быть выпилится?


Вообще никак не усложняет отладку, потому что есть source-maps

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


Вообще не очень понимаю зачем дебажить продакшн, дебажьте дебажную сборку?

Потому что бага воспроизводится лишь на проде и нужно понять как воспроизвести её на дебажной сборке. Вы вообще дебагом хоть раз занимались в реальной жизни?


Не может (если вы следуете стандарту).

Простой пример из жизни — пишу ;this.foo; рассчитывая на сайд эффект в геттере, который протрекает зависимость и перезапустит мой код, когда свойство foo изменится. Минификатор вырезал обращение к свойству, прикинув, что его значение всё-равно никуда дальше не идёт. У меня всё работает, а тестировщики шлют "невозможные" багрепорты. Какой стандарт я нарушил?


Зато ускорит скачивание и открытие страницы пользователем в несколько раз.

При наличии сжатия лишь на жалкие 10-20 процентов, которые никто из пользователей не заметит.


чем меньше кода, чем меньше названия переменных — тем проще и быстрее его распарсить.

Так пишите меньше кода, а не меньше названия переменных — профита будет куда больше.


Смотри пункт про отладку

Вы бы попробовали сначала, прежде чем так уверенно говорить. Сорсмапы работают исключительно в дев тулзах и исключительно постпроцессингом при отображении.

рассчитывая на сайд эффект в геттере
Какой стандарт я нарушил?

Здравую логику. Геттеры не должны делать никаких сайд-эффектов, влияющих на состояние объекта.

А подскажите тогда, как запустить force reflow? Единственный известный мне способ — дёрнуть этот самый геттер с сайд-эффектом (бутстрап, например, дёргает offsetHeight)

Еще не сталкивался с проблемой, требовавшей DOM force reflow.
Я хотел сказать, что такие штуки стоило бы оформлять в виде функции, а не геттера, ибо от последнего ни минификатор, ни программист не ожидают никаких дополнительных действий, непосредственно влияющих на логику выполнения.

При работе с анимациями на базе CSS3 Transition reflow требуется почти везде


В том же бутстрапе это оформлено как function reflow(element) { return element.offsetHeight; }, но это всё ещё сайд-эффект на геттере (я не проверял существующие минификаторы, но чисто теоретически шибко умный минификатор может и вырезать неиспользуемый результат вызова reflow(), наверно)

Интересно. Я вот читал ещё пару лет назад, что такое reflow. Расскажите, пожалуйста, что не так с CSS3 Transitions. Почему после них reflow нужен?

У меня были проблемы почти во всех браузерах, связанные вот с чем: допустим, есть у меня свойство, на нём стоит transition (пусть это transform, делающий движение с небольшим поворотом для эффекта перелистывания страницы-фотографии); я хочу подвинуть элемент, затем скрыть его через display: none, через JavaScript назначить transition-duration в 0, поставить его на место пока он скрыт, и потом вернуть transition-duration обратно. Беда в том, что это всё адски глючит. Если быстро листать фотографии, то можно наблюдать совершенно дикие эффекты — фотография сначала оказывается на 80 процентов от начальной точки (под ней видна следующая, но происходит так, будто 80 процентов траектории мы проскочили моментально), потом делает скачок к начальной точке; иногда получается так, что перелистываемая фотография совпадает с последующей, хотя её src должен обновиться только после завершения эффекта, а никак не во время его.

Опытным путём я установил, что чтобы не было ошибок, надо подождать минимум 250-400 мс после завершения transition перед тем, как менять параметры перехода, и потом поменяв нужные свойства через transform в идеале нужно снова подождать столько же, прежде чем возвращать длительность на место. Приходится делать дикие извраты с вручную подобранными таймаутами, причём в разных браузерах и на железе разной мощности это всё работает по-разному.

Научите, как такое делать правильно :)

Насколько я сам понимаю суть происходящего — без reflow начальное состояние элемента оказывается неопределённым, и если не принудить браузер вычислить стили элементов в начале анимации, то начинаться она будет откуда попало. В случае с display:none начального состояния по сути вообще нет, и никакого transition вообще не будет, пока браузер не просчитает элемент хотя бы раз после выключения none.


Пример: https://jsfiddle.net/83oxepgj/


Общий алгоритм примерно такой:


1) Задать стили начала анимации с transition-duration: 0ms
2) force reflow
3) Задать transition-duration
4) Задать стили завершения анимации
5) [Опционально] Повесить setTimeout на transition-duration миллисекунд (событие ontransitionend не очень надёжно, потому что не сработает, если окажется, что начало и конец совпадают и анимировать нечего)


Другой пример: https://jsfiddle.net/c8d0Ltry/ — без reflow стили начала анимации игнорируются, потому что браузер не успел их учесть и пересчитать всё, из-за чего элемент начинает двигаться с середины, а с reflow браузер вынужден всё пересчитать и поставить элемент на начало, и всё норм

пока браузер не просчитает элемент хотя бы раз после выключения none

Так почему он его не просчитывает после назначения display: block? Кроме того, у меня начальное значение на самом деле ещё как определено — только в CSS коде, а вот конечное я задаю через JS присвоение.

Потому что сама по себе установка display: block не является поводом для reflow — браузер ленивый. А вот попытка получить координаты или размер элемента уже вынуждают браузер не лениться и рассчитать эти самые координаты и размер


Но почему сама по себе установка display: block не является поводом для reflow, я уже не знаю. Может, в стандартах это описано, но не читал


ещё как определено — только в CSS коде

Когда элемент display: none, у него нет ни координат, ни размера — независимо от того, чё там в CSS-коде. И не появится, пока браузер не будет вынужден их просчитать (reflow)

Но почему сама по себе установка display: block не является поводом для reflow, я уже не знаю. Может, в стандартах это описано, но не читал

Видимо, в угоду быстродействию. Я думаю, если у нас display: block у элемента в нормальном потоке, reflow будет (или браузер просто поднимет/опустит нижележащий контент, что намного быстрее, однако если у нас этот элемент ещё и имеет float отличный от none, вот тут уже без перестроения никуда). А тут проблема вся в том, что мы оперируем абсолютно позиционированными элементами (в том моём случае так было, и в этой демке тоже). Их если показать или скрыть — ничего ведь в остальном не поменяется. Я вообще больше удивлён, что происходит при обращении к свойству на чтение… Казалось бы, можно было тупо вернуть последний закэшированный размер :)

Ну и потом — почему разработчикам движков не сделать нормальный метод для такого (который бы делал то же самое, но не выглядел как костыль)? Что-то вроде document.reflow()

UPD: убрал position: absolute, ничего вообще не изменилось.
Посмотрел ваш код. Спасибо, теперь всё стало понятно. У меня проблема была именно в том, что браузер делал reflow через некоторое время, а не когда мне было нужно, поэтому приходилось ставить таймауты.

Я кстати немного «испортил» ваш пример: сделал, чтобы первая кнопка работала несмотря на отсутствие этого приёма (задержка в 20 мс даёт результат, в 10 уже нет), а второй кусок кода тоже порезал, выкинув, казалось бы, довольно критичную часть, позволяющую сделать моментальный возврат шарика — но тем не менее почему-то код продолжает идеально работать (тестировал в Firefox 52 ESR, поскольку в Chrome у меня JSFiddle упорно не хочет работать ни в версии 49, ни даже в версии 54). Возможно, секрет заключается в том, что перепозиционирование происходит тогда, когда элемент невидим (вы писали, что при этом не вообще не активируются transitions)?

jsfiddle.net/4Lfawnqy

Кажется, второй кусок кода продолжил работать, потому что установка display: none сбрасывает элемент в «никакое» состояние и при последующем его снятии браузер оказался вынужден брать translateX(0px), несмотря на ненулевой transition-duration (то есть между display='none' и display='' анимация не работала)


Если заменить display: none на visibility: hidden (когда видимости нет, а координаты с размером всё ещё есть), то второй кусок кода таки сломается

потому что установка display: none сбрасывает элемент в «никакое» состояние
И это тоже крайне странно. Это с точки зрения рендера состояние, быть может, «никакое». А с точки зрения правил CSS/свойств style стили очень даже назначены… Мне кажется более логичным ваше предположение про то, что пока display равен none, транзишены игнорируются, и поэтому нет никаких задержек на длину перехода.
Именно состояние рендера и имеет значение
Почему рендер не ориентируется на логическую модель? Да и вы сами попробовали с hidden: смысл происходящего там тот же, но поведение иное.

На самом деле, я сам буквально месяца два назад писал код своего движка, элементы с display: none у меня пропускаются на стадии layout, а элементы с visibility: hidden — только на стадии отрисовки. Я понимаю, почему для элементов с display: none нет рассчитанных размеров — зачем тратить ресурсы, высчитывая их, если это не повлияет на другие элементы, а текущий элемент вообще скрыт. Но в нашем примере речь про координаты, заданные явно, тут размер без разницы.

UPD: хотя в принципе да, вы правы, координаты считаются примерно в том же месте алгоритма, их тоже в этом случае считать незачем.
В общем случае (если не указаны top/bottom/left/right) положение элемента даже с position: absolute зависит от соседей, а делать всякие эвристические анализы, зависит или не зависит в в данном конкретном случае, браузеру скорее всего лень

Кроме того, в середине анимации состояние рендера не соответствует ни начальному состоянию, ни прописанному в CSS-коде, и если вдруг анимацию поменяют в середине, то начинать новую анимацию надо будет с той самой старой середины, так что опираться на CSS-код тоже нельзя
Понятно.

В общем случае (если не указаны top/bottom/left/right) положение элемента даже с position: absolute зависит от соседей
Разве? Вроде только от положения ближайшего по иерархии предка с position: relative/absolute. По умолчанию там нули (left, top, bottom, right), то есть левый верхний угол элемента будет в левом верхнем углу этого самого предка. Я не прав?
UFO just landed and posted this here

В Firefox этот пример, однако, глючит) Если открыть инспектор и задать display: inline для <p> и потом display: inline-block для <div class="abs">, то этот самый abs останется внизу под <p>. А если сделать всё наоборот (сперва inline-block для abs, потом inline для <p>), то abs переедет вправо) А в Chrome abs уезжает вправо в обоих случаях

UFO just landed and posted this here
Хм, прочитал описание по ссылке. Очень интересно. Я всегда считал <br> блочным элементом с нулевой высотой (потому что поведение похоже), сейчас проверил в Хроме — а он инлайновый, внезапно.
То есть его действительно можно невозбранно включать внутрь инлайновых элементов для разбивки на строки. Хотя всё равно в реальной практике я такого ещё не видел, чтобы те же span-ы или что-то подобное содержали внутри <br>. Но в любом случае, это не важно: у нас может быть просто span, естественным образом занимающий несколько строк, и мы имеем право что-то выставить по его нижнему краю с помощью position: absolute.
Хм, интересно. Не понимаю логику, почему сделано именно так. В стандарте про это есть что-то? Было бы интересно почитать, как трактуются значения auto для координат (что это значение значит, если оно не эквивалентно 0, как я считал).
UFO just landed and posted this here
Спасибо, ознакомлюсь.

Ну да, теоретически вы конечно правы. Однако вот на практике — представляете, за 8-10 лет ни разу ещё не использовал при вёрстке position: absolute не указав обе координаты. Ибо зачем такое может понадобиться вообще? :)
Кстати, Chrome тут следует стандарту достаточно вольно (или я сам неверно его понял).

Если я понял правильно, при значениях auto позиция элемента будет такой же, какой она была бы при position: static (другое дело, что при расчёте высоты и ширины родительского элемента наш абсолютно позиционированный элемент не учитывается, отсюда и эффект вылезания за нижнюю границу). Кроме того, если добавить третьего потомка с position: static, то второй наложится точно на него. Отлично.

А теперь добавим в самое начало ещё один элемент с float: left. Ожидается, что наш абсолютно позиционированный элемент будет выведен там же, где был бы в случае нормального потока (по правому краю float элемента). Ан нет, он наложится прямо на него. Такие дела.
Исправил поведение абсолютно позиционируемых элементов, теперь всё выводится по требованиям стандарта)
это еще и парсинг который очень дорогой

Парсинг (разбор на токены) ни разу не дорогой. Там время пропорционально длине исходного текста. Ну замените вы все имена функций на 1-2 символьные комбинации, и переменные заодно (которые и так часто делают короткими). На сколько сократится объём кода? Что-то мне подсказывает, что даже не в 2 раза. Но даже возьмём, что в 2 — парсинг занимает несколько миллисекунд на современном железе. Ну будет не 4 мс, а 8 мс — разве это смертельно?
Справедливости ради, современные браузеры поддерживают специальные map файлы, позволяющие восстановить в отладчике исходный код со стектрейсами, а не отображать минифицированную кашу. Однако возможность такая должна быть. Проблема в том, что почему-то 90-95 процентов разработчиков не используют её, а вот минификацию — используют.

Вот кстати пример из жизни, когда минификация не столько помогает, сколько вредит: есть сторонний проект, на нём есть код, использующий новые фичи. Код не работает в одном из старых браузеров. В случае наличия несжатых исходников — можно было бы изучить реализацию и понять, в чём там дело. А так -берём минифицированный код, смотрим, ставим брейкпоинты (с этим тоже бывают проблемы, особенно становится весело когда целевой браузер не умеет ставить брейкоинты в коде, получившемся после обработки PrettyPrint и добавления переносов, то есть переносы добавляются, но только визуальные, брейкпоинт туда не воткнуть), снова смотрим, через 2 часа плюём в монитор и бросаем это гиблое дело.
Как оказалось, парсер Хрома не позволит вам использовать унарные плюсы и минусы слитно с плюсом или минусом, так что минификатору придётся поставить скобки в любом случае.
Возвращаясь к вопросу — я всё же не понимаю проблемы.
Сейчас браузер не позволит написать нам ни 1++2 (подразумевая, что второй плюс — унарный плюс), ни 5++a. В обоих случаях парсер выдаст ошибку «Invalid left-hand side expression in postfix operation».

Исходя из этой логики, никаких 5++-5 мой движок допускать вообще не должен в принципе (как сейчас не допускается 5+-5). Да, в текущей реализации это отработает как (5++)-5 (а может быть выдаст ошибку, надо тестировать — не уверен, что у меня вообще допускаются два оператора, идущих подряд на этапе парсинга токенов). Но если мы хотим другого поведения, надо ставить скобки.

P.S. Вообще я понял суть проблемы, перечитав таблицу приоритетов. Создаётся неопределённость — непонятно, у нас унарный плюс, унарный минус и сложение, или постфиксный инкремент и вычитание. Но независимо от того, разрешён постфиксный инкремент на литералах или запрещён (в текущих реализациях он запрещён), запись 5++-5 вызовет ошибку, и это совершенно правильно. Другое дело — в текущих реализациях перед литералом можно написать два минуса, и это будет равносильно тому, как если бы не написали ничего (два умножения на -1), а у меня это выдаст совсем другой результат. Но я не очень представляю, зачем писать ровно два (или любое чётное) количество унарных минусов перед числом или переменной. В конце концов, на то что перед переменной это сработает как префиксный инкремент, никто не жалуется?
Учитывая, что tan(pi/2) равно бесконечности, чем вас не устраивает выражение isFinite(tan(Math.PI / 2)) => false? Здравый смысл подсказывает, что это вполне правильное поведение.
Чёрт, я прошу прощения. Опечатался, когда писал комментарий. Возвращается именно true, то есть то же самое, что для любого числа.
Проблема не в функции isFinite, она обрабатывает корректно. Посмотрите, что возвращает Math.tan(Math.PI / 2)

Точно так же Math.tan(Math.PI) не равен 0
Ну вот мы и добрались до причины проблемы (то, что константа Math.PI не выполняет свою функцию из-за ограничений по точности представления). Но мой движок этой проблемы не имеет: там есть некоторый очень малый допуск в виде интервала по входящему аргументу, при попадании угла в который будет возвращаться строго 0 или плюс/минус бесконечность.
Почему вы думаете, что на практике ваше решение будет лучше?
Потому что это то, что ожидает программист (плюс бесконечность, а не то, что выдаёт функция tan в JavaScript сейчас). Кстати, в Java, насколько я помню, сделано так же, как у меня (может не в случае математической функции тангенса, но в функциях, работающих с отрисовкой графики в Java2D — точно).
Вы уверены, что это проблема? Я вот вижу у вас проблему, что для у вас для многих чисел, которые попадают в ваш «очень малый интервал» вернется неправильное значение в виде бесконечностей или нулей.
Есть такая проблема. Но использование таких очень близких к Pi / 2 аргументов, во-первых, не является частым кейсом, во-вторых, программист будет об этом знать, если донести до него информацию.
Ну достаточно так же донести информацию до программиста, что PI/2 в компьютере представить невозможно (большинство и так об этом знают).

Ну вот мы и добрались до причины проблемы


В чем проблема то?
что PI/2 в компьютере представить невозможно

Возможно. Вы же понимаете, что для того, чтобы определить константу, совсем не обязательно уметь вычислять все её цифры после десятичной точки?

В чем проблема то?

В том, что тангенс вычисляется абсолютно неверно.
В том, что тангенс вычисляется абсолютно неверно.


Я вам больше скажу, тангенс в компьютере вычисляется неверно для всех чисел. Вы также будете будете вводить интервалы для PI/3, чтобы получить «ровно» корень из трех?
Думаю, что нет. Но всё-таки точки, дающие на выходе бесконечность — они в каком-то смысле особые. Можно сделать корректный ответ хоть в них?
Нет, нельзя. Оно должно работать одинаково и последовательно. а не по желанию левой пятки человека, который это делает просто потому что хочется, без единственной реальной практической причины
Вам выше уже написали кучу причин, почему текущая реализация работает некорректно, которые вы в упор не хотите видеть, к сожалению.

Ваша аппеляция к «а давайте тогда сделаем в Pi/3 ровно корень из трёх» имеет не особо много смысла хотя бы потому, что и сам корень из трёх имеет весьма приближённое значение, и при возведении в квадрат не даст 3.
Вы написали лишь одну причину. И ни одной практической причины

Ваша аппеляция к «а давайте тогда сделаем в Pi/3 ровно корень из трёх» имеет не особо много смысла хотя бы потому
Сами придумали, сами опровергли
Сами придумали, сами опровергли

Это вы предложили про корень из трёх, я-то что?)

Вы написали лишь одну причину.

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

Точка экстремума, опять же (Pi/3 таковой не является).
Я вам больше скажу, тангенс в компьютере вычисляется неверно для всех чисел. Вы также будете будете вводить интервалы для PI/3, чтобы получить «ровно» корень из трех?

Окей, вы не предложили, а задали наводящий вопрос. Но из этого вопроса я заключил, что вы предлагаете или отказаться от всех корректировок, или добавить корректировку и для Pi/3. Разве вы не это имели в виду?
Разве вы не это имели в виду?

Я такого вообще не писал.

Но теперь вы возвращаете совершенно некорректное значение для углов, близких к Pi/2.
Причем эта бесконечность отравит все последующие вычисления, где-то мутировав до NaN, и в итоге все будет очень плохо. При чем программист-то этого, руководствуясь стандартом, не ожидал.

Для углов, очень близких к Pi/2 (дельту можно взять очень маленькую, меньше сотой градуса).

Да, это плохо, но имхо не катастрофично.

Впрочем, я сегодня посмотрел — похоже, я вас всех дезинформировал, прошу прощения. В моём коде применён был иной подход, анализируется именно получившееся значение нативной функции tan из Java. То есть точки, отличные от Pi/2, не пострадают.
Опять же — а если наше большое число, которое бесконечностью не является, вылетит за пределы допустимого диапазона — тоже ничего хорошего из этого не выйдет.

Смотрите, бесконечность хороша тем, что операции с ней безопасны. К ней можно прибавить число, её можно умножить на число. Можно даже умножить бесконечность на бесконечность. И при этом всё будет замечательно (пока не начнём делить, тогда получим NaN). Но переполнения в этом случае точно не случится.

Не знаю, что там написано в стандарте на этот счёт, но хороший программист, имхо, прежде чем дальше с этим результатом что-то делать — поставит проверку на допустимость такого действия. Случай с бесконечностью в результате «ловить» гораздо красивее, чем случай с числом 16331239353195370, вам не кажется?
Ещё раз поясню (видимо, я недостаточно понятно объяснил свою позицию):

Предположим, я — прикладной программист на JavaScript. Я хочу проверить, получилась ли у меня бесконечность после вычисления тангенса. В текущей реализации (возьмём имплементацию Chrome) у меня есть три варианта действий:

1. Сверяться с неким очень большим целым числом, обнаруженным при вычислении тангенса Pi/2 эмпирически. (где гарантия, что однажды оно не поменяется? оно даже не равно максимальному целому в рамках какой-либо длины).
2. Считать тангенс Pi/2 прямо перед проверкой. Выглядит не очень, да и с точки зрения производительности — такое себе.
3. Поставить эту проверку до вычисления тангенса. В таком случае мы получим код вроде

if (Math.abs(th - Math.PI/2) < 0.0001) { ... }


Окей, третий вариант неплох. Но зачем заставлять программиста писать это каждый раз?

В моей реализации эти действия делает интерпретатор (программисту ни о чём беспокоиться не нужно), и в случае аргумента, близкого к Pi/2 вернётся ровно то, что программист ожидает получить (плюс бесконечность).

Единственное что нужно доработать — всё-таки стоит создать две особых сущности для плюс бесконечности и минус бесконечности, сделать их полями Number, и возвращать их (а ещё научить с ними работать функции isNaN и isFinite). Потому что сейчас у меня возвращается NaN, а это не совсем идеально — хотя бы тем, что нельзя проверить знак результата.
В моей реализации эти действия делает интерпретатор (программисту ни о чём беспокоиться не нужно), и в случае аргумента, близкого к Pi/2 вернётся ровно то, что программист ожидает получить (плюс бесконечность)


Окей, ваш интерпретатор готов гарантировать (я ожидаю получать правильный результат), что

(tan(PI/3))^2 == 3? Сомневаюсь, а то что
(tan(2*PI/3))^-2 == 3? Я могу таких примеров бесконечное множество приводить
Так это некорректный пример. Я обсуждал конкретно тангенс и котангенс, вполне две конкретные тригонометрические функции. А вы ссылаетесь на то, что квадратный корень из любого числа имеет некоторую степень точности, и при возведении обратно в квадрат можно не получить исходное число, а получить например 2.9999999998 (кстати, я тестировал такие вещи, вроде как Java не имеет такой проблемы, а интерпретатор написан на ней).

Забудьте про тангенс, введите в консоль Хрома Math.sqrt(3) * Math.sqrt(3). Получается 3? У меня нет :)

P.S. На самом деле, из-за особенностей вычислительных алгоритмов разных функций, у нас не будет выполняться
Math.tan(Math.PI/3) == Math.sqrt(3).
Я посчитал разность, получилось -4.440892098500626e-16. Но с этим ничего нельзя поделать, тут и мой интерпретатор ничего не предложит. С этим не справится ни Java, ни мат. библиотека Chrome, к сожалению. Тут уже нужен совершенно специальный мат. софт.
Так вы пытаетесь решить «проблему» неточного представления PI/2 в компьютере и последующего неточно вычисления тангенса, но при этом говорите, что квадрат вычисляется неверно это нормально? Что за двойные стандарты? PI/2 тоже имеет «некоторую степень точности» и tan имеет «некоторую степень точности»

Если вы ожидаете, что tan(PI/2) должно возвращать бесконечность в компьютере, то я например ожидаю, что tan(PI/2-epsilon) не будет возвращать бесконечность, как вы будете решать эту «проблему»? Ведь в вашей имплементации все числа близкие к PI/2 будут давать бесконечность?
PI/2 тоже имеет «некоторую степень точности» и tan имеет «некоторую степень точности»

Просто проблему, которую описал я, решить можно (трактуя Pi не как приближённое float/double значение, а как особую сущность). А проблему, поставленную вами, решить крайне трудно (и не факт, что это нужно вообще для JS движка).

Если вы ожидаете, что tan(PI/2) должно возвращать бесконечность в компьютере, то я например ожидаю, что tan(PI/2-epsilon) не будет возвращать бесконечность, как вы будете решать эту «проблему»? Ведь в вашей имплементации все числа близкие к PI/2 будут давать бесконечность?

Согласен, это косяк. Но всё же шансы, что вы будете делать какие-то осмысленные вычисления с числами, очень близкими к Pi/2 (где вам нужны будут реальные очень большие тангенсы как они есть), довольно мала. Я вижу один вариант такого применения — для сравнения исходных аргументов. Но почему бы просто не сравнивать сами аргументы? Они тоже неплохо сравниваются.
Шансы того, что кто-то будет делать осмысленные вычисления, где понадобится точное значение тангенса пи/2 ещё меньше. Единственная осмысленная операция с ним, это деление на него, но тут достаточно очень большого числа (которое и выдаёт имплементация в chrome) чтобы получить число достаточно близкое к нулю.
Шансы того, что кто-то будет делать осмысленные вычисления, где понадобится точное значение тангенса пи/2 ещё меньше.

Вы к тому, что просто вместо вычисления тангенса можно сразу записать в коде его результат через Number.POSITIVE_INFINITY? Ну в целом — да, согласен. Но всё же иногда это может быть нужно. Вот вам пример: есть у нас угол, кратный Pi/4 (или Pi/8, Pi/16 и так далее). Происходит умножение, и после него мы считаем тангенс. В этом случае «захардкодить» результат нельзя.

Единственная осмысленная операция с ним, это деление на него, но тут достаточно очень большого числа (которое и выдаёт имплементация в chrome) чтобы получить число достаточно близкое к нулю.

Почему только деление? Мало ли, что пользователь захочет сделать потом. Вот захочет он умножить на число, большее нуля, например. В случае, если у него бесконечность — он просто отловит этот случай и не будет умножать (или умножит и получит то же самое, в Chrome это отлично работает). А умножив результат тангенса из Chrome? В лучшем случае — просто непонятное больше число. В худшем — переполнение.
Предположим, я — прикладной программист на JavaScript. Я хочу проверить, получилась ли у меня бесконечность после вычисления тангенса

И зачем ЭТО прикладному программисту на JS?
Ну мало ли, может, алгоритм требует. Например, для последующего деления может быть важно, чтобы получился именно ноль, а не число, очень близкое к нему, как писали выше (1 / Number.POSITIVE_INFINITY даёт именно 0).

Вы лучше скажите, зачем прикладному программисту тангенсы чисел очень большой величины, но конечные. Если мы что-то строим на плоскости, например — то все углы близкие к 90 градусам можно считать равными 90 градусов — всё равно у нас пиксельная сетка, и размеры дисплея не позволят нарисовать такой угол так, чтобы он не был идентичен вертикальной прямой, а если и позволят — будут большие проблемы в виде ступенек или размыленности.
в случае аргумента, близкого к Pi/2 вернётся ровно то, что программист ожидает получить (плюс бесконечность).

Почему плюс, а не минус? Тангенс в этой точке имеет разрыв и не определён, так как слева он уходит в плюс бесконечность, а справа — в минус. Так что возвращаться тогда уж должен NaN, но он с прикладной точки зрения бесполезен чуть менее, чем полностью.

А ведь и правда. Смотря с какой стороны подходим) В Pi/2 и правда, следуя строгой логике, значения нет. Но всё же текущая реализация выдаёт положительное число (кстати, внезапно — в Java всё с точностью до наоборот, там результат отрицательный).
UFO just landed and posted this here
Кроме того, операция инкремента по стандарту требует lvalue, а литерал — это rvalue

Ну, тот же IE в своё время многое делал не так, как указано в стандартах. Правда, это для него плохо кончилось)

Между прочим, в стандарте для функции isFinite сказано: «If num is NaN, +∞, or -∞, return false».

Так в том-то и дело: там плюс бесконечность, а возвращается true.
UFO just landed and posted this here
Там, где false — имелось в виду true, поторопился, когда писал)
Так вот, внимание — isFinite(tan(Math.PI / 2)) возвращает false!

Простите, но я вот решил проверить и Хром говорит, что вы обманываете нас.
isFinite(Math.tan(Math.PI / 2)); // true
Я же уже исправился. Проблема в том, что я поторопился, когда писал комментарий. Я почему-то прочитал название функции как isInfinite() (знаю, это ужасно глупо, но мне показалось, что проверяется именно бесконечность, а не конечность). И потому (я перед этим уже точно убедился, что результат работы неверный) написал false, чтобы в тексте была логика и я не противоречил сам себе.

На самом деле и функция проверяет другое, и ответ другой. Но от этого он не становится правильным.
UFO just landed and posted this here
UFO just landed and posted this here

Вообще, если говорить об альтернативных движках, то NetSurf на первый взгляд выглядит поинтереснее сабжа: свой HTML-парсер есть, CSS-парсер тоже есть (соответствие стандартам не проверял), JS-движок Duktape с последними фишками ES2015+. Затыки, естественно, на самом сложном: рендер (в отличие от сабжа) есть и рисует примерно на уровне IE8 (лично мне этого достаточно, у меня успешно получается верстать под NetSurf), а вот полноценного DOM API и событий (ещё) нет, из-за чего JS бесполезен, несмотря на его наличие

В качестве инструмента для рендеринга будете использовать Skia, Cairo, AGG или что-то самописное?

Почему у вас в коде абсолютно везде используется передача копии объектов в функции? Никак не используются преимущества С++ по эффективной работе с ссылками на объекты.
Мало того что это абсолютно неэффективно, так еще и во многих случаях может ломать код.

Например здесь сложно сказать, что произойдет после выхода из функции так как по факту объект str будет уничтожен сразу после выхода из функции.
Token* fromMisc(DOMString str)
{
MiscToken* misc = new MiscToken();
misc->data = str;
return (Token*)misc;
}
Token* fromText(DOMString str)
{
Text* text = new Text();
text->text = str;
return (Token*)text;
}

Это работает только потому-что у объекта DOMString нету деструктора! В итоге имеет на каждый чих копирование огромной строки и бесконечно большую утечку памяти.

Лучше наверное все таки использовать? (ну и конечно же написать нормальные деструкторы)
const DOMString& str
Спасибо большое, сейчас исправлю!
UFO just landed and posted this here
Каюсь, вы правы насчёт деструктора, там же в коде обычный std::string под капотом. По привычке подумал — раз есть свой string значит это обертка над raw char* — быстро проглядел и заметил что деструктор пустой. Но это тоже плохо на самом деле, убивается огромный пласт оптимизаций, move конструкторов написанных для std::string.

Для вашего примера с временными объектами придумали move-семантику.

Тем не менее вопрос об абсолютно неэффективной работе со строками и постоянным копированием (даже в тех функциях происходит два копирования которые можно, и нужно избегать) остаётся открытым
UFO just landed and posted this here
Я бы так сказал, из названия класса DOMString для меня понятно следующее:

— эта самая строка в ходе парсинга и разбора не должна меняться — следовательно она константа
— использований метода типа fromMisc(«смотри, ма, я временный объект») не будет, так как это не имеет смысла (все таки кто из головы в коде будет придумывать DOMString?)

На мой взгляд нормальной реализацией тут было бы просто написать обертку над const char * и запретить вообще любое копирование и перемещение (=delete). Использовать const DOMString& и проследить чтобы время жизни объекта совпадало бы с вызовом функции парсинга. Если уж хочется сохранять какие то куски строк в токенах как делает автор, то можно оставить возможность отдавать константные слайсы этого DOMString (без выделения новой памяти).

Если юз-кейс отличается от описанного выше — легче использовать std::string
UFO just landed and posted this here
Ох, и накинулись на человека — и это не то и то им не так. Ну, реализовал он малую часть, показывает что есть. Сделает рендеринг — покажет и его. Зачем пинать-то? Посмотрит на ваше злословие и забросит еще.
По моему ещё не накинулись. Не увидел ни одного неадекватного комментария с критикой.
Просто, действительно выглядит пока так что автор замахнулся на задачу, для которой ещё не созрел. Однако, в любом случае это будет отличным опытом, и накидываться не нужно — так никто этого и не делает.
Да, есть отчетливое ощущение, что автор на самом деле не понимает, во что на самом деле ввязался и на что претендует.
UFO just landed and posted this here
Для 13 лет сойдёт. Я видал людей, которые в 30 лет не лучше пишут. И, кстати, если он сам рисовал оформление для своего сайта, то я считаю, у него есть способности к дизайну.
UFO just landed and posted this here
UFO just landed and posted this here
У меня только один вопрос, ограниченность функционала позволит веб-приложениям (с оглядкой на ограниченную совместимость) работать заметно быстрее и требовать меньше ресурсов, хотя ты в разы?

Если да, то пилите! это годное дело.

Точно помню, старый движок opera работал на eeepc900 вполне сносно, когда как то же веб-приложение на последнем firefox (буквально в этом году проверял, жаль железка сломалась) тормозило безбожно.

Между прочим, такой проект был бы оправдан как замена тяжелому electron, а то что ни проект так таскают с собой 60мб хромиум (в установщике) и 30-50 мб оперативки минимум на одно окно приложения и мегааппетиты на просто ui.

p.s. постарайтесь ограничивать функционал там где это оправдано именно для скорости работы движка, если что, популярные фреймворки javascript для веб можно в будущем допилить до поддержки нового движка…
Автор, вы смотрели на Servo перед началом разработки? Это как раз новый движок и у него уже много чего реализовано.
Нет. Но смысл же вашего движка в отсутствии легаси с 90х и, возможно, новых подходов к разработке? С этой точки зрения Servo кажется отличным вариантом.
Скорее смысл его движка — в самообучении. Если верить тому, что автор пишет в комментариях к PR, то он в седьмом классе. Согласитесь, что текущие начинания и достижения (хотя бы в знаниях языка) уже чрезвычайно офигительные для седьмого класса?

Да, с вероятностью 99% этот проект будет заброшен, но свою задачу он выполнит. К окончанию школы у человека будет нехилый фундамент прикладного программирования.
UFO just landed and posted this here
Вы хотя бы плюсы знали. А у нас программирование на Паскале началось в 9-ом классе, мне тогда уже было 14, а до этого я вообще ни на чём программировать не умел. Веб начал изучать в 14 лет, в конце 8-ого класса, всё на той же школьной информатике. А тут в 13 лет человек пишет то, что я написал практически в 26 — при этом судя по описанию, у него реализовано лучше, и пишет он на плюсах, которые для данного проекта подходят куда лучше (да и вообще являются очень непростым в изучении языком) :)
То что человек крут и «далеко пойдёт» — это очевидно. Вот только он должен перейти стадию, когда поймёт, что создавать в одиночку движок — бессмысленно.

Ибо одному можно создать каркас (то самые 90% задачи, которые пишутся за 10% времени), но чтобы из этого получился браузер — нужен труд десятков людей.

Вот как их предполагается привлекать?

P.S. В общем я крайне положительно отношусь к перспективам FlightBlaze и крайне отрицательно — к перспективам описываемого движка.
UFO just landed and posted this here
А можете объяснить, почему реализовав 90 процентов функционала силами 1-2 людей, нельзя считать получившееся браузером и даже движком? Чего не хватает, и почему нельзя это добить сторонними библиотеками (то же чтение картинок, как пример, почти во всех известных мне браузерах это сторонняя либа, а также поддержка ZIP, MIME, проигрывание мультимедиа и всё такое).
Я бы кстати помог автору данного проекта, если бы знал плюсы. Привлекать легко — на энтузиазме и вере в проект. Как и в любом OpenSource типа VLC или Chromium, там куча людей коммитят код просто для себя, не получая за это вознаграждение.
О, я тоже пытался писать свой движок в начале этого года. Сделал HTML и CSS парсер, построение DOM, JS интерпретатор и частично рендер. Реализовывал всё на Java + Swing. В какой-то момент понял, что если реализовывать грамотно работу z-index — всё будет работать очень медленно, и забросил это дело…
Чтобы все работало быстро, надо писать на высоко производительном языке, например на C++ или Rust. Java в этом плане очень сильно отстает. Для работы z-index нужно, чтобы каждый элемент рендерился на своём слое, а затем сравнивая z-index каждого слоя, сортировать их и вывести на экран.
Это всё понятно. Там проблема немного в другом)

Дело в том, что я изначально поставил задачу написать браузер, который будет корректно работать под Windows XP и выводить красивый, резкий текст. К сожалению, опыт показал, что при использовании Swing сделать это можно только используя «нативные» JLabel, но никак не низкоуровневыми методами вывода текста на графический контекст типа drawString. Однако такой подход не позволял отсекать содержимое при overflow: hidden: панели-слои у меня были неограниченного размера, и включение лейблов в эти панели никак не позволяло их обрезать. Тогда я применил комбинированный подход, выводя текст в менее чётком варианте только тогда, когда его реально нужно обрезать (при overflow равном scroll или hidden). Но проблема в том, что при наличии множества контекстов наложения с разными z-index при изменении практически любого z-index у элемента внутри одного из контекстов придётся всё перерисовать, применив новый порядок наложения.

У меня возникли какие-то проблемы, и я не смог заставить работать штатный механизм z-order в Swing (фрагменты текста-то у меня через JLabel сделаны!) иначе как в момент добавления элемента в контейнер. А при каждой смене z-index элемента удалять и по новой добавлять всё — безумно дорогая операция. Так что увы…
Обычно есть расширенный метод вывода графики (включая текст) где есть параметр для отсечения, т.е. передаешь координаты прямоугольника внутри которого все рисуется, а то что выходит за этот прямоугольник, будет пропускаться.
В Java тоже всё это есть. Только вот, зараза такая, при этом субпиксельное сглаживание текста не работает. А вместо него работает монохромное (Grayscale) — и на выходе имеем мыло.

Кстати, данная проблема присутствует на любой ОС и на любой версии Java (пробовал версии 6, 7, 8 и вроде даже 9).
Для работы z-index нужно, чтобы каждый элемент рендерился на своём слое

О, если бы всё было так просто. Объединение в слои как раз и придумали затем, чтобы не создавать на каждый чих отдельного слоя. Почитайте раздел «Краткая история отрисовки и компоновки» в статье habr.com/post/340176. Кроме хорошего объяснения в статье есть хорошие узнаваемые картинки от Лин Кларк :)
>производительном языке C++ или Rust
>Java в этом плане очень сильно отстает

Вот так откровения. Вообще говоря расклад по скорости такой: 1. плюсы 2. жабка 3. раст.
Речь не про микробенчмарки, а большие проекты. Хотя какие большие проекты у раста? Сферический тузик в вакууме, всех порвал… в теории.

Java быстрее раста? какие-нибудь ссылки можно?

Выборочно читаете?
«Хотя какие большие проекты у раста?»
Не согласны? Ну давайте вы ссылки на аналоги Cassandra, Neo4j, Lucene, JBOSS и тд
Когда такое появится, тогда и можно будет говорить про скорость не в микробенчмарках.

В целом, уверен, что аналог более-менее грамотно написанного софта, писанного под JBOSS, на Расте будет из костылей, велосипедов, г и палок. С соответствующей производительностью.

1) Servo сойдет?
2) Я понял вашу точку зрения. Но в таком случае производительность раста и джавы не сравнимы вообще, и любой их порядок, в т.ч. ваш, некорректен.

>Но в таком случае производительность раста и джавы не сравнимы вообще

Неубедительно вчера написал. Вообще говоря, представление о низкой скорости раста у меня сложилось глядя на масштабные бенчмарки с несколькими языками. По тестам выходит что раст телепается где-то на уровне go и сильно отстаёт даже от плюсов, не говоря о анси си. Жабка, как известно, из «второсортных языков» таки самая быстрая. Повторяюсь, речь не про микробенчмарки, а более-менее большие проекты.
UFO just landed and posted this here
А можно увидеть эти бенчмарки?
>Java быстрее раста? какие-нибудь ссылки можно?

Гуглить GraalVM nativeimage. Не быстрее ассемблера, конечно ) Но при грамотном подходе не медленнее Си и гораздо удобнее в разработке и поддержке.

Отсутствуют такие фичи, как динамическая подгрузка кода и финализаторы.
Т.е. управлять ресурсами предлагается вручную?
Насколько я вижу, GC никуда не девается.
Интересно, как Java с GC и без C++-style шаблонов может работать на уровне плюсов.

>Т.е. управлять ресурсами предлагается вручную?
Нет. В Java есть AutoCloseable, финализаторы в Java это про другое их давно никто не использует. Динамическая подгрузка это вы наверное про Dynamic Class Loading?

>Насколько я вижу, GC никуда не девается.
Да, она на месте.

>Интересно, как Java с GC и без C++-style шаблонов может работать на уровне плюсов.
Элементарно, я поэтому и написал при «грамотном подходе». Например, один из подходов использовать пул объектов, там где очень часто нужно удалять и создавать новые объекты. Или вручную размещать структуры в массивах, взяв управление по размещению/освобождению данных в свои руки (но это больше про индексы).

Еще можно использовать RingBuffer и т.д. Опять же в последнее время в Java популярна off-heap техника, когда можно управлять памятью вручную вне владений GC.

Такие подходы вполне можно использовать в узких местах при написании браузера. Поэтому не вижу ничего страшного сделать новый браузер на GraalVM с nativeimage.
  1. То есть предлагается писать собственный jemalloc?
  2. Давайте на примере (псевдокод)


    class CP {
    HANDLE h;
    CP(options) {
       h = CreateProcess(options.path, options.argv, options.env, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    
    }  
    
    // some functions like get_stdout()
    ~CP() {
       CloseHandle(h);
    }
    }


Типичный RAII — в конструкторе выделяем ресурс (в д.с. дочерний процесс), в деструкторе освобождаем.
Таким образом я могу писать код вида


    ChildProcess cp("ls", {"-a"}, {});
    print(cp.get_stdout());
    //resources are cleaned automatically

Как такое переносится на джаву? Для простых случаев кажется есть try-finally, а для более сложных?

Для более сложных в Java есть try with resources.

Костыль тот ещё, но… 98% потребностей закрывает. А RIAA закрывает 99%, всё равно не 100%, так что, в общем, не бог весть какая проблема…
>То есть предлагается писать собственный jemalloc?
Нет. Основную работу делает GC. Сейчас есть GC с гарантированными 10 ms паузами. Но там, где есть узкие места, можно вручную выделять и освобождать память. Создав узкоспециализированный оптимизированный под данную задачу аллокатор.

>Как такое переносится на джаву?
>для более сложных?
Для более сложных управляете вручную или полагаетесь на IoC (dependency injection). Последнее решение очень популярно в Java. IoC автоматически загружает и выгружает (при завершении треда или по другим причинам) объекты, поэтому может, в том числе, выполнять функции деструктора.
  1. Тред вроде бы начался со сложных RAII объектов, которые не могут управляться обычным GC, т.к. он не дает гарантий по вызову деструктора. Например, вышеупомянутый класс CP, если управлять им с помощью сборщика мусора, при активном использовании просто забьет таблицу процессов. При этом сборщик мусора даже не попробует начать почесываться: память свободна на 99,9999%.
  2. По-моему, DI не требует использования DI container'а (вы же его имели в виду?).
  3. А какие еще есть причины, кроме завершения потока? К примеру, выход объекта из области видимости?
>Например, вышеупомянутый класс CP, если управлять им с помощью сборщика мусора
В джаве другой подход. Например, в JDK есть Process API, который не требует очистки ресурсов пользователем при создании аналога CP в джаве. Т.е. вы просто запускаете нужный вам процесс и не паритесь за его ресурсы.

Если копнёте Process API, то увидите, что всё построено вокруг асинхронных проверок завершения процесса. Буквально в пул тредов добавляется Runnable проверяющий завершение процесса и очищающий его ресурсы. Сохраняя его out до выхода объекта из области видимости GC.

Такой подход отчасти позволяет писать примерно так process.onExit().thenAccept(p -> ...)

У меня к сожалению нет опыта разработки на С++, чтобы показать как схожие проблемы решаются на Java. Но думаю выше приведенный пример отчасти показывает различие в подходах.

>А какие еще есть причины, кроме завершения потока?
Вылет по эксепшену. DI не настолько круты, чтобы контролировать выход объекта из области видимости. При желании, конечно можно сделать троллейбус из буханки, но не для этого задумывались DI.
  1. Ок. Я привел плохой пример, т.к. сразу после завершения дочернего процесса уже можно сделать всякие CloseHandle.
  2. Тогда давайте еще более натянутый пример:))
    класс KVM (KuchaVM) — поднимает 100500 виртуалок в облаке и выставляет что-то вроде тредпула наружу.
  3. process.onExit().thenAccept(p -> ...)
    В плюсах можно писать точно так же, если предусмотреть что-нибудь вроде std::future<long long> on_exit()(ни разу не писал такое, поэтому про детали говорить не могу).

  4. Ну вот. DI не позволяют сконструировать замену RAII.
  5. Кстати, часто ли вы встречали сложные лафйтаймы объектов, которые нельзя выразить с помощью unique_ptr / shared_ptr?
>поднимает 100500 виртуалок в облаке и выставляет что-то вроде тредпула наружу

Вручную пишите выделение и освобождение ресурсов. Запихивать такие вещи в деструкторы это путь к не очевидным ошибкам. Отчасти, начинаю понимать, почему в Java метод finalize начиная с 9-ки стал deprecated.

Чем больше в ЯП неявного поведения, тем сложнее такой код поддерживать.

>Кстати, часто ли вы встречали сложные лафйтаймы объектов, которые нельзя выразить с помощью unique_ptr / shared_ptr?

Вы не понимаете сути проблемы. GC позволяет лишний раз не думать и увеличивает скорость разработки. Делает код проще, что означает возможность рефакторинга и простой доработки кода в будущем.

Ручное управление памятью это прошлый век. Такой подход необходим только в узких местах или в очень нишевых областях. В прикладном ПО можно без опасений использовать современные GC. Затыки по перформансу будут совсем в других местах.

Нарпример, вот код который я иногда пишу:


void dfs(const vector<int>& g, vector<bool>& used, int v) {
    //...
}
int main() {
     //read
    dfs(g, used, 0);
}

Без никакого GC.


GC позволяет лишний раз не думать и увеличивает скорость разработки. Делает код проще, что означает возможность рефакторинга и простой доработки кода в будущем.

Где вы тут видите необходимость думать над очисткой? ее тут нет. При выходе из ф-ции main будет вызван деструкторы у g и used, и вся память будет освобождена.
Так же как и в варианте с GC. Но у меня есть деструкторы а у вас нет.
Получается, что как только появляется объект, потребляющий внешние ресурсы (неуправляемая память, файлы, процессы, виртуалки в облаке), вам необходимо использовать какие-то новые конструкции(try-with-resources либо вообще ручное управление foo.close(), что имхо не оч), а мне — нет. Если я написал самый лучший в мире сет, который не делает утечек, то я могу спокойно положить в него объекты вышеупомянутых CP & KVM. А вам придется добавлять костыли для поддержки IClosable. Кстати говоря, есть ли они в стандартной библиотеке? Можно ли сделать ArrayList таких объектов, чтобы он корректно обрабатывал .close()? (НЯП джаву, ответ — нет).

UFO just landed and posted this here

Это вспомогательный массив, который надо спустить вниз по рекурсии. Да я знаю что это говнокод, но это лучшее что имеет смысл писать на олимпиадах.

>Где вы тут видите необходимость думать над очисткой? ее тут нет.
Ну здесь нет, а где-то есть. Еще раз GC позволяет делать код проще. Упрощает рефакторинг и долгосрочную поддержку. Иначе GC ЯП не стали бы настолько популярными.

>Но у меня есть деструкторы а у вас нет.
Я вам еще раз скажу — неявное поведение это путь к неявным ошибкам и сложностям в рефакторинге. Сложности в чтении и поддержки кода.

Через #close метод я смогу найти очистку ресурсов в коде с помощью IDE. Очистка через деструктор этого не позволяет, тем самым усложняется понимание кода, что ведёт к ошибкам.
  1. Я знаю один объективный аргумент — снижается порог входа. Какие еще?


  2. Я могу сказать ровно то же самое что вы сейчас сказали, и показать что самое лучшее — malloc / free. Потому что все явно, везде можно всюду перейти, и т.д.


  3. Вы не ответили на один из моих вопросов. Сколько строк кода нужно в джаве чтобы освободить список файлов?


  4. Почему вы считаете логичным, что один ресурс, т.е. память, управляется GC, а остальные — почти вручную (путем .close())?
    Деструкторы тут более консистентны.


>Я знаю один объективный аргумент — снижается порог входа. Какие еще?

— упрощается рефакторирнг
— код легче читать и поддерживать
— увеличивается скорость разработки
— уменьшается кол-во ошибок с выделением/освобождением памяти

>Я могу сказать ровно то же самое что вы сейчас сказали, и показать что самое лучшее — malloc / free.

Вы не сможете с помощью этого решения найти в коде выделение памяти для конкретного объекта. Т.е. у вас в методе есть ссылка и IDE не скажет вам где для неё выделялась память и где она освобождается.

Если эта проблема решится хотя бы на уровне IDE, то я только за malloc/free и в тот же день буду с пренебрежением относиться к ЯП с GC.

Более того я периодически думаю насколько возможно сделать подобное решение. Но пока нет времени заняться этим вплотную.

>Вы не ответили на один из моих вопросов. Сколько строк кода нужно в джаве чтобы освободить список файлов?

Если для вас важны строки кода, а не простота чтения и поддержка кода. То мы с вами живём в разных вселенных. Значит вы еще не сталкивались с легаси и объемными кодовыми базами.

>Почему вы считаете логичным, что один ресурс, т.е. память, управляется GC, а остальные — почти вручную (путем .close())?

Потому что это хорошо работает. Если у вас потекли объекты, то хрен с ними, обычно это не критично и приложение может продолжать работу.

Но если у вас потекли ресурсы, хуже того вы по ошибке что-то не то снесли. То пользователь будет не в восторге.
Он учитывает любую вашу ошибку.
Например, вы забыли поставить кавычки, набирая атрибут
Движок вас поймет, есть значение атрибута написано без пробелов
Вы можете не закрывать тег, когда это не обязательно


История ничему не учит? Опять на те же грабли наступать?
Хотите повторить судьбу IE?
UFO just landed and posted this here
Да блин… что IE не так?) Он то, как раз единственный работал _СТРОГО_ по спекам, не любили его совсем за другие вещи и только потом это просто стало тупо модным. Ну из серии — *а за что? потомушто.* :)
IE работал как ему хотелось, и пока он занимал 80%+ рынка, все бегали за микрософтом и уговаривали дать стандартны по которым они рендерят. А микрософт хрен на всех забил.
Но потом он потерял рынок и вот только после этого начал стандарты поддерживать.
Вы можете не закрывать тег, когда это не обязательно
Неужели вы стимулируете криворуких макак? Есть прекрасный XHTML 5 — фичи HTML и строгость и расширяемость XML! Чего народ так не любит XHTML? Появление XHTML 1.0 я воспринял как праздник! А массы не взлюбили, теги им закрывать лень!
Попробую объяснить, почему я считаю что строгий xml не нужен.

Все как то забыли, почему создавались такие языки разметки как xml — чтобы быть human readable, это первопричина, а так как используют html в основном люди (как разработчики) так и смотерть нужно на их потребности и удобство… Если не закрывать теги не проблема для парсера — то почему нет? это ведь удобно!

p.s. если вам нужна строгость, то я за реализацию бинарного стандарта, в который будет проводиться компиляция на этапе деплоя веб-приложения на сервер… как минимум это будет эффективнее работать на уровне веб-браузеров, особено если стандарт будет максимально строгий, и лишен исторических наслоений.
UFO just landed and posted this here
UFO just landed and posted this here
На «закопали» и на «признали».
UFO just landed and posted this here

Тем не менее даже в последней спецификации HTML 5.2 (2017 год, однако) посвящён целый раздел XML-синтаксису: https://www.w3.org/TR/html52/xhtml.html


И цитата из этой спецификации:


This specification defines the latest version of the XHTML syntax, known simply as "XHTML".
Автор молодец, плюсую. Каждый программист должен в жизни попробовать написать ОС, браузер, или, на худой конец, язык программирования. Всегда найдутся те, кто скажет что это уже все написано и никому не надо, но не надо позволять им себя останавливать.
А нюансы парсинга кавычек можно всегда подправить, это мелочи.
Язык программирования из всего этого — проще всего. Почему? Потому что:
* ОС — прослойка между железом и юзерспейсом. Юзерспейс можно придумать любой, а вот железо — ой. Делай что есть в реальном мире.
* Браузеры — надо следовать стандартам. Огромным.

В языке программирования же всё предельно просто — как придумаешь, так и будет. Так что для «попробовать свои силы» — язык программирования самый подъёмный. На выходе будет что-то, что будет работать. Удобно или нет — вопрос открытый.
UFO just landed and posted this here
Каждый программист должен в жизни попробовать написать ОС, браузер, или, на худой конец, язык программирования.

При этом — насколько он хорош как программист, определяется пониманием момента, когда надо остановиться. Тут как в фотографии — передержка гибельна.
Линус выкатил свой прототип в возрасте 22 лет:
From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds)
Newsgroups: comp.os.minix
Subject: What would you like to see most in minix?
Summary: small poll for my new operating system
Message-ID: <1991Aug25.205708.9541@klaava.Helsinki.FI>
Date: 25 Aug 91 20:57:08 GMT
Organization: University of Helsinki

Hello everybody out there using minix –

I’m doing a (free) operating system (just a hobby, won’t be big and
professional like gnu) for 386(486) AT clones. This has been brewing
since april, and is starting to get ready. I’d like any feedback on
things people like/dislike in minix, as my OS resembles it somewhat
(same physical layout of the file-system (due to practical reasons)
among other things).

I’ve currently ported bash(1.08) and gcc(1.40), and things seem to work.
This implies that I’ll get something practical within a few months, and
I’d like to know what features most people would want. Any suggestions
are welcome, but I won’t promise I’ll implement them

Linus (torvalds@kruuna.helsinki.fi)

PS. Yes – it’s free of any minix code, and it has a multi-threaded fs.
It is NOT protable (uses 386 task switching etc), and it probably never
will support anything other than AT-harddisks, as that’s all I have :-(.


Интересно, что бы ему написали комментаторы с хабра?
Ваша фамилия есть в коде ядра Linux? (моя есть)

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

Кроме того, крайне важен фактор исторического момента. Открыть что-то новое в математике триста лет назад было несравнимо проще, чем сейчас. И браузер с осью 25 лет назад были гораздо проще нынешних (хотя конечно всё равно сложны).
Сомневаюсь, что у студента Линуса в 22 года был сильно качественный код.
Насчет сложности — в 1991 году все еще сидели под однозадачным ДОС. Даже Windows 3.1 еще не появился. Не было еще виртуалок и эмуляторов. Линус тогда замахнулся на архисложную по тем временам задачу. Но он правда выкатил Линукс с уже работающим башем и gcc. Может поэтому и взлетело.
UFO just landed and posted this here
Как раз сейчас — это задача архисложная. В те времена — всё гораздо проще было. Для того, чтобы на современной системе показать одну букву на экране нужно больше кода, чем всё ядро Linux первой версии содержало. Хорошо если не больше, чем весь тогдашний дистрибутив со всеми библиотеками, GCC и прочим…

Вот если взять современные инструменты и писать под эмуляцию тогдашнего железа (используя QEMU, например) — вот тогда эта задача будет простой…
UFO just landed and posted this here
То что в этот режим нужно ещё как-то умудриться попасть. А для этого вы должны предоставить, прости господи, «relocatable PE executable file» — да ещё и подписанный на некоторых системах. А потом ваш бинарник доложен будет как-то выяснить — где и какое железо живёт. Фиксированные порты и IRQ остались в далёком прошлом, нынче у нас на PC сплошной PnP, что упрощает жизнь пользователям — но существенно усложняет жизнь разработчикам.

А если вы не про PC, то а про какую нибудь ARM-железку типа Raspberri Pi, то там процессор вообще запускается операционкой для GPU! От которой ни документации, ни исходников нету!
#include <efi>
int main(SystemTable* systab, Handle image_handle) {
    InitializeLib(systab, image_handle);
    Print(L"Hello, world!\n");
}

Как-то так. Вроде без legacy костылей.

Может поэтому и взлетело.
Ровно потому и взлетело. Весь userspace у него уже был — его задачей было переписать только ядро.

Тоже та ешё задачка для студента, но… в человеко-год он уложился. Тут же делается попытка переписать что-то, что в базовом варианте никому не нужно (и, собственно, пишется куда быстрее, чем за год), а небазовом — требует очень много человеко-лет (потому что нет такого «удобного» деления на части — UNIX состоял из отдельных относительно небольших частей, а вот современный браузер — это монстр, где в одном бинарнике засунуты сотни компонент)

Что действительно кажется интересным, так это эксперименты с sax вместо dom. Или, например — использованием собственного файла подкачки, с возможностью ограничить потребление памяти(вполне реализуемо на всех основных платформах).


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


Лично я бы смирился даже с определёнными лагами при загрузке и исполнении js, в пользу браузера который жил бы в одном гигабайте памяти, а не в 6-8, как лидеры рынка.

… так это эксперименты с sax вместо dom

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

Я плаваю в вопросе, но со стороны, кажется, что, можно держать в памяти только "горячие" участки dom, а остальное можно держать в подкачке. Разница с системными механизмами подкачки должна оказаться вполне значительной, особенно, учитывая распространённость ssd.

Если ещё пофантазировать — страницы могли бы содержать заголовок манифеста, с профилем обращений к dom, для браузеров, которые такое поддерживают.

UFO just landed and posted this here
Безусловно вы молодец, что развиваетесь.
Но как же Servo?
В нем нет легаси кода из 90-х. Его код молодой и современный. Он парралельный и он написан на Rust, более безопасном языке чем С++.
Вы студет или работаете программистом пару лет, я угадал?

Я заглянул в репозиторий на github и в несколько кликов попал на код класса DOMStringMap. Вы в статье пеняете на различные типы умных указателей, но в вашем коде реализуете map обычным массивом, и вместо логарифмической сложности ищете ключ линейно. Более того, вы итерируете вектор по обычному индексу, хотя итератор позволяет не производить лишних операций вычисления адреса. Оверхед неправильного выбора часто используемого алгоритма будет на порядки выше оверхеда умных указателей, не котороя уже о том, что использование обычных указателей в сложном коде легко приводит к нестабильности кода. И в других местах вы делаете огромное количество ошибок С++, которые влияют либо на скорость, либо на простоту/расширяемость/поддерживаемость, либо на надежность кода.
Не угадали, ему ~14 лет (если его комментарии к PR верны).
Ну, если 14 то можно только гордиться тем, что у нас такие парни есть!
Целиком согласен — браться за проект такого размера и добиваться хоть какого результата в 14 лет — это уже само по себе большой результат. Остается только пожелать автору всяческих удач и творческих успехов :-)
Во-первых, везде в вызовах добавьте const DOMString& key. не только тут, а вообще везде. Вы постоянно копируете параметры, где это нужно и где не нужно.

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

И в-третьих, я пощелкал по нескольким файлам, и буду откровенен, у меня есть предположение, что ваш DOMStringMap не реализует сложный функционал, но глядя на заголовки, я не могу понять, зачем он нужен. Кстати, он не map, а view, потому что предоставляет другой интерфейс к значениям в NamedNodeMap, но зачем в свою очередь нужен тот, я тоже не очень понял. В нем еще есть проблема с владением укателем на атрибут.

Он в свою очередь тоже view, но имеет интерфейс map, и реализован вектором, что порождает проблемы скорости, о которых я писал.

И еще момент. Если вы реализуете контейнеры, то очень полезно сохранять у них стандартный интерфейс с итераторами, функциями begin(), end() и т.п. Это позволяет легко применять к ним алгоритмы стандартной библиотеки и не только их.
Сложность в том, что в браузерных движках не просто рендеринг, но рендеринг быстрый и эффективный. Деление на слои, всякие reflow и так далее. Огромные кучи разных хаков. А тут ещё и недавно статья была про занятный файлик в хроме :)
У меня один вопрос: почему C++, а не Rust?
UFO just landed and posted this here
есть очень много типов умных указателей
и ссылка на описание двух типов и одного вспомогательного класса. Это насторожило. Но когда я дочитал до момента, что деструкторов нет, а сборщик мусора планируется писать «потом», то даже как-то любопытно стало. Ну хорошо, хочется GC(и скорости), но зачем тогда C++? Ведь деструкторы считаются самым главным преимуществом C++ над C.
С чего вы собственно решили, что умные указатели — это причина всех бед и «тормозов» того же WebKit-а?
Если говорить об умных указателях из C++ стандарта (webKit исторически использует свои, видимо, но суть дела это не меняет), то отверхеда от использования умных указателей — собственно почти нет. unique_ptr так вообще, в памяти даже занимает ровно столько же, сколько и обычный сырой указатель. shared_ptr — в памяти чуть больше, но в плане производительности «дороговатая» там только операция копирования, т.е. нужно учитывать возможность мультитрединга, а разыменование — копеечная операция, не отличающаяся от доступа к сырому указателю. Чуть дороже всякие операции блокировки weak_ptr-ов, но опять же не принципиально.

И чем вы собственно собираетесь заменить умные указатели? Очень сомневаюсь что работая с сырыми указателями вы сможете избежать многочисленных падений и утечек памяти.
Просто использовать raw pointers, и аккуратно следить за new/delete по коду, делов-то
/s
Штука интересная и даже если не получится, это всё равно будет серьёзным пунктом в резюме. Парсеры это как раз самое простое. Даже движок JS штука не самая сложная в браузере. Самое сложное это, имхо, поддержка разных платформ: недавняя статья про то как Chromium обходит баги в кривых видеокартах — хороший тому пример.
Ссылку на статью можно увидеть? Спасибо.
UFO just landed and posted this here
Можно просто не использовать аппаратное ускорение, а отрендеренный растр выводить на экран — и никакие баги видеокарт не будут страшны. Или просто взять стороннюю библиотеку (Skia, Cairo, Allegro).
UFO just landed and posted this here
Ясное дело, я сам вижу, как Opera 11 работает медленнее Хрома (правда, она работает даже медленнее Хрома тех времён, когда он ещё не умел аппаратное ускорение, так что тут не в нём даже проблема).

Но поскольку моей задачей было сделать «хоть какой-то браузер», а не «лучший браузер», то тормоза анимаций, особенно если они не сильные — побоку :)

Конкретно у меня попытки реализации в другое упёрлись — в странности джавы при попытке назначить z-индексы слоям через нативный механизм, то есть ничего просто не работало…

P.S. вообще говоря, если анимаций на странице не очень много, сильно тормозить не должно, растровые буферы можно в любом случае кэшировать в оперативной памяти. Тут ещё имеет значение фреймрейт анимации — чем больше фреймрейт, тем больше памяти жрёт и тем чаще надо обновлять картинку.

P.P.S. На сколько я знаю, для ускорения вывода графики применяется очень простая инструкция — BLIT PIXEL (читал в статье от Oracle о Java 2D). Там всего 3-4 варианта реализации, и если отбросить «продвинутые» — то останется вообще один (этот один поддерживается вообще любыми видеокартами любой степени давности, и можно ограничиться им). Какие тут могут быть баги, с которыми непросто справиться даже Гуглу?)
UFO just landed and posted this here
Так вроде в стандарте html 5 есть подробный раздел о парсинге и построении дерева. Что-то вроде инструкции — https://www.w3.org/TR/html52/syntax.html#parsing-html-documents. Зачем что-то изобретать? А лояльность к ошибкам дописывать в процессе тестирования.
Идеология Newtoo — показать страницу быстрее, чем остальные.

Это выглядит не как идеология, а как цель. Будем надеяться, что это единственная «путанница в головах», и проект даст даст выхлоп!

Как работа для прокачки кругозора — найс. Но не стоит надеяться на успех мероприятия. Парсер это самое простое. Но и там горизонта пока не видно. JavaScript двигло, если и там ты будешь свой велик делать, отнимет огромное количество времени. Рендер,… сдается мне, что еще больше. Тем более поддержка WebGL и анамаций. За это время твой проект устареет. Но даже это не все. Б — БЕЗОПАСНОСТЬ.


Браузер давно перешагнул себя как приложение. Он стал скорее ОС. Не зря появился такой проект как Chrome OS. А интеграция браузеров с сервисами вендеров стала ключевой в их выборе. Например, WebPUSH, маркеты.
В общем, для познания мира изнутри, проект ценен для личного развития. Но я бы рекомендовал фокус сузить. Это позволит достигнуть действительно ценного результата за вменяемый срок.

Я несколько в шоке от количества плюсов к этой статье. Неужели никто не дочитывает до момента «реализован только парсинг»?
Многие воспринимают парсер (написать интерпретатор) как нечто магическое. Хотя, по сути, это достаточно просто для заданной спецификации. Гораздо сложнее сделать его быстрым, надежным и компактным. И уж действительно сложно создать новый синтаксис для решения задач выбранного профиля. Но, конечно, по себе помню, когда написал свой первый интерпретатор, считаешь, что ты как минимум третий после Стиви и Билли. Да фик с ним с Билли, сразу после Стиви. И все же, практически любой толковый Сишник пишет свой первый интерпретатор. Т.ч. путь то верный, а опыт поднакопится ;)
Автор просто не осознает, насколько это объемно. Но для «прокачки» кругозора — да. Можно смело пожелать всяческих успехов (сам такой в молодости был :-)).

Хорошим примером того, как надолго может всё это дело растянутся, является sciter.com.
Там схожая ситуация: проект делается одним человеком. Стоит отдать должное — библиотека сделана очень хорошо. Подтверждение тому список клиентов. Цель проекта правда немного другая — GUI для десктоп-приложений на основе HTML вёрстки. Там и CSS, и собственный scripting есть, можно и собственный backend на С++ писать. Исходников забесплатно к сожалению нет, но зато есть бесплатная возможность использовать всё это дело в коммерческих проектах.

Да, и пишется всё это уже много много лет.

Безопасность — и правда довольно важный аспект. С остальным не соглашусь. Если мне, как юзеру, дадут браузер по виду и возможностям похожий на IE версии 8 (но не падающий, не тормозящий, быстро рендерящий страницы и с удобным интерфейсом разработчика) — я даже забью на старомодный скин и буду на седьмом небе от счастья. И не спрашивайте, чем мне Хром не по душе. Просто хочется альтернатив, хороших и разных :)
UFO just landed and posted this here
Это как раз пофиг.

1. Я использую в повседневной работе Chrome 45, в нём всё более-менее норм работает.
2. Есть Advanced Chrome, в котором использованы фрагменты кода версии 54, это даже ещё более свежий браузер чем Chrome 49. Работает он шустро, там нет ненавистного мне MD, там работает переход назад по Backspace без установки расширения, в общем, всё шикарно там. Даже шрифты чуть чётче благодаря тюнингу Skia от автора сборки.

Просто не люблю быть привязанным к одному единственному продукту, пусть даже и хорошему. Особенно когда продукт не обновляется (интернет-то меняется постепенно, новые фичи и всё такое).
UFO just landed and posted this here
Для XP — не обновляется. Очевидно же. Я не говорю про всех, я говорю про свой конкретный случай. Менять ОС из-за браузера я как-то не горю желанием :)

P.S. Это не был наезд на Хром, просто объясняю, что конкретно меня тревожит, и почему я заинтересован в дополнительных альтернативах.
UFO just landed and posted this here
поддержка операционной системы Windows XP официально прекращена несколько лет назад

Я знаю об этом. Мне-то что с того, если мне в ней удобно и вообще нравится работать?

Вас не беспокоит, что вы сидите на дырявой, неподдерживаемой, устаревшей операционной системе?

Ничуть не более дырявой, чем все остальные. А насчёт устаревшей — назовите хоть одну причину, почему это так, вот тогда и поговорим. ПРо игры только не надо писать — у меня для этого семёрка рядом стоит. Надо будет — и десятку для игр поставлю, если будет под неё какой-то интересный мне эксклюзив.

И вам не кажется, задуматься о замене ОС вы должны как раз из-за этого?

Нет, я ничего и никому не должен.

Эти альтернативы никогда не стали бы писаться так, чтобы они поддерживали мертвые операционные системы.

Неправда ваша. Погуглите Advanced Chrome, New Moon, K-Meleon (с движком Goanna), Basilisk и Serpent.
И кроме того, я пишу ещё свой браузер параллельно именно из расчёта, чтобы он отлично работал на Windows XP (включая корректный рендеринг текста с субпиксельным сглаживанием).
UFO just landed and posted this here
Вы почитайте историю этого человека. Он использует Оперу меньше 12-й версии, отрицает https, предпочитает кодировку win-1251 на сайтах и крайне фанатает от ХРюшы
UFO just landed and posted this here
Просто не люблю быть привязанным к одному единственному продукту, пусть даже и хорошему

Да, подловили, и правда противоречие. Но я писал о программах. ОС — особый разговор :)

Да и программа программе рознь. Взять вот браузер — часто ли вы сталкиваетесь с его интерфейсом, какими-то тонкими возможностями, «потрохами»? Для меня это просто инструмент, позволяющий просматривать веб, то есть некий такой «портал в интернет». Тут привычка не так решает, легче перейти на другой продукт. И то будет заметна разница: изменится высота вьюпорта (это очень сильно замечаешь), цвет UI в верхней области (не везде это можно настроить скинами), скорость прогрузки страниц (как правило, после Хрома — это всегда в меньшую сторону.

Когда я на Хром с Оперы 11 переходил, меня наоборот пару месяцев бесило, что всё грузится «слишком быстро», и я не успеваю насладиться процессом. Да, бывают и такие странности))

Про базовые знания — согласен. Наверное, одной базы маловато будет.

Но я как бы не против изучать что-то новое, если это интересно/полезно. Вы, как мне кажется, мешаете в кучу лень в изучении технологий (что нельзя оправдать) и инструмент для работы (в качестве которого XP ничуть не устарела).

Единственные две области, где она уже не годится — это игры (поскольку нет поддержки нового железа и новых версий DirectX, ну и то что нет 64-битной версии, которую поддерживал бы софт) и аудио-продакшен (новые версии сэмплерных библиотек, хостов и VST не поддерживают XP). Но даже из этих двух второе ограничение — искусственное (созданное производителями софта), принципиальных препятствий работе этих вещей на XP попросту нет.

Да и с играми могло бы обернуться иначе, если бы Microsoft портировала на XP Direct X 10 и 11 (обновив, если нужно, ядро ОС, добавив туда новых фич). Ведь драйвера от моей видеокарты 2012 года под XP вполне себе были выпущены, проблема даже не в железе. И даже будь она в железе — если работа не требовательна к ресурсам (игры здесь идут мимо), всегда можно поставить более старое.
Приведите хоть одну реальную «дыру», чем бросаться пустыми словами — тогда и поговорим :)
UFO just landed and posted this here
Показательный пример — вы скинули ссылку, и Хром отказался её открыть… потому что использует SSL библиотеку, встроенную в ОС. А она в XP слишком старой версии и не поддерживает современные шифры.

И так почти на каждом третьем сайте. Очень раздражает, да. Если бы не тормоза Firefox — давно бы на него пересел :)

Открыл, посмотрел. не очень понимаю, как читать эти данные. Учёт уязвимостей ведёт (вела) Microsoft, или сообщество? Скорее всего, Microsoft, потому что после 2014-ого года я вижу всего 7-8 штук за все 3 года, тогда как до этого было от 40 до 110 в год. Поддержка же и выпуск патчей как раз была прекращена в 2014-ом.

Вы предлагаете аппроксимировать, и считать число дыр примерно постоянным, независимо от количества фиксов? Если так, то штук 300 должно было накопиться.

С другой стороны, в середине нулевых количество найденных уязвимостей было существенно меньше, и колебалось в районе 20-60 в год. У вас есть этому объяснение?

Кстати, в 2012-ом тоже за год было найдено всего 43.
Так, хорошо, открыл список за 2013-ый год.

первые 7 уязвимостей
1 CVE-2013-5065 20 +Priv 2013-11-27 2018-10-12 7.2
None Local Low Not required Complete Complete Complete
NDProxy.sys in the kernel in Microsoft Windows XP SP2 and SP3 and Server 2003 SP2 allows local users to gain privileges via a crafted application, as exploited in the wild in November 2013.

2 CVE-2013-5058 189 Overflow +Priv 2013-12-10 2018-10-12 4.9
None Local Low Not required None None Complete
Integer overflow in the kernel-mode drivers in Microsoft Windows XP SP2 and SP3, Windows Server 2003 SP2, Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8, Windows 8.1, and Windows Server 2012 Gold and R2 allows local users to gain privileges via a crafted application, aka «Win32k Integer Overflow Vulnerability.»

3 CVE-2013-5056 399 DoS Exec Code Mem. Corr. 2013-12-10 2018-10-12 9.3
None Remote Medium Not required Complete Complete Complete
Use-after-free vulnerability in the Scripting Runtime Object Library in Microsoft Windows XP SP2 and SP3, Windows Server 2003 SP2, Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2012 Gold and R2, and Windows RT Gold and 8.1 allows remote attackers to execute arbitrary code or cause a denial of service (memory corruption) via a crafted web site that is visited with Internet Explorer, aka «Use-After-Free Vulnerability in Microsoft Scripting Runtime Object Library.»

4 CVE-2013-3940 189 DoS Exec Code Overflow Mem. Corr. 2013-11-12 2018-10-12 9.3
None Remote Medium Not required Complete Complete Complete
Integer overflow in the Graphics Device Interface (GDI) in Microsoft Windows XP SP2 and SP3, Windows Server 2003 SP2, Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2012 Gold and R2, and Windows RT Gold and 8.1 allows remote attackers to execute arbitrary code or cause a denial of service (memory corruption) via a crafted image in a Windows Write (.wri) document, which is not properly handled in WordPad, aka «Graphics Device Interface Integer Overflow Vulnerability.»

5 CVE-2013-3918 119 DoS Exec Code Overflow 2013-11-12 2018-10-12 9.3
None Remote Medium Not required Complete Complete Complete
The InformationCardSigninHelper Class ActiveX control in icardie.dll in Microsoft Windows XP SP2 and SP3, Windows Server 2003 SP2, Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2012 Gold and R2, and Windows RT Gold and 8.1 allows remote attackers to execute arbitrary code or cause a denial of service (out-of-bounds write) via a crafted web page that is accessed by Internet Explorer, as exploited in the wild in November 2013, aka «InformationCardSigninHelper Vulnerability.»

6 CVE-2013-3900 20 Exec Code 2013-12-10 2018-10-12 7.6
None Remote High Not required Complete Complete Complete
The WinVerifyTrust function in Microsoft Windows XP SP2 and SP3, Windows Server 2003 SP2, Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2012 Gold and R2, and Windows RT Gold and 8.1 does not properly validate PE file digests during Authenticode signature verification, which allows remote attackers to execute arbitrary code via a crafted PE file, aka «WinVerifyTrust Signature Validation Vulnerability.»

7 CVE-2013-3899 20 +Priv Mem. Corr. 2013-12-10 2018-10-12 7.2
None Local Low Not required Complete Complete Complete
win32k.sys in the kernel-mode drivers in Microsoft Windows XP SP2 and SP3 and Server 2003 SP2 does not properly validate addresses, which allows local users to gain privileges via a crafted application, aka «Win32k Memory Corruption Vulnerability.»


3 и 5 меня не затрагивают, потому что я никогда не использую Internet Explorer. 4 тоже мимо, потому что я не использую WordPad (ну может что-то открываю в нём раз в год, но это всегда мои собственные файлы, а не полученные со стороны).

Остальное — серьёзнее. Но даже тут скорее всего безопасно, потому что я не запускаю сторонних exe файлов кроме тех, что уже установлены у меня на компьютере. А если что-то ставлю, то смотрю хотя бы подпись и издателя. И в целом ставлю софт очень редко.

Также стоит добавить, что «allows local users to gain proviledges» для меня тоже не актуально, поскольку я — единственный пользователь в системе.

У вас есть пример чего-то такого, что может мне навредить, желательно с примером на пальцах, что я должен для этого сделать, и каковы будут последствия?

Я пока нашёл только две уязвимости, эксплуатируемые через файлы шрифтов, и позволяющие выполнять произвольный код. Это и правда очень плохо, я часто открываю шрифты, в том числе загруженные из интернета с разных каталогов.
UFO just landed and posted this here
Я вам сразу написал, пользуйтесь, только в инет не выходите.

Это почему?) Из-за шрифтов, которые я иногда качаю, и 2-3 уязвимостей в их просмотрщике?

Сравните хотя бы с windows 7:

А чего там сравнивать?.. Почти все уязвимости, которые я просмотрел за 2013-ый год (я мог что-то упустить) — были найдены на всех ОС (включая Win7, 8 8.1). Просто для XP всё что новее января 2014-ого так и не было пофикшено.

Введены новые методы обхода атак ASLR, PatchGuard, UAC, PMIE.
Много пособий по exploit-ам именно для windows xp.

В XP нет UAC в том виде, в котором его привыкли видеть. Или вы о чём сейчас?

OC — тоже программа.

Программа, управляющая всеми другими программами и аппаратными ресурсами. Так-то да, я в курсе, что она программа)
Точнее, прошу прощения. В XP вообще нет ничего из этого
Введены новые методы обхода атак ASLR, PatchGuard, UAC, PMIE

Кстати, из вашей формулировки следует, что и наличие всех этих вещей не сильно спасает, раз «введены методы обхода».
UFO just landed and posted this here
Я удивляюсь почему Вы на windows 9x не сидите

Вы серьёзно или троллите? Попробую предположить, что серьёзно. Окей, потому что 9x падает чаще, и поддерживает меньше оперативной памяти (насколько я помню, 98 SE не увидит даже 4 Гб, хотя возможно я ошибаюсь). Плюс банально требования софта, который я использую. Из всего, что мне нужно, на 98-ой пойдёт разве что Sound Forge 7. Кстати, драйверов на мою звуковую и видеокарту под 98 SE тоже нет.

Были бы драйвера и софт — я бы проверил (на виртуалке я гонял 98 SE довольно много, кстати, всё летало и синих экранов не было). Не сомневаюсь, что скорость её работы была бы ещё выше.

Введены новые методы обхода атак ASLR, PatchGuard, UAC, PMIE.
Много пособий по exploit-ам именно для windows xp.

Возвращаясь к вашей цитате и к статьям, что вы привели по ссылкам: вы таки думаете, что вся вот эта ерунда не потребляект аппаратных ресурсов? Прямо совсем-совсем? Рандомизация адресов требует вычислительных тактов, UAC… Казалось бы, что в ней плохого — но то-то у меня всё стало шевелиться раза в полтора быстрее даже на Windows 7 x64 после её отключения (3.3 GHz @4, 8 Gb RAM). Ну окей, не только её, а ещё 2-3 служб. Prefetcher, кстати, я не отключал — не заметил очень сильного влияния на время запуска ОС, а вот время запуска программ он правда сокращает.

Итак, если допустить, что производительность Windows Vista/7 в режиме работы (не в режиме монопольной работы какого-то приложения типа игры) правда упала, то возникает вопрос — а нафига мне всё это нужно? Поиск уязвимостей и создание патчей к ним и методов защиты — это вечная гонка меча и щита. Я совершенно не собираюсь в ней участвовать в надежде оказаться где-то быстрее хакеров (вместо с вендором ОС), если повезёт.
UFO just landed and posted this here
Версия? Вы про Home/Professional? Или про сервис-пак?
SP3 Pro, и патчи до лета 2012-ого года стоят включительно.

Linux — может и хорошая система. Но привыкать к полностью новому проводнику, рабочему столу, поменять практически весь софт (кроме браузеров и пары плееров)? Сомнительное предприятие :)

Я кстати в 2009-ом году пробовал играться с Mandriva Linux. Не зашло вроде, утонул в опциях и настройках (в Windows их не то чтобы меньше, но тут я знаю, где что настраивается, а там вот запутался).
С 2009-го очень многое в линуксе поменялось, если что. Я в том же 2009-го вдоволь намучался с той же мандривой, а уже в 2010-м полностью перешёл на убунту без каких-либо проблем и с тех пор на винду не возвращался
Можете вкратце рассказать, чем убунту лучше мандривы? Можно в личку.

Опять же, про софт интересно узнать, много ли приходится работать с консолью (и приходится ли), и так далее.

Просто если человеку вообще не нужна консоль, и он планирует только GUI использовать — чем вообще плоха винда :)

А с консолью у меня тоже тяжко. Пытался подружиться с FreeBSD (для сервера), долго мучился, в итоге забил.

В убунте (и родственных ей дистрибутивах) всё относительно готово для конечного пользователя из коробки — если железо не слишком экзотическое, то зачастую можно просто поставить и пользоваться, про консольку и не вспоминая. В той же мандриве 2009 года у меня категорически не хотел работать GPRS-интернет (а другого у меня тогда и не было), а через год в убунте он завёлся в три клика в настройках сети


Многие другие вещи, которые в 2009-м приходилось делать через консольку, сейчас тоже или совсем автоматизированы, или имеют относительно адекватные гуёвые кнопочки (но точный список таких вещей уже не вспомню). Это, конечно, не только в убунте, но в других дистрибутивах «кнопочек» обычно поменьше и лазать в консольку всё-таки приходится


чем вообще плоха винда :)

Может и ничем

Спасибо. Меня тут просто очень настойчиво отговаривают бросить WinXP ради Linux, вот обдумываю, а надо ли.

У меня тогда кстати был интернет через ADSL — драйвер от моего модема вряд ли был в составе ОС, а погуглить, как ставить драйвера в мандриве, без интернета я никак не мог (у меня был всего один ноут в те годы, в школе ещё учился).

Но главная беда даже не в этом. Новая ОС — это не только, условно говоря, новый текстовый редактор и другой файл-менеджер. Это другие шрифты, другой механизм рендеринга и сглаживания текста (!), что особенно критично, когда ненативное разрешение монитора юзаешь, новая цветовая гамма. Не всё из этого настраивается так, как привычно, а я очень консервативен в этом плане.

Вот десятку я смог визуально сделать настолько приятной (хоть и не идентичной XP), что готов был ей пользоваться. Однако периодические тормоза, ненужные мне попапы, долгое открытие главного меню из-за плиток, и слишком контрастный дизайн Modern-компонент, включая «панель управления» — всё же вынудили отказаться от её использования…

Кстати, та же «панель управления» в Висте и Семёрке у меня негатива не вызывала в плане своего дизайна (хотя в плане что-то там найти — это мрак, Десятка тут сделала шаг вперёд)…
UFO just landed and posted this here
В отличии от других движков

Не стоит вносить некие «features», которые ещё не одобрены окончательно W3C. Не начинайте очередную войну браузеров. Единственное, чем должен отличаться Ваш движок, уважаемый Автор — это корректной поддержкой всего, что уже есть в стандартах W3C, и скоростью работы (в лучшую сторону относительно других браузеров).

Не всё так просто, следование стандартам W3C будет означать нарушение совместимости со всеми современными браузерами, например https://habr.com/post/353514/


А ещё говорят, что реализовать всё по стандартам эффективно просто невозможно. Настолько невозможно, что гугл переписывает спецификацию под свой хром

Вот и я том же. Не стоит вносить ещё больший вклад в общую энтропию. Реализуйте то, что совместимо с W3C и WHATWG, и не надо придумывать супер-мега-фичи, которые будет поддерживать только Ваш движок.
Круто, а где можно попробовать? Ссылки на офф сайте выдают 404.
Вопрос — чем не устраивает Webkit?
Так уж получилось, что в мире есть всего 4 популярных браузерных движка

А какие ещё два?..

UFO just landed and posted this here
UFO just landed and posted this here
Если это открывающийся тег, он парсит его название тега, атрибуты, а затем, если это параграф и в иерархии тоже есть параграф, удаляет существующий в иерархии тег параграфа и добавляет туда новый, если это не одиночный тег (тег без закрывающегося тега). Если это закрывающийся тег, парсер удаляет из иерархии последний тег и если последний тег был параграфом, то удаляет сразу два последних.

Пожалуйста, вот с этого места поподробнее. Что говорит на этот счёт стандарт?
Это работает только с абзацами? Абзац нельзя вложить в абзац, по логике вещей (такое стандарт должен запрещать). Однако если я напишу такой код:

<div>Какой-то текст
<div>Ещё текст


В таком случае это работать не будет (ведь div можно вложить в div)? Каковы вообще формальные правила автозакрытия тега парсером?

UPD: потестил в Chrome, этот приём работает со ссылками и абзацами внутри div. Если же создать абзац, и попробовать провернуть такое с div-ами — ничего не выйдет, получится пустой абзац, в нём div с текстом и ещё одним div-ом внутри, и после внешнего div-а ещё один пустой абзац.
Прочитал первые два пункта про обработку некорректной вложенности, и третий про неожиданный контент в таблицах. Это какой-то ад просто. Совершенно не интуитивно, такое ощущение, что просто придумали некий абстрактный алгоритм разбора, потом посмотрели, что он выдаст в этих особых случаях, расписали это, и сказали «да будет так, никак отдельно обрабатывать мы это не будем». Жесть в общем :)

Вообще, не понятно, какой смысл выделять отдельную категорию тегов, такую как «теги форматирования», если у нас форматированием давно занимается CSS. У нас есть блочные, инлайновые и инлайново-блочные элементы — вот это важно. Блочные не стоит вкладывать в инлайновые — это тоже важно (браузеры кстати обрабатывают эту ситуацию корректно, делая вложенный блочный элемент практически инлайновым по поведению).

А вот эти неконсистентные результаты…

В общем, как бы сделал я на месте разработчиков:

а) В теги <b>, <i> и прочие вообще запретил бы вкладывать элементы вроде <div>, <p> и так далее. Только в обратную сторону — ибо нефиг, должна быть чёткая система правил, что первично, а что вторично.
б) Весь неожиданный контент внутри <table>, который не лежит внутри <td> — просто вырезать к чертям, как будто его и не было.
в) Вот этот последний шестой пример, который я до конца так и не понял, там уж слишком что-то странное — тоже бы запретил так писать. Чистый лист отображать — это конечно перебор, что-то вывести надо, и как-то закрыть незакрытые теги тоже надо. Но алгоритм такого закрытия должен быть проще и предсказуемее в плане результата, имхо.

UPD: Примерно понял, что там происходит. Отдельный список тегов форматирования, который управляется отдельно, и поскольку он не очищен, то создаёт новые <b> элементы даже для пустых абзацев, пока мы его не очистим.

Моё мнение не изменилось, я всё ещё считаю, что это полный бред. Теги создавались с целью разметки и структурирования (придания частям текста семантики). Выделять отдельную группу тегов и управлять ей особо — это только создавать сложности верстальщикам и разработчикам браузеров (в случае, если те что-то реализуют не так, тесты не сойдутся с эталоном).
такое ощущение, что просто придумали некий абстрактный алгоритм разбора, потом посмотрели, что он выдаст в этих особых случаях, расписали это, и сказали «да будет так

Примерно так всё и было. Было несколько парсеров в разных браузерах, которые друг под друга подстраивались, потом решили всё это стандартизировать. Это пытались починить посредством xhtml, но верстальщики взбунтовались и теперь имеем то, что имеем: нельзя просто так взять и написать свой браузер не повторив поведение дилетанской поделки двадцатилетней давности.

Но какой смысл повторять её поведение? Я не очень понимаю всё равно. Нет, случаи бывают разные (верстальщик ленив или совсем неопытен), но я на реальных сайтах ещё ни разу в жизни не видел незакрытых тегов в разметке от слова «вообще» (а если где-то такое и есть, то скорее это последствия сбоя генерации HTML на сервере, а не намеренное желание автора сайта). И даже в этих редких случаях, когда возникает ошибка, вёрстка всё равно выглядит сильно не так, как задумывал дизайнер (почти всегда), это быстро замечают и тут же исправляют.

Обратная совместимость :(


На практике бывают не только незакрытые теги или <b><i></b></i>, но и мутанты типа </br>, я вот видел


(почти всегда)

А иногда ошибка успешно исправляется браузером, и она доживает до продакшена. Поэтому даже я свои сайты периодически прогоняю валидатором, несмотря на то, что давно умею писать валидный код, просто чтобы опечатки выловить

Имхо лучше бы браузеры выводили в уголке попап с сообщением «в разметке сайта найдено N ошибок, из них M критических», пусть даже с возможностью отключить эту штуку в настройках, чем пытались такое молча исправлять. Всем лучше было бы, и не нужно было бы отдельно использовать валидатор.

но и мутанты типа

Обычная опечатка, ничего удивительного. С этим случаем всё намного проще: по стандарту тег <br> непарный. Можно просто дописать в код парсера одну строчку, которая позволит закрывающий тег рассматривать как открывающий (игнорировать слэш), если тег непарный.

Ага, примерно таким и был XHTML, и я даже писал все свои сайты на XHTML, пока его не закопали в угоду HTML5 :(


Вообще в стандартах HTML5 описывается какой-то XML-синтаксис для него, но я что-то не вкурил, как его правильно использовать, да и вживую на сайтах не видел ни разу

Но я ведь правильно понимаю, что никто нам не мешает писать HTML5 doctype, но при этом использовать все требования XHTML? Это будет валидно, и это будет работать корректно (по идее).

Я, к слову, всегда придерживался XHTML синтаксиса (правда последние 3-4 года ленюсь писать значения для атрибутов вроде disabled и т.п.) — но doctype указывал HTML 4.01 Transitional.

Сейчас ведя индивидуальные занятия по HTML/CSS, рекомендую использовать HTML5 doctype, потому что он и пишется короче, и как бы 2018-ый год на дворе обязывает :) Хотя что-то мне подсказывает, что при нормальной правильной разметке вообще разницы почти не будет от того, какой именно указан.

Валидный XHTML не всегда является валидным HTML4 (например, в HTML4 нельзя записать <meta блаблабла />, нужно обязательно <meta блаблабла>)


А для HTML5 я и так пишу в XML-стиле, однако от плохих вестальщиков, пишущих всякие </br> и абсолютно уверенных в правильности этого, это всё равно не спасёт


разницы почти не будет

«Почти». Я пару раз сталкивался с вёрсткой, поехавшей от неправильного доктайпа. Правда, деталей уже не помню, к сожалению

На самом деле, самая печаль в том, что мне нравится концепция с указанием слэша в непарных тегах — но <meta блаблабла /> не работает и в HTML5.

Смотрите, простой эксперимент: если создать на жёстком диске страницу в кодировке windows-1251, и не указать кодировку, то после посещения любого сайта с utf-8 кодировкой в соседней вкладке и последующего обновления нашей локальной страницы у нас будет применяться utf-8 и будут кракозябры (браузер не запускает по какой-то причине процедуру «угадывания» кодировки). Тестил в самой свежей версии Chrome на Win 7.

Теперь попробуем добавить в <head> страницы <meta charset="utf-8">. Проблема уходит. Но стоит добавить слэш: <meta charset="utf-8" />, как проблема возвращается…

Что-то у меня не получилось повторить, мой хром безошибочно угадывает кодировку windows-1251 при любых сделанных мной манипуляциях с вкладками. А <meta charset="utf-8"> и <meta charset="utf-8" /> одинаково включают utf-8 и ломают русские буквы как положено

Очень странно. Сейчас сам проверю. Сначала в своей 45-ой версии, потом в последней под семёркой. Я точно напоролся на эту вещь на последнем практическом занятии, перепутать я не мог ничего. Скажите, а у вас doctype в начале документа проставлен именно HTML5?
Скажите, а у вас doctype в начале документа проставлен именно HTML5?

Да

Попытался воспроизвести проблему на Windows XP в Chrome 45, не получилось.

Но проблема имела место. Из того, что помню:

Chrome одной из последних версий, возможно, не самой последней, но уже одной из тех, что с новым дизайном, Windows 7 с непонятным набором обновлений. Файл создавали в GridinSoft Notepad 3.3.1 Lite, сохраняет он по умолчанию, надо думать, в ANSI а не в UTF-8.
Баг появлялся именно после просмотра другого сайта, где кодировка UTF-8; если вернуться на вкладку с тестовой страницей, и перезагружать подряд 3, 4 и более раз, проблемы не было.

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

Мне кажется, багнутая версия Хрома была всему виной. Ну или то, что редактор, который мы использовали, имеет какой-то специфичный баг именно под семёркой (редактор очень старый, хотя когда его выпускали, Vista точно уже была в ходу, 2008 год вроде).

Например, сейчас я запустил эту версию (она вроде как portable позиционируется) — проблем нет, правда настройки берутся из моего реестра, от более старой версии, что довольно любопытно. А там была странная вещь: я в окне настроек задавал размер таба в 4 пробела, он вроде куда-то сохранялся, и даже работал, но стоило сохранить файл с расширением .html — как таб становился равным пяти пробелам, и в итоге выравнивание кода превращалось в пытку, приходилось после Tab жать Backspace для выравнивания по предыдущей строке.

Кстати, потом оказалось, что я просто забыл включить принудительную конвертацию табов в пробелы, когда её включил — проблема исчезла. Но сейчас пытаюсь воспроизвести баг на WinXP — никак не выходит, не получается 5 вместо 4, всё чётко — отступ ставится ровно такой, как ставишь в настройках. И даже при отключенной опции «Tabs to spaces» всё нормально.

Так что может, файл сохранялся как-то криво, в других редакторах я его открывать в тот день не пробовал :)

Это я знаю, но это не HTML5 всё-таки (если я правильно интерпретрирую index.xsl, надстройка над старым XHTML?)

Это трансформация из произвольного XML в XHTML. Можно и сразу в XHTML писать, но тогда нужно сервер настраивать, чтобы правильный mime-type указывал, иначе браузер будет использовать не xml, а html парсер.
В любом случае старый XHTML давно умер и перестал быть интересен, интересует именно XML-синтаксис для HTML5
Умер лишь XHTML2, фичи которого так и не реализовали в браузерах. XHTML1.1 и XHTML5 (который — не более чем xhtml1 с новыми тегами) вполне здравствуют. Потому и имеем число уровней заголовков на странице не более 6.
не более чем xhtml1 с новыми тегами

А вот например что мне нужно сделать, чтобы валидатор считал «xhtml1 с новыми тегами» валидным?

Починить валидатор, либо писать код совместимо с html5 :-)
Современный веб бессмысленный и беспощадный.
Очень рад, что кто-то взялся за эту задачу! Так как потребность в легком брозуерном движке назрела уже давно. Сам иногда подумывал о чем-то подобном, но увы, не хватает знаний.
Сразу вопрос: а с потребляемой памятью у него как? И идея на далекое будущее (если дело дойдет до релиза): сделать две сборки — одну полноценную с поддержкой всех технологий, вторую — минималистичную, где будет вырезано все ненужное типа WebGL или CSS Animation.
Кто сказал, что CSS Animation не нужны?) Или вы именно про анимации по ключевым кадрам? В любом случае, я боюсь, очень много сайтов поломается, если эту штуку исключить. На ней всякие спиннеры загрузки реализованы, ну и разные игры на JS несложные её используют.

Чтобы можно было использовать вместо Chrome в Electron'e, я так понимаю

Я вообще не понимаю, зачем нужен этот Electron. Чтобы привести в десктопный сегмент программистов, которые не умеют в Java/C#/C++? Зачем это?)
UFO just landed and posted this here
Можно и на C++ писать кроссплатформенные приложения вполне… Взять тот же Firefox, Skype (как минимум до версии 8), Chrome, MS Office с его версией под Mac OS.
UFO just landed and posted this here
А MS Office for Mac — это вообще отдельный проект.

Ну да, не каждой компании под силу такое, верно.

И ещё как минимум на iOS и Android надо

Зачем это? Мы про десктопный софт говорим. И даже не про игры

но долго и дорого

Дороже, но не факт, что очень намного. Во сколько раз зарплата программиста на плюсах выше зарплаты программиста на JavaScript?
UFO just landed and posted this here
Все говорят про то, что Electron ускоряет скорость разработки — но почему-то после перехода на него новые версии выходят реже и улучшений в них меньше.

Мне скорее кажется, что дело в том, что C++-тулкиты вообще не преднаначены для «той» разработки, которой хотят менеджеры на определённом этапе. «Добавить красненького» или «сделать уголки покруглее» в них достаточно сложно, наоборот — весь UI следует гайдлайнам платформы, а не хотелкам дезигнеров. Зато там просто подключать дополнительные библиотеки и интерироваться с разными сторонними сервисами — а как раз это Electron резко ограничивает, приложение живёт у себя «в песочнице» и оттуда очень сложно выскочить.

Соответственно имеем феномен: с точки зрения менеджеров (они видят и думают исключительно о пикселях, не забыли?) разработка резко ускоряется. С точки зрения пользователей… а тут как бы вилка: часть пользователей видит, что функционал годами не меняется и начинает подумывать о том, что «пора искать альтернативу», часть — считает что VS Code резко лучше какого-нибудь древнего Emacs'а, RHIDE (или вообще Borland C++ 3.1) только потому, что там кнопочки красивее.

Соотношение этих двух групп неизвестно, но судя по успеху VS Code… похоже, что и программисты уже тоже только о пикселях думают.
UFO just landed and posted this here
Это дороже. Бизнес пытается снизитть свои издержки за счёт пользователя. Мне, как пользователю, это не близко и потому у меня есть одно Eelectron-like приложение: клиент Steam. Потому что с альтернативами ну уж очень фигово.

Если есть альтернатива, то приложение с этим ужасом в пузе я, конечно, никогда не выберу.
Не знал, что Steam тоже на Electron написан. А электрон вроде же не так давно появился, года полтора-два назад. А стиму лет уже бог знает сколько, он уже в конце нулевых был…
Не знал, что Steam тоже на Electron написан.
Он не на Electron. Там CEF используется, это предшественник Электрона. Он как раз нулевых появился (как бы не Стима его и делали, но тут я на 100% не уверен)
О, вот про CEF я читал. А чем он оказался плох? Зачем было что-то ещё придумывать, если было такое отличное решение уже доступно?
Тем что CEF — это не совсем то. Это решение, где внутри нативного интерфейса есть кусок, сделанный на HTML-технологиях. Оно жрёт примерно так же, как Electron, но тормозит чуток поменьше. Потому что большая часть, всё-таки, делается нативно. А Электрон — это полное щастя: нативные девелоперы вам больше не нужны, всё можно делать на CSS/DHTML/JS… тормоза гарантированы «по полной».
На десктопе с кросс-платформенной разработкой вполне справляется Lazarus/Delphi. Как раз резко снижая стоимость (по своему опыту, Windows/Linux, несколько крупных приложений)
UFO just landed and posted this here
А бизнесу продукт «нужен вчера».
А получают они его послезавтра. Как у Макаренко — если коротко говорить: сорок сорокарублевых педагогов могут привести к полному разложению не только коллектив беспризорных, но и какой угодно коллектив.

Потому что играться цветами-то легко, а вот выпустить продукт — сложно. То ему памяти не хватает на телефонах с 512MiB (что, вообще-то, больше памяти суперкомпьютеров, на которых атомные бомбы считали), то что-то отваливается на каких-нибудь экзотических GPU (хотя вроде у нас банковский клиент с тремя кнопками, нафига ему GPU), то ещё что-нибудь…
Программистов найти элементарно. В своём, небольшом, городе, находили без каких-то проблем. А вот недавно понадобился питонист. И вообще никто не отозвался. Вот такая суровая правда.
UFO just landed and posted this here

Articles