-
Notifications
You must be signed in to change notification settings - Fork 10
index.html from Barabash #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
max-barabash
wants to merge
3
commits into
mvv1981:master
Choose a base branch
from
max-barabash:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,244 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="ru"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <title>Право.ru: Блог от Барабаша Масима Сергеевича</title> | ||
| </head> | ||
| <body style = "background-color: beige"> | ||
| <h1>Блог компании Pravo.ru</h1> | ||
| <h2>КАК МЫ ИЗМЕРЯЕМ СКОРОСТЬ ЗАГРУЗКИ И УЛУЧШАЕМ ЕЁ</h2> | ||
| <p> | ||
| Если ваш сайт медленно грузится, вы рискуете тем, что люди не оценят ни то,<br> | ||
| какой он красивый, ни то, какой он удобный. Никому не понравится, когда все<br> | ||
| тормозит. Мы регулярно добавляем в Doc.One новую функциональность,<br> | ||
| иногда — исправляем ошибки, а это значит, у нас постоянно появляются новый код<br> | ||
| и новая логика. Всё это напрямую влияет на скорость работы интерфейса. | ||
| <p> | ||
| <h3>Что мы измеряем</h3> | ||
| <ul> | ||
| <lh>Этапы первой загрузки:</lh> | ||
| <li>подготовка;</li> | ||
| <li>загрузка статики (HTTP-запрос и парсинг);</li> | ||
| <li>исполнение модулей;</li> | ||
| <li>инициализация базовых объектов;</li> | ||
| <li>отрисовка.</li> | ||
| </ul> | ||
| <ul> | ||
| <lh>Этапы отрисовки любой страницы:</lh> | ||
| <li>подготовка к запросу на сервер;</li> | ||
| <li>запрос данных с сервера;</li> | ||
| <li>шаблонизация;</li> | ||
| <li>обновление DOM.</li> | ||
| </ul> | ||
| <div style = "background-color: bisque ; display: inline-block; padding: 10px; border-radius: 20px"> | ||
| <p> | ||
| <q>—Ок, теперь у нас есть метрики, мы можем отправить их на сервер</q> - говорим мы | ||
| </p> | ||
| <p> | ||
| <q>—Что же дальше?</q> - вопрошаете вы | ||
| </p> | ||
| <p> | ||
| <q>—А давай построим график!</q> - отвечаем мы | ||
| </p> | ||
| <p> | ||
| <q>—А что будем считать?</q> - уточняете вы | ||
| </p> | ||
| </div> | ||
| <p> | ||
| Как вы знаете, <strong>медиана</strong> – это серединное, а не среднее значение в выборке.<br> | ||
| Если у нас имеются числа 1, 2, 2, 3, 8, 10, 20, то медиана – 3, а среднее – 6,5.<br> | ||
| В общем случае медиана отлично показывает, сколько грузится средний пользователь. | ||
| </p> | ||
| <p> | ||
| В случае ускорения или замедления медиана, конечно, изменится. Но она не может<br> | ||
| рассказать, сколько пользователей ускорилось, а сколько замедлилось. | ||
| </p> | ||
| <p> | ||
| <strong>APDEX</strong> – метрика, которая сразу говорит: хорошо или плохо. Метрика<br> | ||
| работает очень просто. Мы выбираем временной интервал [0; t], такой, что если<br> | ||
| время показа страницы попало в него, то пользователь счастлив. Берем еще один<br> | ||
| интервал, (t; 4t] (в четыре раза больше первого), и считаем, что если страница<br> | ||
| показана за это время, то пользователь в целом удовлетворен скоростью работы,<br> | ||
| но уже не настолько счастлив. И применяем формулу: | ||
| </p> | ||
| <figure> | ||
| <img alt = "(кол-во счастливых пользователей + кол-во удовлетворенных / 2) / (кол-во всех)" src = "https://tex.s2cms.ru/svg/%5Ccfrac%7B%5Ctext%7B%D0%BA%D0%BE%D0%BB-%D0%B2%D0%BE%20%D1%81%D1%87%D0%B0%D1%81%D1%82%D0%BB%D0%B8%D0%B2%D1%8B%D1%85%20%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D0%B5%D0%B9%20%2B%20%D0%BA%D0%BE%D0%BB-%D0%B2%D0%BE%20%D1%83%D0%B4%D0%BE%D0%B2%D0%BB%D0%B5%D1%82%D0%B2%D0%BE%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D1%85%7D%7D%7B%0A%20%20%20%20%20%5Ccfrac%7B2%7D%7B%0A%20%20%20%20%20%20%5Ctext%7B%D0%BA%D0%BE%D0%BB-%D0%B2%D0%BE%20%D0%B2%D1%81%D0%B5%D1%85%7D%0A%20%20%20%20%20%7D%0A%20%20%20%20%7D"> | ||
| <figcaption><sub>Количество довольных пользователей</sub></figcaption> | ||
| </figure> | ||
| <p> | ||
| Получается значение от нуля до единицы, которое, видимо, лучше всего показывает,<br> | ||
| хорошо или плохо работает почта. | ||
| </p> | ||
| <h3> | ||
| Как мы измеряем | ||
| </h3> | ||
| <p> | ||
| Сейчас модуль обновления сам логирует все свои стадии, и можно легко понять<br> | ||
| причину замедления: медленнее стал отвечать сервер либо слишком долго<br> | ||
| выполняется JavaScript. Выглядит это примерно так: | ||
| </p> | ||
| <code> | ||
| this.timings['look-ma-im-start'] = Date.now(); <br> | ||
| this.timings['look-ma-finish'] = Date.now(); | ||
| </code> | ||
| <p> | ||
| C помощью <code>Date.now()</code>> мы получаем текущее время. Все тайминги собираются и при<br> | ||
| отправке рас<wbr>счи<wbr>ты<wbr>ва<wbr>ют<wbr>ся. На этапах разница между <em>“end”</em> и <em>“start”</em> не считается,<br> | ||
| а все вычисления производятся в конце: | ||
| </p> | ||
| <code>var totalTime = this.timings['look-ma-finish'] - this.timings['look-ma-im-start'];</code> | ||
| <p>И на сервер прилетают подобные записи:</p> | ||
| <code>serverResponse=50&domUpdate=60</code> | ||
| <h3>Как мы ускоряем</h3> | ||
| <p> | ||
| Чтобы снизить время загрузки почты при выходе новых версий,<br> | ||
| мы уже делаем следующее: | ||
| </p> | ||
| <ul> | ||
| <li>включаем gzip;</li> | ||
| <li>выставляем заголовки кэширования;</li> | ||
| <li>фризим CSS, JS, шаблоны и картинки;</li> | ||
| <li>используем CDN.</li> | ||
| </ul> | ||
| <p> | ||
| Мы подумали: <q>А что если хранить где-то старую версию файлов, а при выходе новой</q><br> | ||
| передавать только diff между ней и той, которая сохранена у пользователя?»<br> | ||
| В браузере же останется просто наложить патч на клиенте. | ||
| </p> | ||
| <p> | ||
| На самое деле эта идея не нова. Уже существуют стандарты для HTTP — например,<br> | ||
| RFC 3229 «Delta encoding in HTTP» и «Google SDHC», — но по разным причинам они<br> | ||
| не получили должного распространения в браузерах и на серверах. | ||
| </p> | ||
| <p> | ||
| Мы же решили сделать свой аналог на JS. Чтобы реализовать этот метод обновления,<br> | ||
| начали искать реализации diff на JS. На популярных хостингах кода нашли<br> | ||
| библиотеки: | ||
| </p> | ||
| <ul> | ||
| <li>VCDiff</li> | ||
| <li>google-diff-patch-match</li> | ||
| </ul> | ||
| <p>Для окончательного выбора библиотеки нам нужно сравнить:</p> | ||
| <table> | ||
| <tr> | ||
| <td style = "border: 1px solid black;">Библиотека</td> | ||
| <td style = "border: 1px solid black;">IE9</td> | ||
| <td style = "border: 1px solid black;">Opera 12</td> | ||
| </tr> | ||
| <tr> | ||
| <td style = "border: 1px solid black;">vcdiff</td> | ||
| <td style = "border: 1px solid black;">8</td> | ||
| <td style = "border: 1px solid black;">5</td> | ||
| </tr> | ||
| <tr> | ||
| <td style = "border: 1px solid black;">google diff</td> | ||
| <td style = "border: 1px solid black;">1363</td> | ||
| <td style = "border: 1px solid black;">76</td> | ||
| </tr> | ||
| </table> | ||
| <p> | ||
| После того как мы определились с библиотекой для диффа, нужно определиться с тем,<br> | ||
| где и как хранить статику на клиенте. | ||
| </p> | ||
| <p> | ||
| Формат файла с патчами для проекта выглядит так: | ||
| </p> | ||
| <code> | ||
| <pre> | ||
| [ | ||
| { | ||
| "k": "jane.css", | ||
| "p": [patch], | ||
| "s": 4554 | ||
| }, | ||
| { | ||
| "k": "jane.css", | ||
| "p": [patch], | ||
| "s": 4554 | ||
| } | ||
| ] | ||
| </pre> | ||
| </code> | ||
| <p> | ||
| То есть это обычный массив из объектов. Каждый объект — отдельный ресурс. У<br> | ||
| каждого объекта есть три свойства. k — названия ключа в localStorage для этого<br> | ||
| ресурса. p — патч для ресурса, который сгенерировал vcdiff. s — чексумма для<br> | ||
| ресурса актуальной версии, чтобы потом можно было проверить правильность<br> | ||
| наложения патча на клиенте. Чексумма вычисляется по алгоритму Флетчера.<br> | ||
| </p> | ||
| <p> | ||
| Алгоритм Бройдена — Флетчера — Гольдфарба — Шанно (<acronym>BFGS</acronym>)<br> | ||
| — итерационный метод численной оптимизации, предназначенный для<br> | ||
| нахождения локального максимума/минимума нелинейного функционала<br> | ||
| без ограничений. | ||
| </p> | ||
| <p>Почему именно алгоритм Флетчера, а не другие популярные алгоритмы вроде:</p> | ||
| <ul> | ||
| <li><strong>CRC16/32</strong> - алгоритм нахождения контрольной суммы, предназначенный для проверки<br> | ||
| целостности данных | ||
| </li> | ||
| <li><strong>md5</strong> - 128-битный алгоритм хеширования. Предназначен для создания «отпечатков»<br> | ||
| или дайджестов сообщения произвольной длины и последующей проверки<br> | ||
| их подлинности. | ||
| </li> | ||
| </ul> | ||
| <p> | ||
| Потому что он быстрый, компактный и легок в реализации. | ||
| </p> | ||
| <h3>Итог</h3> | ||
| <p>Фактически мы экономим 80-90% трафика. Размер загружаемой статитки в байтах:</p> | ||
| <table> | ||
| <tr> | ||
| <td style = "border: 1px solid black;">Релиз</td> | ||
| <td style = "border: 1px solid black;">С патчем</td> | ||
| <td style = "border: 1px solid black;">Без патча</td> | ||
| </tr> | ||
| <tr> | ||
| <td style = "border: 1px solid black;">7.7.20</td> | ||
| <td style = "border: 1px solid black;">397</td> | ||
| <td style = "border: 1px solid black;">174 549</td> | ||
| </tr> | ||
| <tr> | ||
| <td style = "border: 1px solid black;">7.7.21</td> | ||
| <td style = "border: 1px solid black;">383</td> | ||
| <td style = "border: 1px solid black;">53 995</td> | ||
| </tr> | ||
| <tr> | ||
| <td style = "border: 1px solid black;">7.7.22</td> | ||
| <td style = "border: 1px solid black;">483</td> | ||
| <td style = "border: 1px solid black;">3 995</td> | ||
| </tr> | ||
| </table> | ||
| <h1>Комментарии</h1> | ||
| <div> | ||
| <div style="background-color: antiquewhite"> | ||
| <strong><i>- Mogaika (mogaika@pravo.ru) 30 ноября 2014 в 17:05</i></strong> | ||
| <p> | ||
| А можете привести сравнение, на сколько быстрее грузится lite версия? | ||
| </p> | ||
| </div> | ||
| <div style="background-color: antiquewhite"> | ||
| <strong><i>- JIguse (mrawesome@pravo.ru) 29 ноября 2014 в 21:30</i></strong> | ||
| <p> | ||
| Спасибо за статью, познавательно. Здорово, что Pravo.ru делится некоторыми<br> | ||
| подробностями о внутренней работе сервисов. | ||
| </p> | ||
| </div> | ||
| <div style="background-color: antiquewhite"> | ||
| <strong><i>- Brister (brist89@pravo.ru) 24 ноября 2014 в 13:13</i></strong> | ||
| <p> | ||
| <blockquote>(кол-во счастливых пользователей + кол-во удовлетворенных / 2) / (кол-во всех).</blockquote> | ||
| Получается значение от нуля до единицы, которое, видимо, лучше всего показывает,<br> | ||
| хорошо или плохо работает почта. | ||
| </p> | ||
| </div> | ||
| </div> | ||
| <footer style = "background-color: darkgoldenrod; margin-top: 20px; padding: 10px "> | ||
| <strong>Автор:</strong> @doochik<br> | ||
| С++ разработик<br> | ||
| <strong>Электронная почта:</strong> <a href="mailto:doochik@pravo.ru">doochik@pravo.ru</a><br> | ||
| <strong>Компания:</strong> <a href="https://pravo.ru/">Pravo.ru</a><br> | ||
| </footer> | ||
| </body> | ||
| </html> | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
не существующий тег и это хак, что бы было как заголовок у списка?
или я не умею гуглить? )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Это тег из древней спецификации - HTML3, как я понял, но хром с ним дружит)))
https://www.w3.org/MarkUp/html3/listheader.html