Привет! Меня зовут Дмитрий Козичев.
Сегодня я вам расскажу о моей попытке создать собственный современный веб-браузерный движок с нуля.
Мой движок называется Newtoo.
Что за Newtoo
Итак, Newtoo. Зачем я его создал?
Так уж получилось, что в мире есть всего 4 популярных браузерных движка, которые настолько сложны, что сами разработчики не знают и половины их кодовой базы, и настолько продвинутые по технологиям, что начать их догонять — пустая трата времени.
А так ли это на самом деле? Мой проект создан, чтобы повторить подвиги современных браузерных движков и проверить, насколько ли реально создать достойную альтернативу крупным проектам, история которых начинается с девяностых годов. Мой новый движок создается с нуля, а значит его история начинается — сегодня.
Идеология Newtoo — показать страницу быстрее, чем остальные.
Как Newtoo работает быстрее
Как я говорил ранее, основные браузерные движки развиваются не первый год. Те ошибки, которые были допущены на начальных стадиях разработки остаются в проекте до конца. Самый яркий пример этому — умные указатели в C++ — это еще более сложный синтаксис, большой оверхед при работе, создании и удалении умных указателей. Кроме того, есть очень много типов умных указателей и нужно знать, какой когда использовать, ведь у каждого есть свои
Что в коробочке
Давайте посмотрим из чего состоит Newtoo
На данный момент реализованы следующие части проекта:
- Парсер HTML
- Сериализатор HTML
- Парсер CSS (селекторы, правила и свойства)
- Сериализатор CSS
- Основное DOM API1
Остальные части проекта, которые пока не реализованы:
- Каскадинг CSS (вычисление css стилей)
- Компоновщик
- Рендер
- Виртуальная машина JS и события
- Обработчик событий и интерактивное выделение страницы
Парсер HTML
Мой парсер HTML вполне можно назвать современным. Начнем с того, что он построен по стандарту HTML5. Он учитывает любую вашу ошибку.
Например, вы забыли поставить кавычки, набирая атрибут
<article id=hello></article>
Движок вас поймет, есть значение атрибута написано без пробелов
Вы можете не закрывать тег, когда это не обязательно
<div>
<p>First line
<p>Second line
<img src="ru/images/2019.png" alt="С новым годом!">
<p>Third line <br> Last line
</div>
Парсер поддерживает префиксы
<myprefix:span>Hello, world!</myprefix:span>
Для того, чтобы обратно превратить элементы страницы в код, я написал сериализатор HTML. Я думаю, вы догадались, что он делает.
Как работает парсер HTML
Для начала наш парсер режет наш html код на кусочки и определяет их тип.
К примеру вот это:
<!doctype html><html><head><title>Lorem ipsum</title></head></html>
Превращается в это:
<!doctype html> - doctype token
<html> - tag token
<head> - tag token
<title> - tag token
Lorem ipsum - text token
</title> - close tag token
</head> - close tag token
</html> - close tag token
Эти кусочки называются токены.
Токены делятся на 6 типов:
- Тег
- Закрывающийся тег
- Текст
- Комментарий
- Тип документа (doctype)
- Javascript или css код
Парсер читает токены слева направо. Для каждого типа свой подход парсинга.
Когда парсер читает содержимое тега, сам тег регистрируется в иерархии (иерархия от ребенка до родителя вниз), а когда парсер закончил читать содержимое тега, он удаляет его из иерархии.
Если это открывающийся тег, он парсит его название тега, атрибуты, а затем, если это параграф и в иерархии тоже есть параграф, удаляет существующий в иерархии тег параграфа и добавляет туда новый, если это не одиночный тег (тег без закрывающегося тега). Если это закрывающийся тег, парсер удаляет из иерархии последний тег и если последний тег был параграфом, то удаляет сразу два последних. А если это код, в нем разрешены спецсимволы.
Используя такой метод парсинга токенов, можно писать <p> без закрывающегося тега.
Парсер CSS
На данный момент движок умеет парсить только стилевые css правила, например:
.flex[alignment="right"] { font-weight: light; color: #999 }
Поддерживая только одни стилевые правила, можно уже нормально отобразить настольную версию какого-нибудь сайта.
В отличии от других движков, Newtoo поддерживает одиночные комментарии '//' в css коде и не удаляет их при взаимодействии с css через javascript.
Парсер CSS селекторов
Чтобы узнать, какие именно html элементы страницы нужно форматировать стилями css, был придуман язык селекторов. Вы наверное его уже знаете.
Парсер селекторов поддерживает все комбинаторы, два вида кавычек, селекторы тегов, классов, атрибутов, множественные селекторы и классы.
Вот полный список всех поддерживаемых селекторов:
TagName
#Id
.Class
[attr=value]
[attr|=value]
[attr$=value]
[attr~=value]
[attr^=value]
[attr*=value]
.Multi.Class
#Mix#ed.Selec[tor=s]
"Quotes"
'Alternative quotes'
#descedant #child
#parent < #child
#previous + #this
#other ~ #this
.multi, .selectors
#element:hover
#element:active
#element:...
Да, селекторы четвертого уровня движок пока не поддерживает, но я работаю на этим.
DOM API
Когда мой парсер HTML читает наш код, он создает объектную модель документа (DOM). DOM выглядит как дерево из узлов, где корень — окно браузера, от него ответвляется документ, а от документа уже элементы страницы. Cо всеми узлами DOM можно взаимодействовать через JavaScript c помощью DOM API.
Мой движок поддерживает любые изменения изменения DOM. Например, можно переделать html код любого элемента:
document.getElementById("article").innerHTML = "Статья исчезла. <b>Бум!</b>";
Сейчас не буду перечислять все функции работы с элементами, документом, текстом, выделением, поверьте, их много!
Виртуальную машину JavaScript пока не написал, но API уже есть и хорошо работает.
Будущее проекта
Про перспективы проекта ничего не могу сказать, вам решать.
Если вам понравился мой движок, значит я хорошо постарался.
Newtoo на GitHub
Комментарии (234)
stranger777
30.09.2018 12:20+1Дело хорошее. В конце концов, nginx сожрал apache.
Только польза от учитывания ошибок, ИМХО, сомнительная:
1. Стимулирует писать некрасиво: и так сойдёт;
2. Заставляет тратить время на поддержку возможности писать некрасиво, потенциально порождая баги;
3. Этакая криво написанная страница, простимулированная таким парсером, ещё и сломает кучу других парсеров, написанных строже;
Яндекс, Гугл даже в простом html стараются придерживаться XML, видимо, именно по причине 3.Sabubu
30.09.2018 12:26+3Игнорирование и исправление ошибок HTML было начиная с первых браузеров, и некоторые способы исправления даже задокументированы в стандартах, если я не путаю. Что касается тега <p>, стандарт разрешает не ставить закрывающий тег.
RPG18
30.09.2018 12:28+1Погодите. Например парсер от Google толерантен к ошибкам в html.
stranger777
30.09.2018 12:34+1Я про вот такие чудеса: XML — не просто расширение, там действительно под капотом XML. У Яндекса таких чудес тоже хватает.
staticlab
30.09.2018 13:08Это совсем другое. Там действительно XML, который затем обрабатывается с помощью XSLT. В результате получается HTML, который затем отображает браузер. Поддержка этих технологий — отдельная задача.
srhbdv
30.09.2018 12:44+4Только польза от учитывания ошибок, ИМХО, сомнительная
Так это не ошибки, а стандарт.
Кавычки у атрибутов не обязательны. Многие закрывающие теги не обязательны (у html, head, body, p, dt, dd, li, option, thead, th, tbody, tr, td, tfoot, colgroup, img, input, br, hr, meta, etc). Да даже сами теги в структуре документа, более не обязательны (такие как, html, head, body).
Вы предлагаете не поддерживать html-документы, написанные в соответствии со спецификацией?stranger777
30.09.2018 17:42+1Я предлагаю изменить стандарт. Поэтому и подчеркнул ИМХО :) по тексту это всё понятно: автор сначала ссылается на стандарт, а потом раскрывает. Значит, такой стандарт. И это печально…
srhbdv
30.09.2018 18:14+3Автор не знает стандарта, и его реализация «парсера» не является имплементацией спецификаций, потому и пишет подобную ерунду.
Я предлагаю изменить стандарт.
Текущий стандарт и есть итог его более чем 20-ти летних изменений. Вы же предлагаете все выбросить и откатиться на 20 лет назад, и писать на XML (XHTML?). Кому это надо? Или что вам мешает это делать и сейчас?
Развитие идет по пути повышения абстракций, а не наоборот. Весь веб изначально задумывался для простых людей, а не для программистов. Все технологии в нем изначально ориентированы на низкий порог входа. Необязательность тегов, кавычек, закрывающих тегов и прочие поблажки — это не просто прихоть или поощрение некомпетентных разработчиков. Это в том числе и экономия пресловутого трафика и уменьшение сложности. Если вы пишите веб-приложение, пожалуйста — используйте строгий синтаксис, статически-типизированные языки, системы сборок, препроцессоры, компиляторы, тесты и прочие инструменты, позволяющие поддерживать большие проекты и избегать в них логических ошибок. Но если вам понадобится сверстать форматированную html-страницу с двумя картинками и парой абзацев текста — вам зачем это всё? Текущий веб позволяет делать и сложное и простое, подходящим для каждой задачи способом. Вы же предлагаете не упрощать, а усложнять, оставив возможность делать только через сложно.
Ну и в любом случае, если вы имеете такие предложения, то предлагаете вы их явно не там, здесь вас никто не услышит. Веб тем и прекрасен, что разработка этих самых стандартов — открытый процесс, и принять участие может любой желающий.AllexIn
01.10.2018 07:09Но если вам понадобится сверстать форматированную html-страницу с двумя картинками и парой абзацев текста — вам зачем это всё?
Насколько это типичный кейс?
Да, раньше подругому не было.
Но сейчас страницы так никто не делает и сделать так ничего толкового нельзя.
Дольше всех продержался IoT, но даже там уже не актуально и практически никто уже не верстает странички в блокноте.srhbdv
01.10.2018 08:20Настолько же типичный, как верстка в markdown или TeX.
Но сейчас страницы так никто не делает и сделать так ничего толкового нельзя.
Делают и очень многие. github.com/thomaspark/pubcss
DaneSoul
30.09.2018 21:11Уже пробовали, был такой XHTML больше 10 лет назад, который не прижился именно из-за его строгости.
Если хочется строгого четкого стандарта — всегда можно использовать XML.
И самый важный момент, если парсер браузера не будет поддерживать не строгий стандарт, на котором написаны уже миллионы сайтов, причем еще с 90-х, то зачем такой браузер, который не покажет большую часть веба?alan008
01.10.2018 09:26Мне казалось, что посыл статьи как раз и состоит в указании на то, что вся эта совместимость добавила значительный багаж, который тащится и порождает проблемы, усложняющие разработки и поддержку веб-движков, а хочется сделать "правильно с нуля" (по текущим стандартам, но без багажа).
srhbdv
01.10.2018 09:49по текущим стандартам, но без багажа
Это взаимоисключающие параграфы. Текущие стандарты — это и есть весь «багаж».
По текущим стандартам браузер должен уметь обрабатывать как строгие XHTML, XML, так и совершенно нестрогий HTML.Durimar123
01.10.2018 17:30Судя по всему вы «в теме» про багованные ХТМЛ.
Существует стандарт по парсингу и исправлению ХТМЛа с ошибками?
Лет 10 назад я написал свой парсер хтмл и рендер машину, и тогда с обработкой ошибками был полный аут, все пытались делать как у микрософта, но он никому ничего не рассказывал и поэтому у всех был свой велосипед.
С тех пор что-то изменилось?lastmac
01.10.2018 19:16Всё описано в спецификации. Там есть чудный алгоритм adoption agency algorithm, а так же reconstruct the active formatting elements.
Смотрим как оно работает в описании.
Следует помнить, что сайт заблокирован, под руку попали когда телеграмм блокировали.
Durimar123
03.10.2018 14:35Спасибо. Но я чуть про другие баги.
Есть ли например принцип, по которому «живые» тэги, попавшие например в незакрытый !--, «вытаскиваются» и обрабатываются.
Или ХТМЛ в котором 2+ BODY каждый со своими парметрами; style где то по середине и тому подобная хрень.
IE это все обрабатывает, но как именно я так и не понял.
RPG18
01.10.2018 11:14который тащится и порождает проблемы, усложняющие разработки и поддержку веб-движков
Есть бенчмарки которые говорят, что парсинг HTML это самое тяжелое место?
dimm_ddr
02.10.2018 10:18Мне кажется в статье и у вас подразумевается разный багаж. В статье говорится про багаж от ранних версий движков, что совершенно не нужно новому. А вот от багажа веба никуда не деться, он как раз нужен и от него, я надеюсь, автор статьи не собирается отказываться.
Hardcoin
01.10.2018 10:59+3Хотите изменить — изменяйте. Есть же комитет по стандартизации. А делать движок не по стандарту — это плохо. С ИЕ уже проходили.
staticlab
30.09.2018 13:11Кстати, знаете, что «самозакрывающиеся» теги в HTML (например,
<img src="pic.jpg" />
) — это, на самом деле, ошибка синтаксиса, которую браузеры в соответствии со стандартом игнорируют?psycho-coder
30.09.2018 13:19Так ведь в HTML5 это пофиксили. Там можно не указывать слеш перед закрытием. Но да, если слеш есть его игнорят.
Heian
01.10.2018 05:33Это не ошибка, это часть стандарта XHTML, в соответствии с которым каждый тэг должен быть закрыт. Допустимо писать как
<img></img>
, так и, чтобы было короче и красивее,<img />
.
Жаль, что этот стандарт не получил развития.staticlab
01.10.2018 09:05Для режима XHTML также нужно сообщить браузеру об этом. Например, передать mime-тип
application/xhtml+xml
.
VolCh
01.10.2018 07:27Это не ошибка:
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.
Hardcoin
01.10.2018 10:57Движок, только выходящий на рынок, не может быть строже, чем существующие. Если хром поддерживает незакрытые теги (а он поддерживает), но и новый движок должен. Иначе сайты, "простимулированные" хромом, не будут открываться.
aPiks
01.10.2018 11:20Это не криво написанная страница, а стандарт. Сейчас, валидная страница html вообще должна содержать только доктайп, остальное — по желанию.
Яндекс — Гугл построены на одном движке — Хромиум, который выведет даже содержимое текстового файла с расширением html без доктайпа и тегов.
Wilk
30.09.2018 12:33+4Здравствуйте!
Могу я попросить Вас привести более страшный пример кода с умными указателями? Моя проблема заключается в том, что я не увидел страшного кода по приведённой Вами ссылке.Alex_ME
30.09.2018 13:35+1Поддерживаю. Что страшного? Разве что много вложенных шаблонов, но это в принципе на С++ зачастую так, даже без умных указателей.
RefPtr<HTMLCollection> { downcast<Document>(ownerNode()).allFilteredByName(name) }
Это какой-то свой умный указатель вебкита?
Вообще, идея отказа от умных указателей выглядит очень сомнительной. Не думаю, что именно из-за них браузеры такие тяжелые, зато они помогут не так часто выстреливать себе в ногу утечками памяти. Я немного поискал: 1, 2
- unique_ptr не имеет оверхеда по памяти и имеет оверхед по производительности в конструкторе.
- shared_ptr имеет оверхед по памяти на счетчик, оверхед по производительности в конструкторе, деструкторе, операторе присваивания. Зато разименование без оверхеда.
- По результатам у обоих в конструкторе с включенной оптимизацией небольшой оверхед.
0xd34df00d
01.10.2018 04:44+1Да ладно страшный пример кода с умными указателями.
Я открыл рандомный файл (вот серьёзно, первое, во что я тыкнул), и тут прекрасно всё, можно разбирать на цитаты.
USVString(const std::string str) : data_(str) {}
и товарищи — это пять. Можно было бы написать(std::string str) : data_(std::move(str)) {}
, можно было бы хотя бы(const std::string& str) : data_(str) {}
, но мы возьмём худшее из двух миров. И мы возьмём худшее вместо того, чтобы жить в20112018 году, когда с нами уже 7 лет как move-семантика, и ей бы неплохо научиться пользоваться, мы напишем стопицот перегрузок конструктора, вместо изящного и лаконичного
UVString(std::string str) : data_(std::move(str)) {} UVString(const UVString&) = default;
Это будет делать то же самое, только эффективнее. Писать конструкторы отдельно от
const char*
, отдельно от строк и всё такое в 2018 году не нужно уже 7 лет как.
inline
в определяемых в определении класса функциях не имеет смысла. Вообще.
operator+=
клёвенькие. Вместоdata_ += str.data_
(что делает не более одной аллокации, а потенциально может обойтись и без них) мы делаемdata_ = data_ + str.data_
. Одна аллокация гарантирована. С оператора присоединения одного символа я… Ну, в общем, да, спасибо.
Если бы я заботился о производительности, я бы добавил
&&
-перегрузкиtoUpper
,toLower
и подобных.
dublicate
, возвращающий, видимо, новую строку на хипе сырым указателем — это тоже очень хорошо. Зачем он нужен? Чем не устроил конструктор копирования? Так много вопросов, так мало ответов.
inline bool hasChar(const char str, unsigned long startsAt) { const char* i = strchr(this->data_.c_str(), str); if(i != NULL) { if(i - this->data_.c_str() >= (int)startsAt) return true; } return false; }
Вы это серьёзно? Что оно должно делать и что оно делает?
"aaa".hasChar('a', 1)
возвращает false, это так и надо?
Автор явно слышал про
std::to_string
, судя по коду выше. Но, видимо, далее захотелось нюхнуть сишца, и появилось
#define m_from(format) char buff[128]; sprintf(buff, format, value); data_ = std::string(buff); inline void fromShort(short value) { m_from("%i"); } inline void fromInt(int value) { m_from("%i"); } inline void fromLong(long value) { m_from("%li"); } inline void fromFloat(float value) { m_from("%f"); } inline void fromDouble(double value) { m_from("%f"); }
Хотя можно было просто
std::to_string(value)
в каждом из этих случаев. Правда-правда.
Самый главный вопрос. Нафига нужен этот очень тонкий враппер над
std::string
?
Ща мне за оверхед от умных указателей зато расскажут.
FlightBlaze Автор
01.10.2018 04:55Спасибо за такое внимание к деталям. USVString я как-нибудь поправлю. Теперь на данный момент, c помощью вашего тонкого юмора у меня хорошее настроение,
хотя некоторые люди из комментариев могут мне пожелать и плохое.
UPD: Читаю ваш комментарий еще раз и снова смеюсь со свои «ошибочек»
mkshma
01.10.2018 12:56+1Самый главный вопрос. Нафига нужен этот очень тонкий враппер над std::string?
Главный вопрос C++ программирования и всего такого: а писал ли ты свою реализацию строк/враппер над ними? Вот мужики теперь похвастаться могут.
Wilk
01.10.2018 13:32Здравствуйте!
Мне хватило ужаса от приведённых ранее ссылок, а Вы ещё больше пугаете.
Мои варианты ответа на вопросы:
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); }
0xd34df00d
01.10.2018 16:322. Да, делайте интерфейсы тонкими.
6. В идеале — да. Можно ещёstd::string::find
(и даже лучше, я не так давно бенчмаркал, оказалось, чтоstd::string::find
существенно быстрее и на уровнеmemchr
).
7. Да, почти. Я не уверен (и сходу не нагуглил), можно ли перегружатьstd::to_string
для поддержки собственных типов данных, или же правильной идиомой будет как соswap
:
using std::to_string; data_ = to_string(value);
Wilk
01.10.2018 16:437. Видимо, как минимум формально, нельзя.
0xd34df00d
01.10.2018 16:58Ну, значит, точно надо с
using
, и SFINAE-акробатика несколько усложняется.
NeoCode
30.09.2018 13:00Круто!
А есть ли у вас режим редактирования?
Почему спрашиваю: есть всем известные движки html, со всеми наворотами, но совсем нет удобных WYSISYG редакторов более легких форматов — таких как Markdown, FB2/FB3 и т.д. Или их делают на основе движков html типа Webkit и тащат вместе с движками кучу лишнего, т.е. написание такого редактора сводится к затыканию дыр и возможностей вставить в редактор то что там не должно быть. А чего-то простого и минималистичного, не завязанного на браузерных монстров — нет.Taraflex
30.09.2018 13:59+1В qt есть doc.qt.io/archives/qt-4.8/richtext-html-subset.html#using-html-markup-in-text-widgets
не путать с QWebEngine* компонентами.
GrimMaple
30.09.2018 13:37+2Не поймите меня неправильно, но из того, что написано, я понял примерно следующее.
На данный момент ваш движок поддерживает парсинг HTML и кое-как парсинг CSS? Т.е. по сути он не умеет вообще ничего и на данном этапе совершенно бесполезен как таковой?
Я посмотрел ваши исходные коды на гитхабе и, честно говоря, ННП. Если вы этой статьей планировали привлечь людей к разработке, то крайне советую хоть какое-то структурное описание проекту сделать, и желательно всё-таки оформить файлы исходных кодов, а то те редкие комментарии (причём на русском) не помогают от слова совсем.
В целом, желаю удачи в этом нелёгком начинании. Был бы заинтересован помочь, если дело сдвинется хотя бы до рендера страничек :)FlightBlaze Автор
30.09.2018 15:45Спасибо большое. До рендера страничек еще пару to-do листов, а после рендера я сделаю интерактивное выделелние и поддержку contenteditable.
GrimMaple
30.09.2018 16:07Просто люди любят глазами. Представьте, что вы приходите к потенциальным инвесторам и заявляете, что пишете новый супер браузер, который будет лучше, быстрее и вообще качественней, чем все остальные. Инвесторы заинтересованы, вы рассказываете им о вашем крутом парсере, который соответствует всем стандартам и показывает просто невероятные цифры в бенчмарках. Но инвесторам всё-равно, они постоянно твердят вам: «а где посмотреть?»
В данном случае инвесторов можно свободно заменить на читателей. Почитать это хорошо, но хотелось бы чего-нибудь наглядного — какие-нибудь тесты, пусть даже глуповатые типа «парсим миллион тегов в секунду». Это было бы куда более привлекательно, как мне кажется.dom1n1k
30.09.2018 16:17Да дело даже не в любви, а просто для браузера визуальный рендеринг страниц — это тот основной функционал, ради которого всё и затевается. Если его нет (ну хоть в каком-то виде) — нет и браузера, есть только набор вспомогательных кирпичей.
timdorohin
30.09.2018 17:03+1А я немного не согласен, очень часто может пригодится headless движок, если надо заниматься парсингом информации с сайтов.
dom1n1k
30.09.2018 17:10Парсинг — это парсинг, не браузер.
А браузер, даже headless, всё равно обязательно подразумевает рендеринг (просто headless не показывает результат на экране).
FlightBlaze Автор
30.09.2018 18:37+2Рендеринг и компоновку я еще успею сделать, а вот api, css каскадирование, и прочее нужно обязательно сделать. Мы же хотим интерактивную страницу, а не просто статичная нарисованная картинка.
Hokum
01.10.2018 09:47Зависит от ировня интерактивности, для начала можно отображать статичную страницу с применеными стилями и, опционально, возможностью перехода по гиперссылке. Как мне кажется, этого уже достаточно, чтобы его можно было начать использовать где-нибудь еще и привлечь внимание разработчиков.
К общим замечаниям, если планируете привлечь других разработчиков, то выложите в репозиторий правила форматироавния для какого-нибудь распространенного автоформатера кода. Судя по всему вы форматируете код в ручную, что не очень хорошо для привлечения других разрабоотчиков — не все форматируют как так же. Так же попробуйте начать использовать тесты, проект новый, принимаемые решения могут оказаться не удачными спустя какое-то время, а с тестами и рефакторинг проще, и частично они помогу прояснить, какое поведение ожидалось.
Durimar123
01.10.2018 18:2899% что результат этой работы будет один — набор скила и знаний, хотя если цель в этом, то конечно стоит продолжить.
Движков не 4, а куда больше, десятки если не сотни.
Парсинг HTML/CSS это меньше 5% от задачи даже с учетом расчета параметров. Хотя все параметры все равно не посчитать — многие от редеринга зависят.
5% расчет реальных параметров тегов (зависящих от дисплей и их наследование)
5% рендер имиджей (включая динамические и background всех мастей)
5% разбивка и рендер текста
5% рендер с учетом параметра flow
15% рендер таблиц
10% веселуха с импут котролами
5% форматирование после ресайза
5% движение по документу (скрол линки и т.п.)
10% борьба с чарсетами, иероглифами и поломанным блин UTF
5% динамическая загрузка мегабайтных документов и как следствие перефарматирование всего предыдущего
10% печать документа и особенно инпут контролов :)
3% доводка для тестовых ХТМЛ (есть где то для проверки стандарта)
6% обработка багованных ХТМЛ
и уже не помню, что там еще из время затратного
Durimar123
01.10.2018 17:44Рендерин это без сомнения тяжко, но когда на рендеринг накладывается селектирование, переходы по тексту, изменение размера браузера, обработка тега INPUT, вывод на принтер. Вот это веселуха по взрослому.
И все равно это даже не 20% браузера. Надо будет вечность дописывать например, систему загрузки файлов, систему post/get, различные шифрования, поддержку сотен других инструментов.
ИМХО, нафиг — это все дорого и бесперспективно.
babylon
01.10.2018 15:53Парсер читает токены слева направо. Для каждого типа свой подход парсинга.
Правильнее было бы справа налево. Так как в противном случае мы заранее не знаем какого типа будет значение (array или object) Можно конечно свести к одному типу, но это не то.
phantom-code
30.09.2018 13:38Вот непонимаю, почему крупные заинтересованные компании (Google, Microsoft, Apple, Amazon, и т.п.) не соберутся и не
переизобретут велосипедсоздадут замену для технологий, применяемых сейчас в вебе. HTTP, HTML, CSS имеют столько исторически сложившихся недоразумений, что проще сделать что-то новое, с учетом современных реалий. Тот же Google может запросто добавить поддержку новой технологии в свой браузер. А по прошествии периода адаптации, объявить старый стек технологий небезопасным/устаревшим, как они уже делали с Flash, HTTP.
Глядишь, и не нужно будет трать столько усилий на написание и поддержку браузерного движка.GrimMaple
30.09.2018 13:55+1На большинство таких вопросов легко ответить: посчитайте, сколько это стоит. И сколько прибыли это принесет :) В случае с HTTP люди уже пытаются что-то сделать, однако прошло уже три года, а воз и ныне там. Люди вообще не любят менять то, что «итак работает», да и невыгодно это.
arielf
30.09.2018 20:32То же самое говорили про компилеры, например про gcc, внезапно аспирант Chris Lattner плюнул и написал офигенную LLVM, её купил Apple, за пару лет запилили компилеры кучи языков, а щаз на Clang + LLVM перешли кучи проектов и компаний.
Goodkat
30.09.2018 21:42+1Компиллятор — он используется локально и генерирует совместимый с существующими ОС и процессорами код.
Т.е. остальным участникам не нужно ничего менять.
phantom-code предлагает заменить весь существующий веб на какую-то новую технологию.
arielf
01.10.2018 00:15+2Чтобы разные проекты — завязанные на gcc — перешли на Clang, нужны причины! И про LLVM вначале говорили, что он не влетит — а затем, что жизнь его лишь в границах Mac OS X, а затем…
Резюме: временами полезно переписывать с нуля оси, компилеры, браузеры и иные базовые вещи нашего мира. Но бросая всем вызов, лучше быть всё же аспирантом американского универа! ;-)
Hardcoin
01.10.2018 11:07+1Так ваш пример про аспиранта, а не про корпорации. Корпорации намного инертнее одного человека. Может за 20 лет и поменяют, почему нет?
zelenin
30.09.2018 14:24все так и происходит. Вышеозначенные компании находятся во всех инициативных и исполнительных группах, перепиливают старые стандарты, пишут новые, форсируют переходы на новые технологии.
phantom-code
30.09.2018 15:02Они просто улучшают текущие технологии, не меняя основную идею. HTTP до сих пор использует отдельное TCP соединение для каждого нового запроса (я в курсе о гугловском SPDY), а информация передается в текстовом виде. Это конечно человекочитаемо и удобно, не спорю, но на практике все сводится к избыточному потреблению электроэнергии, ресурсов компьютера и пропускной способности канала.
zelenin
30.09.2018 15:04у них мировая аудитория. Они допиливают до удобоваримого состояния внедренное, параллельно разрабатывая новое на будущее.
srhbdv
30.09.2018 15:13HTTP до сих пор использует отдельное TCP соединение для каждого нового запроса (я в курсе о гугловском SPDY), а информация передается в текстовом виде
HTTP/2 и WebSockets вас чем не устраивают?GrimMaple
30.09.2018 18:06Ну вот меня они всем устраивают, например. И что? Как убедить всех подряд, что 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 еще очень и очень долго :) И поддерживать его.VBart
30.09.2018 18:15HTTP/2 объективно очень плохой протокол и не является заменой HTTP/1.x. Нет у него будущего.
GrimMaple
30.09.2018 18:28Это был своего рода абстрактный пример для донесения мысли, я не очень хорошо знаю веб и до HTTP/2 мне мало дела. Работает? Хорошо, пусть работает. Мы можем придумать XXXUBERTTP/9001.0 и любой другой мега-хороший и супер стандарт. Но только толку от него, если HTTP работает, и миллионы (если не миллиарды) сайтов успешно работают так, как есть сейчас. В компьютерах всё строится на очень своеобразных решениях, которые диктовались спецификой требований тех лет, легаси коде и костылях. Это везде, не только в вебе или HTTP. Посмотрите на Xorg, Linux Kernel и gcc. Хотя бы на них. Это просто клады легаси кода и поддержки уже давно несуществующих или слишком малозначимых платформ. Люди вон до сих пор находят вакансии на RPG, Delphi и PHP, хотя все они признаны мёртвыми. Ну не денемся мы никуда от легаси.
P.S. Кстати Xorg пытались выпилить Вэйлендом, но не взлетело, впрочем примерно понятно, почему. Да и сам Вэйланд почти целиком эмулирует Xorg.VBart
30.09.2018 18:45Учитывая, что все дистрибутивы потихоньку переползают на вейленд — странно писать о том, что он не взлетел.
Не стоит путать легаси с надежным, проверенным временем решением. Должна происходить постепенная эволюция, а не революции с майданами. Когда горячие головы, терзаемые NIH-синдромом без десятков лет опыта за плечами, приходят с лозунгами: «а давайте всё перепишем!» — ничего хорошего на выходе не получается.
Достаточно коротко и ясно происходящее описал легендарный Poul-Henning Kamp в своей заметке: queue.acm.org/detail.cfm?id=2716278GrimMaple
30.09.2018 19:04Я бы не сказал, что все дистрибутивы на него «переползают». Как максимум — предоставляют возможность использовать. Ubuntu вон так успешно ввела Wayland, что аж откатилась назад к Xorg в 18.04. Впрочем, учитывая специфику ОС и мира открытого ПО, поставить его может кто угодно и когда угодно, и собрать его можно попытаться подо что угодно. Включение пакета в репозиторий или возможность установить что-то еще не показывает, что он таки взлетел. Максимум находится в том же положении, что и HTTP/2.0
Но это всё мелочи, мы сходимся в базовом аргументе — нельзя просто взять и сделать новый Интернет, уже слишком поздно для этого. А всё остальное — холивары :)WitcherGeralt
01.10.2018 01:08Ubuntu вон так успешно ввела Wayland, что аж откатилась назад к Xorg в 18.04
Опять глупости, вы делаете выводы, не располагая даже общеизвестной информацией. Релиз-цикл бунты предполагает выкатывание LTS-релизов, в качестве дефолтов туда попадает самое стабильное, а в промежуточных релизах, соответственно, могут позволить себе больше. И тем не менее, вейланд присутствует как минимум в дефолтном варианте с Gnome, лично я его и использую.
balamutang
01.10.2018 13:57но новый интернет уже делается, когда вместо сайта в браузере телефона открывается приложение этого же ресурса, которое взаимодействует с сервером оптимально, а не прогружая почти каждый раз весь интерфейс и данные через HTTP/HTTPS при переходе в другой раздел :)
WitcherGeralt
01.10.2018 00:56HTTP/2 финансово катастрофически невыгоден
Лол, что? Браузеры поддерживают, а в nginx оно включается правкой одной строки конфига. Где чего не выгодно?
VBart
30.09.2018 18:09HTTP до сих пор использует отдельное TCP соединение для каждого нового запроса
И это правильно, так и должно быть. А от того ужаса, который вышел в виде SPDY и HTTP/2 ещё долго придется плеваться. И да, в результате в SPDY и HTTP/2 гораздо больше накладных расходов.phantom-code
30.09.2018 18:16Я не говорил, что SPDY или HTTP/2 не имеют проблем. Однако, одно соединение на один запрос довольно избыточно. В чем, по вашему, правильность данного метода? Даже для реализации «сессии» пришлось придумывать костыли. Теперь каждый второй сайт уведомляет о том, что он использует cookie и просит понять и простить. А все из-за того, что «это правильно, так и должно быть».
VBart
30.09.2018 18:38+3Однако, одно соединение на один запрос довольно избыточно.
В чем заключается избыточность?
В чем, по вашему, правильность данного метода?
В том, что TCP это протокол транспортного уровня и проблемы транспортного уровня должны решаться на транспортном уровне. Один запрос — это один поток данных. Один поток данных — одно независимое TCP соединение. Это правильно, это позволяет применять flow control на уровне каждого потока, а также роутить эти запросы независимо друг от друга. Они могут обрабатываться разными серверами, они могут идти разными маршрутами. Всё это позволяет лучше масштабировать нагрузку и лучше справляться с ошибками.
Даже для реализации «сессии» пришлось придумывать костыли.
В чем заключаются костыли? HTTP — это stateless протокол, благодаря этому он очень хорошо масштабируется, с помощью него можно реализовать удобный и красивые RESTfull интерфейсы. Не будь он stateless, костыли бы пришлость расставлять повсюду.
Теперь каждый второй сайт уведомляет о том, что он использует cookie и просит понять и простить. А все из-за того, что «это правильно, так и должно быть».
Смешались в кучу кони, люди, мухи, котлеты… Каждый второй сайт уведомляет об использовании cookies согласно новому закону евросоюза. Это не имеет никакого отношения к протоколам, а является законодательным актом.
Более того, работа с cookies и сессиями, как и вся остальная семантика HTTP — совершенно одинаковая, что в HTTP/1.1, что в HTTP/2 и SPDY.
Работу с сессиями вероятно можно было бы улучшить, но это никак не связано с количеством TCP соединений, и ни HTTP/2, ни SPDY — вообще ничего в этом отношении не улучшают.phantom-code
30.09.2018 20:08В чем заключается избыточность?
Установка соединения (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.
Доработки и улучшения — это хорошо. Но я говорю о «попробовать спроектировать с нуля исходя из текущего опыта». Я понимаю, что это не быстрый процесс и его внедрение может занять многие годы. Но иногда требуется отбросить обратную совместимость и дать дорогу чему-то принципиально новому.RPG18
30.09.2018 20:27С сжатием уже не plain text. Да, остаются еще заголовки, но есть WebSocket.
но при этом быстрее и выглядит на всех устройствах одинаково.
Он быстрее ровно настолько, насколько оптимизирован Qt. При этом там так же есть свои нюансы. Например под iOS нет JIT компилятора для QML.
phantom-code
30.09.2018 20:33С сжатием уже не plain text. Да, остаются еще заголовки, но есть WebSocket.
На сжатие/распаковку требуются ресурсы процессора (как сервера, так и клиента).
Он быстрее ровно настолько, насколько оптимизирован Qt. При этом там так же есть свои нюансы. Например под iOS нет JIT компилятора для QML.
Конкретно QML был всего-лишь примером.
aram_pakhchanian
01.10.2018 09:39На шифрование-дешифрование тоже требуются ресурсы процессора. Может тогда от HTTPS отказаться тоже? А неизмеримо бОльшие ресурсы требуются на поддержание электрического или беспроводного подключения сетей, и эта мощность лишь частично коррелирует с трафиком. И львиную долю трафика составляется не текстовый контент (в конце концов способность человека воспринять текст ограничена физиологически), и даже не код скриптов (и кстати, подумайте, как его передавать бинарно и при этом не навредить разнообразию скриптовых механизмов, гарантирующему их развитие, а также безопасности их выполнения), а видео и фото, которые сжаты максимально. Я думаю, вы сейчас не ту задачу решаете.
VBart
30.09.2018 20:32Установка соединения (SYN->ACK->ACK) с передачей cookies для каждого запроса дает лишнюю нагрузку на сервер и на канал. Для одного клиента она не существенна, но когда клиентов тысячи, она внезапно начинает играть свою роль. А если мы вспомним, что внутри у нас plain text, то становится еще грустнее.
Нагрузка от TCP хэндшейка просто смешная по сравнению с дополнительной нагрузкой, которую дает реализация ещё одного пакетного слоя для мультиплексирования и ещё одного flow control внутри соединения. Для работы HTTP/2 требуется больше накладных расходов и больше пересылать TCP-пакетов, а также расходуется больше памяти и больше процессорных ресурсов. А внутри по сути такой же plain text, который также нужно парсить.
Безусловно. Только сами cookies появилсь, чтобы сервер мог хоть как-то хранить на клиенской машине информацию и различать сессии между собой. Исторически, это был именно костыль.
А как нужно их хранить и где по вашему? В чём же заключается «костыль» и кто мешает хранить простой ключ сессии, как в общем-то многие и делают?
Но иногда требуется отбросить обратную совместимость и дать дорогу чему-то принципиально новому.
Наверное такие решения должны прорабатываться, обсуждаться и приниматься с особой осторожностью, чтобы не сломать то, что работает годами, не сделать хуже. А сейчас мы видим то, что большие корпорации проталкивают свои протоколы в своих корыстных целях, при этом заставляя всех остальных страдать. Как в своё время было с Microsoft и IE, сейчас то же самое происходит, только в руках одной мегакорпорации оказались, как самые популярные браузеры так и самые посещаемые веб-ресурсы, а потому они в результате затачивают веб под себя, наплевав на остальных. Имея при этом большие маркетинговые ресурсы, они всё это подают под соусом улучшений и инноваций, легко одурачивая основную массу, которая плохо себе представляет работу сетевых протоколов и повторяет из статьи в статью одни и те же заблуждения касательно HTTP/1 vs 2.phantom-code
30.09.2018 20:44А как нужно их хранить и где по вашему? В чём же заключается «костыль» и кто мешает хранить простой ключ сессии, как в общем-то многие и делают?
Я бы хранил все данные на сервере и отдавал клиенту только его ID или ID сессии. Костыль заключается в том, что сначала был разработан stateless HTTP, а уже потом появилась необходимость различать сессии/клиентов, в результате чего появились cookies. Конечно, если рассматривать stateless как преимущество, то это уже не костыль. Лично я не вижу особой необходимости в stateless протоколе, но готов поверить вам, т.к. в данном вопросе не имею достаточно опыта.
Наверное такие решения должны прорабатываться, обсуждаться и приниматься с особой осторожностью, чтобы не сломать то, что работает годами, не сделать хуже.
Да, именно взвешенное решение, выработанное в ходе обсуждений я и имею в виду.lorc
01.10.2018 12:05Так собственно, в большинстве случаев все так и работает — сервер хранит все у себя, а клиенту отдает ID в виде одной куки.
Вообще, кука в любом случае нужна, ибо мир не идеален, и сессии могут рваться. В вашем случае — клиент переподключается и получает новую сессию. А если он хочет восстановить старую — ему опять же нужна кука в каком-то виде.
phantom-code
01.10.2018 12:07Или его личный уникальный ID, который он сообщает серверу.
lorc
01.10.2018 14:36Ну вот этот самый личный уникальный 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 пользователя, подписать ее и тогда любой сервер кластера будет знать что вы — это вы, даже без синхронизацию через общую базу.
symbix
01.10.2018 01:11В том, что TCP это протокол транспортного уровня и проблемы транспортного уровня должны решаться на транспортном уровне. Один запрос — это один поток данных. Один поток данных — одно независимое TCP соединение.
Звучит правильно, но… но… ведь так можно оправдать дизайн протокола FTP :-)
Rast1234
01.10.2018 07:53А что с ним? Если не учитывать неактуальные уже фичи типа перекодирования байтов, и неактуальные на момент создания протокола вопросы безопасности, он прекрасен своей простотой и тем, что работает. Просто работает. И понятно куда смотреть, если не работает как ожидалось.
Goodkat
30.09.2018 21:45информация передается в текстовом виде
Информация давно уже передаётся в сжатом виде, а текстовый оставлен только для совместимости.
DaneSoul
30.09.2018 21:21А разработка нового стандарта породит два рода проблем:
1) Производителям браузеров все равно прийдется поддерживать старые стандарты, так как на них написано уйма сайтов, которые обновляться не будут, но которые могут быть важны отдельным пользователям.
2) Надо переучиваться всему сообществу веб разработчиков, выпускать новые книги, новые учебные курсы и т.п. — это встретит большое сопротивление!swelf
01.10.2018 12:02-1На самом деле не совсем, вот есть у нас например всякие телеграмм, whatsup, fb мессенджеры. Ими пользуются сотни миллионов людей, под них уже сейчас пишутся боты для интерактивного взаимодействия системы и человека. С таким же успехом, как выпустили fb мессенджер, facebook может сделать зеркало своего сайта на новой технологии и выпустить для него браузер и сказать «Люди, пользуйтесь, пилите свои сайты вот на этом новом html10». И поставят люди себе декстопный клиент под facebook, и начнут программисты писать сайты в том числе и под новый стандарт(а скорее всего система сборки будет и под новый и под старый собирать сама). Так что старый легаси вообще не проблема, будет просто у людей браузер для старых сайтов и для новых. Проблема думаю в том, что люди которые понимают как это сделать, не видят в этом смысла, потому что в конце концов получится такой же монстр.
DaneSoul
01.10.2018 16:50Да, так можно, но только это не будет браузер для Веба — это будет браузер для facebook.
И вот такое расщепление веба на внутренние стандарты — это худше что можно для него придумать…
staticlab
30.09.2018 14:01+4насколько ли реально создать достойную альтернативу крупным проектам, история которых начинается с девяностых годов. Мой новый движок создается с нуля, а значит его история начинается — сегодня.
Servo — тоже новый движок, разрабатываемый настолько с нуля, что под него даже новый язык программирования написали. Используются современные возможности, такие как многопоточность и рендеринг через GPU. Трудятся над ним больше десятка инженеров, сделавшие уже 34 тыс. коммитов, но до приемлемого состояния ещё очень далеко.
erlyvideo
30.09.2018 14:11угу. Нахрена тратить время на C++, если проблемы языка очевидны настолько, что целые языки придумывают под браузеры. Тот же раст например.
Alexey2005
30.09.2018 19:04+1Не завидую я этим инженерам. Писать не что-нибудь, а браузер — программу, где полным-полно связанных списков и деревьев, на языке, в котором даже нет полноценного ООП, и многие паттерны проектирования реализуются через тонны костылей — это ж врагу не пожелаешь…
staticlab
30.09.2018 19:18Функциональные языки при обработке связанных списков и деревьев как-то же без ООП обходятся.
MikailBag
30.09.2018 22:21Я писал дерево отрезков, Фенвика, декартово и много других структур данных. И каждый раз это примерно 2 шаблонные структуры. В Расте такое делается также без проблем.
0xd34df00d
01.10.2018 04:49Связные списки и деревья именно что хорошо обрабатывать на функциональщине. ООП и вот эти вот все паттерны там не то что не нужны, а вредны.
popov654
30.09.2018 19:42А что не так с его состоянием? Вроде работает шикарно.
staticlab
30.09.2018 19:58Например, https://github.com/servo/servo/issues/13495.
И гитхаб выдаёт ещё 115 незакрытых багов с меткой I-wrong для самых разных сайтов.
F0iL
30.09.2018 14:10Те ошибки, которые были допущены на начальных стадиях разработки остаются в проекте до конца. Самый яркий пример этому — умные указатели в C++
Только вот «наследие со времен 90-х» не помешало Google после форка WebKit в Blink выпилить там умные указатели и завезти Garbage Collector, как и сделав красивее код, так и решив некоторые другие проблемы с работой с памятью.
lastmac
30.09.2018 15:34Привет!
Я уже было обрадовался, подумал вот, есть такие же психи как и я. Но, посмотрев исходники разочаровался.
1) Каким спецификациям соответствует парсинг HTML? Я так понял, что вы из головы написали парсер. Штука эта давольно сложная, тем более чтобы написать её правильно с заделом на будущее. Судя по вот этому о скоростях мечтать не приходится. Это действительно весь HTML парсер? Это тоже странно выглядит.
2) Каким спецификация соответствует парсинг CSS? Опять же, судя по коду никаким. Вы просто взяли из головы то, что знаете о CSS и сделали для этого парсинг. Вообще, CSS раздербанить ни фига не простая задача. Уж поверьте моему опыту.
3) У вас не верно сделана сериализация HTML. Точнее сказать, она сделана из каких-то ваших соображений. В спецификации чётко описано поведение сериализатора.
К сожалению, вы не сможете показать страницу быстрее других, у вас для этого ничего нет.
А теперь попугаю, немного :).
У вас исходники всего этого дела занимают 312КБ. Чтобы хоть как-то оценить насколько ничего нет: в проекте lexbor один только html парсер занимает 1.8МБ. DOM, в котором почти ничего нет, только минимум для создания и удаления нод, элементов, атрибутов 100КБ.
Чтобы понять масштаб того, что надо делать посмотрите мой roadmap, и это процентов 10 от полноценного браузерного движка.
Ваши бы силы да в нужное русло.
Поправьте меня если я где-то ошибся.FlightBlaze Автор
30.09.2018 16:04+1Насчет размера.
Я не понял, важнее функционал или размер исходников?lastmac
30.09.2018 16:25Дмитрий, важен не размер, нет.
Важно, чтобы ожидания сходились с заявлениями. У вас, к сожалению, нет парсера HTML, CSS, у вас нет сериализаторов. Да и странно заявлять о сериализации даных. Куда важнее заявить о парсинге чанков, парсинге фрагментов. У вас нет работы с неймспейсами. Не знание HTML спецификации сразу кинулось в глаза после фраз о кавычках, это самое стандартное поведение, зачем это оговаривать отдельно? У вас есть что-то, что вы сами придумали и назвали это парсером HTML, CSS.
Я никак не пытаюсь «наехать». И я искренне обрадовался когда прочитал заголовок, но по факту у вас пустышка + непонимание базовых вещей. Если вы хотите, то можете написать мне, что нибудь да обсудим.
Размер тут как показатель, на глаз прикинуть.FlightBlaze Автор
30.09.2018 16:43Александр, спасибо за конструктивную критику, она действительно важна для реализации сложных проектов. С удовольствием обсудим проект.
FlightBlaze Автор
01.10.2018 03:09А что такое чанки и фрагменты, и зачем их парсить?
lastmac
01.10.2018 12:25+2Чанки (chunks) — фрагменты.
Браузеры процесят хтмл кусками. Прилетело по сети 4к данных, эти данные идут на парсинг и так далее. Данные могут быть прерваны в любом месте, соответственно и продолжить обработку надо уметь с того места где закончил. Но, тут магии нет, если ты посмотришь на спецификацию то поймешь, что она написана так, чтобы это работало "из коробки". Токенизатор на вход принимает codepoint (unicode) по одной штуки и решает куда дальше рулить. Это обычная стейт машина.
Фрагменты — парсинг хтмл фрагментов очень важен. Это так называемый innerHTML. Штука эта довольно тяжелая для выполнения. Как оно должно работать так же описывает спецификация. Тяжелая она потому, что для неё необходимо создавать новый парсер, новый Document объект и root element + всякая логика.
Сделать, хотя бы, парсинг хтмл быстрым задача тоже интересная.
Ты, конечно, молодой и активный. Но прежде чем делать громкие заявления изучи как устроены текущие браузеры, посмотри почему они все отрабатывают страницы одинаково (спецификации).
Конечно, фигачить из головы куда интереснее. Делать что-то по спецификациям нудное занятие.
Чтобы что-то сделать лучше необходимо понять текущие проблемы. Нужен опыт. У тебя, к сожалению, опыт отсутствует как в программировании так и в понимании браузерных движков.
Но шуму ты наделал много.
FlightBlaze Автор
01.10.2018 18:50Хорошо, спасибо! Да, и у меня еще поддерживается get/set innerHTML и get/set outerHTML.
lastmac
01.10.2018 19:23Эх, вы либо вообще не понимаете о чём я пишу, либо, я даже не знаю. В общем, удачи вам.
vintage
30.09.2018 16:38-2Я вот тоже пилю свой браузер. Точнее пока что браузер внутри браузера, а когда обкатаю алгоритмы, то уже нативной реализацией займусь. Только моя мысль в том, что нет смысла реализовывать весь тот легаси, что накопился за десятки лет, а ограничиться какой-то своей простой гибкой спекой, так что сайты, написанные с учётом этой спеки, получат все преимущества новой лёгкой, быстрой и гибкой реализации, а остальные будут просто открываться во встроенном chromeframe.
Вообще, я тут создал чат в телеграме. Присоединяйтесь, будем обмениваться идеями :-) t.me/dev_browserlastmac
30.09.2018 16:54+1О каком легаси вы пишете? В спеках всё довольно логично и понятно. Есть, конечно, шероховатости, но в целом всё ясно.
Как вы поймёте, что сайт «нормально» отображается с помощью вашего движка? Что это будет за урезанная спека которая сможет предоставить весь нужный набор опций для верстки и будет лучше чем сейчас?
Чтобы вам хоть как-то попытаться пропихнуть свою спеку вам надо стать гуглом, и то не прокатит.
Есть стандарт который все знают и поддерживают, опираются на него. Идея написать свой движок, но если чего отдавать на отрисовку гуглу за гранью разумного.vintage
30.09.2018 17:51+1Да хотя бы даже фривольности с незакрытыми тегами в HTML. Можно ограничиться XHTML парсером, чем значительно упросить и ускорить реализацию. От разработчиков обеспечить совместимость с xhtml не составит труда. Кучу устаревших css свойств, вендорных префиксов и прочего барахла можно смело выбросить, опять же описав что использовать не следует, а что следует использовать вместо.
Определять просто — специальным флагом в коде разработчик явно берёт на себя обязанность соблюдать более строгие требования. Подумать о том, как можно было улучшить текущий стек, я и предлагаю подумать. У меня, разумеется есть куча идей разной степени тяжести.
И давайте вы свой пессимизм оставите ведру с крабами. Возможно тот же гугл заинтересуется проектом, когда он покажет свои преимущества. Глаза боятся — руки делают. А если вам страшно так, что руки немеют — так вас никто не заставляет. Каждый сам решает чем ему интересно заниматься.
Никто не знает веб стандарты в полной мере. Это одна из бед этого переусложнённого бардака.
Taraflex
30.09.2018 17:21Судя по вот этому о скоростях мечтать не приходится. Это действительно весь HTML парсер? Это тоже странно выглядит.
Там кстати можно применить оптимизацию habr.com/post/166201
У html тегов длиннее 9 символов начальные части не пересекаются, поэтому их можно отбросить при вычислении хэша.TheShock
01.10.2018 02:43Тот кусок вообще нужно выкинуть, зачем его оптимизировать? Тем более так спичечно
Alesh
30.09.2018 15:44Насколько я понял из первых абзацев, вы считаете, что умные указатели — это зло?
Хм, интересная точка зрения. И деструкторов в классах я что-то тоже не вижу, очень интересно)FlightBlaze Автор
30.09.2018 16:14Garbage collector у меня в to-do, можете не переживать по этому поводу.
andreymal
30.09.2018 16:22+1Без рендера неинтересно — это самое сложное. А парсеры может написать почти кто угодно, особенно если не соблюдать стандарты и не делать оптимизаций
finlandcoder
30.09.2018 18:18+1JS нет. Рендеринга нет. DOM-дерево не оптимизировано. Точнее автор даже не доказал, что оно оптимизированное и корректное. Что его модель вообще будет рисоваться и ложиться на GPU. Что там корректный байт-код или он собирается строки гонять на каждый кадр.
FlightBlaze Автор
30.09.2018 18:41andreymal
30.09.2018 18:43Мне кажется, заявлять о «полноценном браузерном движке с нуля» можно будет начинать, только когда рендеринг появится. Хотя перечисленное в комменте тоже нужно, на данный момент говорить по-моему ещё не о чем
mspain
30.09.2018 17:59Слабоумие и отвага.jpg
alan008
01.10.2018 09:30-1Какие все злые. Сами бы не сделали и доли того, что сделал автор. Потому что сложно, лень, никому не нужно, всё равно будет не по спецификациям и т.д. Разве это всё важно? Задумка интересная, автор молодец.
mspain
01.10.2018 09:57>Сами бы не сделали и доли того, что сделал автор
Аффтар НИЧЕГО полезного не сделал, сколько бы строчек ненужного кода он в этот проект не накидал. Ибо, как активно делающий web scrape на java, авторитетно заявляю, даже если ему ещё 20 студентов (что маловероятно) дать в помощники, они не будут успевать. И уж точно это не будет самый быстрый и «архитектурно правильный» движок.
Самый продвинутый headless browser под java — HtmlUnit пилит команда из человек 5, причём безбожно проигрывают в гонке. Если 4 года назад можно было почти всё скрейпить, сейчас чуть ли не каждый второй сайт с авторизацией выпишет облом.
При этом безголовый браузер это далеко не полноценный браузер. Нужна лишь навигация по DOM.
В общем, через много лет это будет в самом лучшем случае что-то вроде chromium с выключенным js. Но в хроме я, когда сильно хочется, жму кнопочку «включить js», а у них такой волшебной кнопочки не будет.
srhbdv
01.10.2018 09:58+6Так он ничего не сделал. Вот вообще.
Это не браузер во-первых. Не браузерный движок во-вторых. Так в-третьих, это даже не html\css-парсер. Рядовой разработчик делает больше, когда пишет обработчики кастомных протоколов или форматов данных.
Учитывая, что автор — ученик седьмого класса, как проект по информатике его старания конечно — это и хорошо. Но громкие заголовки и бег впереди паровозов на мачтах желтых статей без бэкграунда — это исключительное зло, особенно когда оно присуще таким вот юным падаванам.
Или вас Денисы Поповы и Бабушкины совершенно не смущают? Так давайте отправим Дмитрия Козичева на ЦТВ. Расскажет нам в эфире новостей, как он изобрел убийцу хрома.
andreymal
30.09.2018 18:33Вообще, если говорить об альтернативных движках, то NetSurf на первый взгляд выглядит поинтереснее сабжа: свой HTML-парсер есть, CSS-парсер тоже есть (соответствие стандартам не проверял), JS-движок Duktape с последними фишками ES2015+. Затыки, естественно, на самом сложном: рендер (в отличие от сабжа) есть и рисует примерно на уровне IE8 (лично мне этого достаточно, у меня успешно получается верстать под NetSurf), а вот полноценного DOM API и событий (ещё) нет, из-за чего JS бесполезен, несмотря на его наличие
AnarchyMob
30.09.2018 18:39В качестве инструмента для рендеринга будете использовать Skia, Cairo, AGG или что-то самописное?
bvdmitri
30.09.2018 18:43+3Почему у вас в коде абсолютно везде используется передача копии объектов в функции? Никак не используются преимущества С++ по эффективной работе с ссылками на объекты.
Мало того что это абсолютно неэффективно, так еще и во многих случаях может ломать код.
Например здесь сложно сказать, что произойдет после выхода из функции так как по факту объект 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
0xd34df00d
01.10.2018 05:05Шта. Вы в корне неправы.
data
иtext
— обычные объекты внутри Token и Text соответственно. В строке, напрмер,misc->data = str
эта самаяstr
скопируется вdata
, и всё будет хорошо (да и иначе, даже если принимать по ссылке, то как в рамках вашей логики будет работать что-то вродеfromMisc("смотри, ма, я временный объект")
?).
DOMString
мне послеUVString
выше смотреть не хотелось, но я себя всё-таки заставил, и не зря — это просто алиас наUVString
. Во-первых, деструктор там есть, во-вторых, даже если бы его не было, то сгенерированный по умолчанию точно так же очищал бы внутренности объекта.
Я даже немного поражён тем, сколько людей с вами согласны.
bvdmitri
01.10.2018 08:47+1Каюсь, вы правы насчёт деструктора, там же в коде обычный std::string под капотом. По привычке подумал — раз есть свой string значит это обертка над raw char* — быстро проглядел и заметил что деструктор пустой. Но это тоже плохо на самом деле, убивается огромный пласт оптимизаций, move конструкторов написанных для std::string.
Для вашего примера с временными объектами придумали move-семантику.
Тем не менее вопрос об абсолютно неэффективной работе со строками и постоянным копированием (даже в тех функциях происходит два копирования которые можно, и нужно избегать) остаётся открытым0xd34df00d
01.10.2018 16:36Для вашего примера с временными объектами придумали move-семантику.
И ровно поэтому в данном контексте принимать по значению нормально (и даже лучше, чем по ссылке). Надо только заменить
misc->data = str
наmisc->data = std::move(str)
.
Посчитайте сами число аллокаций строк для каждого из случаев и убедитесь.
Но с общим вашим тезисом я не могу поспорить, оно там весьма неэффективно. Ну и успехов автору в попытках отследить, кто когда что будет удалять.
bvdmitri
01.10.2018 17:48Я бы так сказал, из названия класса DOMString для меня понятно следующее:
— эта самая строка в ходе парсинга и разбора не должна меняться — следовательно она константа
— использований метода типа fromMisc(«смотри, ма, я временный объект») не будет, так как это не имеет смысла (все таки кто из головы в коде будет придумывать DOMString?)
На мой взгляд нормальной реализацией тут было бы просто написать обертку над const char * и запретить вообще любое копирование и перемещение (=delete). Использовать const DOMString& и проследить чтобы время жизни объекта совпадало бы с вызовом функции парсинга. Если уж хочется сохранять какие то куски строк в токенах как делает автор, то можно оставить возможность отдавать константные слайсы этого DOMString (без выделения новой памяти).
Если юз-кейс отличается от описанного выше — легче использовать std::string0xd34df00d
01.10.2018 20:33Если вам так хочется следить за лайфтаймами, то правильным решением будет взять
std::string_view
. Там и слайсы, и никакого копирования, и очень дешёвый объект, можно по значению тоже передавать туда-сюда.
MacIn
30.09.2018 18:57+3Ох, и накинулись на человека — и это не то и то им не так. Ну, реализовал он малую часть, показывает что есть. Сделает рендеринг — покажет и его. Зачем пинать-то? Посмотрит на ваше злословие и забросит еще.
UnknownUser
30.09.2018 19:41+3По моему ещё не накинулись. Не увидел ни одного неадекватного комментария с критикой.
Просто, действительно выглядит пока так что автор замахнулся на задачу, для которой ещё не созрел. Однако, в любом случае это будет отличным опытом, и накидываться не нужно — так никто этого и не делает.dom1n1k
30.09.2018 21:53+5Да, есть отчетливое ощущение, что автор на самом деле не понимает, во что на самом деле ввязался и на что претендует.
0xd34df00d
01.10.2018 05:07Вы код-то смотрели?
vagran
01.10.2018 20:17Для 13 лет сойдёт. Я видал людей, которые в 30 лет не лучше пишут. И, кстати, если он сам рисовал оформление для своего сайта, то я считаю, у него есть способности к дизайну.
srhbdv
01.10.2018 20:26И, кстати, если он сам рисовал оформление для своего сайта, то я считаю, у него есть способности к дизайну.
Это ucoz.
rPman
30.09.2018 19:17+1У меня только один вопрос, ограниченность функционала позволит веб-приложениям (с оглядкой на ограниченную совместимость) работать заметно быстрее и требовать меньше ресурсов, хотя ты в разы?
Если да, то пилите! это годное дело.
Точно помню, старый движок opera работал на eeepc900 вполне сносно, когда как то же веб-приложение на последнем firefox (буквально в этом году проверял, жаль железка сломалась) тормозило безбожно.
Между прочим, такой проект был бы оправдан как замена тяжелому electron, а то что ни проект так таскают с собой 60мб хромиум (в установщике) и 30-50 мб оперативки минимум на одно окно приложения и мегааппетиты на просто ui.
p.s. постарайтесь ограничивать функционал там где это оправдано именно для скорости работы движка, если что, популярные фреймворки javascript для веб можно в будущем допилить до поддержки нового движка…
Safort
30.09.2018 19:54Автор, вы смотрели на Servo перед началом разработки? Это как раз новый движок и у него уже много чего реализовано.
FlightBlaze Автор
30.09.2018 19:55Я разве про Servo что-то говорил?
Safort
30.09.2018 20:18Нет. Но смысл же вашего движка в отсутствии легаси с 90х и, возможно, новых подходов к разработке? С этой точки зрения Servo кажется отличным вариантом.
dagen
30.09.2018 20:44+1Скорее смысл его движка — в самообучении. Если верить тому, что автор пишет в комментариях к PR, то он в седьмом классе. Согласитесь, что текущие начинания и достижения (хотя бы в знаниях языка) уже чрезвычайно офигительные для седьмого класса?
Да, с вероятностью 99% этот проект будет заброшен, но свою задачу он выполнит. К окончанию школы у человека будет нехилый фундамент прикладного программирования.0xd34df00d
01.10.2018 05:10А, ну это респект тогда ваще. Я в том возрасте только на самодельные CMS замахивался (на плюсах, ага) :(
popov654
30.09.2018 20:01+1О, я тоже пытался писать свой движок в начале этого года. Сделал HTML и CSS парсер, построение DOM, JS интерпретатор и частично рендер. Реализовывал всё на Java + Swing. В какой-то момент понял, что если реализовывать грамотно работу z-index — всё будет работать очень медленно, и забросил это дело…
FlightBlaze Автор
30.09.2018 20:08-1Чтобы все работало быстро, надо писать на высоко производительном языке, например на C++ или Rust. Java в этом плане очень сильно отстает. Для работы z-index нужно, чтобы каждый элемент рендерился на своём слое, а затем сравнивая z-index каждого слоя, сортировать их и вывести на экран.
popov654
30.09.2018 20:30Это всё понятно. Там проблема немного в другом)
Дело в том, что я изначально поставил задачу написать браузер, который будет корректно работать под Windows XP и выводить красивый, резкий текст. К сожалению, опыт показал, что при использовании Swing сделать это можно только используя «нативные» JLabel, но никак не низкоуровневыми методами вывода текста на графический контекст типа drawString. Однако такой подход не позволял отсекать содержимое при overflow: hidden: панели-слои у меня были неограниченного размера, и включение лейблов в эти панели никак не позволяло их обрезать. Тогда я применил комбинированный подход, выводя текст в менее чётком варианте только тогда, когда его реально нужно обрезать (при overflow равном scroll или hidden). Но проблема в том, что при наличии множества контекстов наложения с разными z-index при изменении практически любого z-index у элемента внутри одного из контекстов придётся всё перерисовать, применив новый порядок наложения.
У меня возникли какие-то проблемы, и я не смог заставить работать штатный механизм z-order в Swing (фрагменты текста-то у меня через JLabel сделаны!) иначе как в момент добавления элемента в контейнер. А при каждой смене z-index элемента удалять и по новой добавлять всё — безумно дорогая операция. Так что увы…Durimar123
01.10.2018 18:42Обычно есть расширенный метод вывода графики (включая текст) где есть параметр для отсечения, т.е. передаешь координаты прямоугольника внутри которого все рисуется, а то что выходит за этот прямоугольник, будет пропускаться.
dagen
30.09.2018 21:00Для работы z-index нужно, чтобы каждый элемент рендерился на своём слое
О, если бы всё было так просто. Объединение в слои как раз и придумали затем, чтобы не создавать на каждый чих отдельного слоя. Почитайте раздел «Краткая история отрисовки и компоновки» в статье habr.com/post/340176. Кроме хорошего объяснения в статье есть хорошие узнаваемые картинки от Лин Кларк :)
mspain
02.10.2018 07:24>производительном языке C++ или Rust
>Java в этом плане очень сильно отстает
Вот так откровения. Вообще говоря расклад по скорости такой: 1. плюсы 2. жабка 3. раст.
Речь не про микробенчмарки, а большие проекты. Хотя какие большие проекты у раста? Сферический тузик в вакууме, всех порвал… в теории.MikailBag
02.10.2018 13:32Java быстрее раста? какие-нибудь ссылки можно?
mspain
02.10.2018 18:19-1Выборочно читаете?
«Хотя какие большие проекты у раста?»
Не согласны? Ну давайте вы ссылки на аналоги Cassandra, Neo4j, Lucene, JBOSS и тд
Когда такое появится, тогда и можно будет говорить про скорость не в микробенчмарках.
В целом, уверен, что аналог более-менее грамотно написанного софта, писанного под JBOSS, на Расте будет из костылей, велосипедов, г и палок. С соответствующей производительностью.MikailBag
02.10.2018 18:231) Servo сойдет?
2) Я понял вашу точку зрения. Но в таком случае производительность раста и джавы не сравнимы вообще, и любой их порядок, в т.ч. ваш, некорректен.mspain
03.10.2018 05:20>Но в таком случае производительность раста и джавы не сравнимы вообще
Неубедительно вчера написал. Вообще говоря, представление о низкой скорости раста у меня сложилось глядя на масштабные бенчмарки с несколькими языками. По тестам выходит что раст телепается где-то на уровне go и сильно отстаёт даже от плюсов, не говоря о анси си. Жабка, как известно, из «второсортных языков» таки самая быстрая. Повторяюсь, речь не про микробенчмарки, а более-менее большие проекты.
Foror
03.10.2018 13:00>Java быстрее раста? какие-нибудь ссылки можно?
Гуглить GraalVM nativeimage. Не быстрее ассемблера, конечно ) Но при грамотном подходе не медленнее Си и гораздо удобнее в разработке и поддержке.
bask
30.09.2018 20:10+1Он учитывает любую вашу ошибку.
Например, вы забыли поставить кавычки, набирая атрибут
Движок вас поймет, есть значение атрибута написано без пробелов
Вы можете не закрывать тег, когда это не обязательно
История ничему не учит? Опять на те же грабли наступать?
Хотите повторить судьбу IE?Merkat0r
01.10.2018 05:16Да блин… что IE не так?) Он то, как раз единственный работал _СТРОГО_ по спекам, не любили его совсем за другие вещи и только потом это просто стало тупо модным. Ну из серии — *а за что? потомушто.* :)
Durimar123
01.10.2018 18:48IE работал как ему хотелось, и пока он занимал 80%+ рынка, все бегали за микрософтом и уговаривали дать стандартны по которым они рендерят. А микрософт хрен на всех забил.
Но потом он потерял рынок и вот только после этого начал стандарты поддерживать.
arielf
30.09.2018 20:21Вы можете не закрывать тег, когда это не обязательно
Неужели вы стимулируете криворуких макак? Есть прекрасный XHTML 5 — фичи HTML и строгость и расширяемость XML! Чего народ так не любит XHTML? Появление XHTML 1.0 я воспринял как праздник! А массы не взлюбили, теги им закрывать лень!rPman
30.09.2018 20:30Попробую объяснить, почему я считаю что строгий xml не нужен.
Все как то забыли, почему создавались такие языки разметки как xml — чтобы быть human readable, это первопричина, а так как используют html в основном люди (как разработчики) так и смотерть нужно на их потребности и удобство… Если не закрывать теги не проблема для парсера — то почему нет? это ведь удобно!
p.s. если вам нужна строгость, то я за реализацию бинарного стандарта, в который будет проводиться компиляция на этапе деплоя веб-приложения на сервер… как минимум это будет эффективнее работать на уровне веб-браузеров, особено если стандарт будет максимально строгий, и лишен исторических наслоений.
sumanai
01.10.2018 13:57Есть прекрасный XHTML 5
Нету, его закопали сами разработчики стандартов и призвали всех писать на HTML 5.vintage
01.10.2018 18:43Можно пруфлинк?
srhbdv
01.10.2018 20:07XHTML 2.0 является последней версией XHTMLandreymal
01.10.2018 20:53Тем не менее даже в последней спецификации 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".
amaksr
30.09.2018 20:50Автор молодец, плюсую. Каждый программист должен в жизни попробовать написать ОС, браузер, или, на худой конец, язык программирования. Всегда найдутся те, кто скажет что это уже все написано и никому не надо, но не надо позволять им себя останавливать.
А нюансы парсинга кавычек можно всегда подправить, это мелочи.amarao
30.09.2018 23:20+1Язык программирования из всего этого — проще всего. Почему? Потому что:
* ОС — прослойка между железом и юзерспейсом. Юзерспейс можно придумать любой, а вот железо — ой. Делай что есть в реальном мире.
* Браузеры — надо следовать стандартам. Огромным.
В языке программирования же всё предельно просто — как придумаешь, так и будет. Так что для «попробовать свои силы» — язык программирования самый подъёмный. На выходе будет что-то, что будет работать. Удобно или нет — вопрос открытый.
yurisv3
01.10.2018 08:45+1Каждый программист должен в жизни попробовать написать ОС, браузер, или, на худой конец, язык программирования.
При этом — насколько он хорош как программист, определяется пониманием момента, когда надо остановиться. Тут как в фотографии — передержка гибельна.amaksr
01.10.2018 20:50Линус выкатил свой прототип в возрасте 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 :-(.yurisv3
02.10.2018 06:37Ваша фамилия есть в коде ядра Linux? (моя есть)
И да, в свое время я действительно сделал собственный парсер HTML (с обсчетом геометрии), очень даже работающий. Именно полученный опыт помог принять правильное решение на этапе обдумывания рендера и DOM.
dom1n1k
02.10.2018 09:39А что комментаторы? Если бы у топик-стартера внезапно обнаружился бы качественный код и работающий прототип, думаете реакция не была бы другой?
Кроме того, крайне важен фактор исторического момента. Открыть что-то новое в математике триста лет назад было несравнимо проще, чем сейчас. И браузер с осью 25 лет назад были гораздо проще нынешних (хотя конечно всё равно сложны).amaksr
02.10.2018 16:07Сомневаюсь, что у студента Линуса в 22 года был сильно качественный код.
Насчет сложности — в 1991 году все еще сидели под однозадачным ДОС. Даже Windows 3.1 еще не появился. Не было еще виртуалок и эмуляторов. Линус тогда замахнулся на архисложную по тем временам задачу. Но он правда выкатил Линукс с уже работающим башем и gcc. Может поэтому и взлетело.babylon
02.10.2018 17:30Она и по этим временам архисложная
khim
02.10.2018 21:58Как раз сейчас — это задача архисложная. В те времена — всё гораздо проще было. Для того, чтобы на современной системе показать одну букву на экране нужно больше кода, чем всё ядро Linux первой версии содержало. Хорошо если не больше, чем весь тогдашний дистрибутив со всеми библиотеками, GCC и прочим…
Вот если взять современные инструменты и писать под эмуляцию тогдашнего железа (используя QEMU, например) — вот тогда эта задача будет простой…sumanai
02.10.2018 23:15А что мешает сейчас писать под режим виртуального 8086, кроме того, что это нафиг никому не нужно?
khim
02.10.2018 23:32То что в этот режим нужно ещё как-то умудриться попасть. А для этого вы должны предоставить, прости господи, «relocatable PE executable file» — да ещё и подписанный на некоторых системах. А потом ваш бинарник доложен будет как-то выяснить — где и какое железо живёт. Фиксированные порты и IRQ остались в далёком прошлом, нынче у нас на PC сплошной PnP, что упрощает жизнь пользователям — но существенно усложняет жизнь разработчикам.
А если вы не про PC, то а про какую нибудь ARM-железку типа Raspberri Pi, то там процессор вообще запускается операционкой для GPU! От которой ни документации, ни исходников нету!
khim
02.10.2018 21:55Может поэтому и взлетело.
Ровно потому и взлетело. Весь userspace у него уже был — его задачей было переписать только ядро.
Тоже та ешё задачка для студента, но… в человеко-год он уложился. Тут же делается попытка переписать что-то, что в базовом варианте никому не нужно (и, собственно, пишется куда быстрее, чем за год), а небазовом — требует очень много человеко-лет (потому что нет такого «удобного» деления на части — UNIX состоял из отдельных относительно небольших частей, а вот современный браузер — это монстр, где в одном бинарнике засунуты сотни компонент)
maydjin
30.09.2018 21:10Что действительно кажется интересным, так это эксперименты с sax вместо dom. Или, например — использованием собственного файла подкачки, с возможностью ограничить потребление памяти(вполне реализуемо на всех основных платформах).
Ибо на данный момент, самое узкое место в браузерах — это всё же память, которая потребляется немыслимыми объёмами.
Лично я бы смирился даже с определёнными лагами при загрузке и исполнении js, в пользу браузера который жил бы в одном гигабайте памяти, а не в 6-8, как лидеры рынка.
dagen
30.09.2018 21:32… так это эксперименты с sax вместо dom
В текущих реалиях это равносильно отключению JS: множество сайтов перестанет нормально работать. Вы этого можете достичь и обычным отключением JS. Впрочем не уверен, что все браузеры при этом будут жрать меньше памяти)maydjin
30.09.2018 21:36Я плаваю в вопросе, но со стороны, кажется, что, можно держать в памяти только "горячие" участки dom, а остальное можно держать в подкачке. Разница с системными механизмами подкачки должна оказаться вполне значительной, особенно, учитывая распространённость ssd.
maydjin
30.09.2018 21:42Если ещё пофантазировать — страницы могли бы содержать заголовок манифеста, с профилем обращений к dom, для браузеров, которые такое поддерживают.
dbagaev
30.09.2018 22:41+1Вы студет или работаете программистом пару лет, я угадал?
Я заглянул в репозиторий на github и в несколько кликов попал на код класса DOMStringMap. Вы в статье пеняете на различные типы умных указателей, но в вашем коде реализуете map обычным массивом, и вместо логарифмической сложности ищете ключ линейно. Более того, вы итерируете вектор по обычному индексу, хотя итератор позволяет не производить лишних операций вычисления адреса. Оверхед неправильного выбора часто используемого алгоритма будет на порядки выше оверхеда умных указателей, не котороя уже о том, что использование обычных указателей в сложном коде легко приводит к нестабильности кода. И в других местах вы делаете огромное количество ошибок С++, которые влияют либо на скорость, либо на простоту/расширяемость/поддерживаемость, либо на надежность кода.dagen
01.10.2018 16:20Не угадали, ему ~14 лет (если его комментарии к PR верны).
rpiontik
01.10.2018 16:47Ну, если 14 то можно только гордиться тем, что у нас такие парни есть!
dbagaev
02.10.2018 00:38Целиком согласен — браться за проект такого размера и добиваться хоть какого результата в 14 лет — это уже само по себе большой результат. Остается только пожелать автору всяческих удач и творческих успехов :-)
Keyten
30.09.2018 23:06+2Сложность в том, что в браузерных движках не просто рендеринг, но рендеринг быстрый и эффективный. Деление на слои, всякие reflow и так далее. Огромные кучи разных хаков. А тут ещё и недавно статья была про занятный файлик в хроме :)
DjSapsan
30.09.2018 23:56Недавно была статья о фиксах хрома под конкретное железо. Для одного человека сделать такое невозможно. Как ваш браузер будет работать с багами железа и драйверов?
DaylightIsBurning
01.10.2018 00:08есть очень много типов умных указателей
и ссылка на описание двух типов и одного вспомогательного класса. Это насторожило. Но когда я дочитал до момента, что деструкторов нет, а сборщик мусора планируется писать «потом», то даже как-то любопытно стало. Ну хорошо, хочется GC(и скорости), но зачем тогда C++? Ведь деструкторы считаются самым главным преимуществом C++ над C.
qrck13
01.10.2018 00:31С чего вы собственно решили, что умные указатели — это причина всех бед и «тормозов» того же WebKit-а?
Если говорить об умных указателях из C++ стандарта (webKit исторически использует свои, видимо, но суть дела это не меняет), то отверхеда от использования умных указателей — собственно почти нет. unique_ptr так вообще, в памяти даже занимает ровно столько же, сколько и обычный сырой указатель. shared_ptr — в памяти чуть больше, но в плане производительности «дороговатая» там только операция копирования, т.е. нужно учитывать возможность мультитрединга, а разыменование — копеечная операция, не отличающаяся от доступа к сырому указателю. Чуть дороже всякие операции блокировки weak_ptr-ов, но опять же не принципиально.
И чем вы собственно собираетесь заменить умные указатели? Очень сомневаюсь что работая с сырыми указателями вы сможете избежать многочисленных падений и утечек памяти.biseptol
01.10.2018 02:59Просто использовать raw pointers, и аккуратно следить за new/delete по коду, делов-то
/s
ankh1989
01.10.2018 00:35Штука интересная и даже если не получится, это всё равно будет серьёзным пунктом в резюме. Парсеры это как раз самое простое. Даже движок JS штука не самая сложная в браузере. Самое сложное это, имхо, поддержка разных платформ: недавняя статья про то как Chromium обходит баги в кривых видеокартах — хороший тому пример.
rekzi
01.10.2018 01:10Так вроде в стандарте html 5 есть подробный раздел о парсинге и построении дерева. Что-то вроде инструкции — https://www.w3.org/TR/html52/syntax.html#parsing-html-documents. Зачем что-то изобретать? А лояльность к ошибкам дописывать в процессе тестирования.
achekalin
01.10.2018 01:22Идеология Newtoo — показать страницу быстрее, чем остальные.
Это выглядит не как идеология, а как цель. Будем надеяться, что это единственная «путанница в головах», и проект даст даст выхлоп!
rpiontik
01.10.2018 08:33Как работа для прокачки кругозора — найс. Но не стоит надеяться на успех мероприятия. Парсер это самое простое. Но и там горизонта пока не видно. JavaScript двигло, если и там ты будешь свой велик делать, отнимет огромное количество времени. Рендер,… сдается мне, что еще больше. Тем более поддержка WebGL и анамаций. За это время твой проект устареет. Но даже это не все. Б — БЕЗОПАСНОСТЬ.
Браузер давно перешагнул себя как приложение. Он стал скорее ОС. Не зря появился такой проект как Chrome OS. А интеграция браузеров с сервисами вендеров стала ключевой в их выборе. Например, WebPUSH, маркеты.
В общем, для познания мира изнутри, проект ценен для личного развития. Но я бы рекомендовал фокус сузить. Это позволит достигнуть действительно ценного результата за вменяемый срок.saluev
01.10.2018 11:31+2Я несколько в шоке от количества плюсов к этой статье. Неужели никто не дочитывает до момента «реализован только парсинг»?
rpiontik
01.10.2018 11:41Многие воспринимают парсер (написать интерпретатор) как нечто магическое. Хотя, по сути, это достаточно просто для заданной спецификации. Гораздо сложнее сделать его быстрым, надежным и компактным. И уж действительно сложно создать новый синтаксис для решения задач выбранного профиля. Но, конечно, по себе помню, когда написал свой первый интерпретатор, считаешь, что ты как минимум третий после Стиви и Билли. Да фик с ним с Билли, сразу после Стиви. И все же, практически любой толковый Сишник пишет свой первый интерпретатор. Т.ч. путь то верный, а опыт поднакопится ;)
Nikeware
01.10.2018 12:46Автор просто не осознает, насколько это объемно. Но для «прокачки» кругозора — да. Можно смело пожелать всяческих успехов (сам такой в молодости был :-)).
Хорошим примером того, как надолго может всё это дело растянутся, является sciter.com.
Там схожая ситуация: проект делается одним человеком. Стоит отдать должное — библиотека сделана очень хорошо. Подтверждение тому список клиентов. Цель проекта правда немного другая — GUI для десктоп-приложений на основе HTML вёрстки. Там и CSS, и собственный scripting есть, можно и собственный backend на С++ писать. Исходников забесплатно к сожалению нет, но зато есть бесплатная возможность использовать всё это дело в коммерческих проектах.
Да, и пишется всё это уже много много лет.
XanderBass
01.10.2018 09:30В отличии от других движков
Не стоит вносить некие «features», которые ещё не одобрены окончательно W3C. Не начинайте очередную войну браузеров. Единственное, чем должен отличаться Ваш движок, уважаемый Автор — это корректной поддержкой всего, что уже есть в стандартах W3C, и скоростью работы (в лучшую сторону относительно других браузеров).andreymal
01.10.2018 11:21Не всё так просто, следование стандартам W3C будет означать нарушение совместимости со всеми современными браузерами, например https://habr.com/post/353514/
А ещё говорят, что реализовать всё по стандартам эффективно просто невозможно. Настолько невозможно, что гугл переписывает спецификацию под свой хром
XanderBass
01.10.2018 13:08Вот и я том же. Не стоит вносить ещё больший вклад в общую энтропию. Реализуйте то, что совместимо с W3C и WHATWG, и не надо придумывать супер-мега-фичи, которые будет поддерживать только Ваш движок.
Trixon
01.10.2018 09:37-8Ребята, извините, немного оффтопа. Помогите, пожалуйста, с ответом на вопрос:
https://stackoverflow.com/questions/52568126/cookie-sharing-in-simultaniously-requests
Maria244
02.10.2018 00:18О, я тоже пытался писать свой движок в начале этого года. Сделал HTML и CSS парсер, построение DOM, JS интерпретатор и частично рендер. Реализовывал всё на Java + Swing. В какой-то момент понял, что если реализовывать грамотно работу z-index — всё будет работать очень медленно, и забросил это дело…
gunayd?n mesajlar?
prefrontalCortex
02.10.2018 11:51Так уж получилось, что в мире есть всего 4 популярных браузерных движка
А какие ещё два?..
firedragon
Круто. Браузер для ReactOS?
perfect_genius
Лучше бы для KolibriOS.
x86corez
Насчёт браузера не знаю, но в качестве MSHTML движка было бы интересно увидеть. :)