- PVSM.RU - https://www.pvsm.ru -
Заняться этим проектом и написать эту статью вдохновил меня "молодой и шутливый человек который ускорял страницу с reactjs [2]". Если кто-то помнит нашумевшую в своей время статью от сайта pingdom.com, о том что "Страницы в интернете прилично обросли жиром [3]" их вывод складывался к тому, что раньше к весу страницы в основном добавляли изображения, теперь к этому "жиру" накинули и JavaScript. Страница шутливого молодого человека не дает особой практической пользы — больше разминка для его мозгов. Я же решил помочь своей девушке с продажей самого популярного продукта из ее ассортимента.
Я уже и раньше пытался делать крайне минималистичные сайты [4]. Такие проекты были вызваны желаниям выйти за рамки фреймворков и возможно закончить проект быстрее. Такой подход достаточно популярен и среди моих друзей [5] — популярность KISS (Keep It Simple, Stupid) дает свои плоды. Будучи в основном бэкенд программистом — я много времени провожу с оптимизацией кода на стороне сервера. На практике понял, как это важно не делать такие изменения вслепую, а подкреплять их метрикой.
Я не фронт-енд программист и поэтому мне приходится полагаться на фронт-енд фреймворки. Чаще всего это означает bootstrap со всем "его добром", и хотя bootstrap компоненты можно использовать селективно, это все равно означает что я притащу с собой как минимум jQuery. Я был не уверен что мне нужен jQuery, я видел уже достаточно native-javascript библиотек которые работают без Jquery. Размер бутстрапа и его компонент тоже меня не устраивал, мне всегда казалось что он "стилизует" чуть больше чем нужно.
Поэтому немного погуглив немного, я нашел фреймворки которые позиционируют себя как минималистычные. Вот примерный список того что я рассматривал
Я выбрал фрейворк base. Большинство из причин глубокого личные:
Поэтому я не буду рекомендовать только Base, а выдал список. Но я должен оговориться, что можно начать еще более минималистично, только с grid system — sussy grid, например.
Я не собирался делать динамический контент. И хоть казалось бы логичным сделать форму для покупки, большинство тайских магазинов что я видел избегали этого. Форма для покупки еще усложняется тем, что их бы пришлось интегрировать с банками, а в Тайланде нету четких лидеров в банковской сфере. Их больше 10 и все они более или менее пользуются спросом, даже среди моих друзей иностранцевтайцев выбор банка крайне разнится. Очень много покупок делается непосредственно через интернет банки и мессенджер line. Поэтому я решил не ломать привычных паттернов, тем более это крайне упрощает мою задачу.
Мне нужен
_ В комментариях отметили что мой географический выбор сервера не самый разумный для Тайского сайта. Так же, какой бы легковесный не был apache — он все равно создает новый поток для каждого соединения [13]. Пока я еще в Тайланде — замерю, задвину на сервер поближе и обновлю статью.
Я изначально договорился сам с собой, что я не буду полагаться на собственные "ощущения". А буду полагаться на общественно признанный инструментарий.
gtmetrix.com — Я выбрал как основной тул для измерения "скорости" моего сайта. Он в себя включал два самых популярных инструмента google page speed и yslow. Оказалось, что оригинальный page speed [14] все таки нашел чуть больше ошибок. Это привело меня к выводу, что полагаться на 100 процентный показатель в gtmetrix и схожие тулы — возможно не самая лучшая идея, это же скриптованая проверка на "самые популярные" ошибки. Вы всегда можете пойти дальше.
Самая простая оптимизация которую можно было сделать — это предоставлять статические файлы в gzip формате. Это я делал во всех проектах в которых я работал до этого. Поэтому крайне быстро набросал таск в gulpfile.js, чтобы автоматизировать процесс создания .gz файлов.
var gzip = require('gulp-gzip');
gulp.task('gzip', function (){
return gulp.src('./public//**/*.+(js|css|html)')
.pipe(gzip())
.pipe(gulp.dest('./public/'))
});
И так же быстро набросал .htaccess файл, который подсовывает браузеру архивированный файл.
Header add Vary accept-encoding
RewriteEngine on
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [L]
Мне так же пришлось копировать этот файл в билд папочку, без особых изменений. Это оказалось еще проще:
gulp.task('htaccess', function () {
return gulp.src('./src/**/.htaccess')
.pipe(gulp.dest('./public/'));
});
Так же, пришлось обновить и build таск
gulp.task('build', function() {
runSequence('clean', 'sass', 'build-img', 'jsmin', 'inlinesource', 'htaccess', 'gzip');
});
Помоему это самый простой способ оптимизировать страницу, только ленивый не делает это в своих проектах. Во многих современных движках это все доводится до банальщины — добавить плагин или включить опцию.
Менее тривиальной оказалась задача по указыванию заголовков для кэширования. С AWS эти уже автоматизировано. Я пытался вспомнить когда я это делал последний раз, но так и не вспомнил когда. Поэтому с помощью магической силы гугла, пару попыток я все-таки сделал что-то 100% приеемлемое для gtmetrix.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType text/javascript "access plus 2 month"
ExpiresByType application/javascript "access plus 2 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType image/icon "access plus 1 year"
ExpiresByType application/ico "access plus 12 month"
ExpiresDefault "access plus 2 days"
</IfModule>
Но чтобы избежать двух попыток, я бы рекомендовал воспользоваться темплейтом для сервера из проекта html5-boilerplate [15]. Я в следующий раз обязательно это сделаю :)
Для человека у которого нету Photoshop'a на компьютере — работа с изображениями это большая попаболь. Половина проблем с изображениеми было решено за меня за счет того что я выбрал готовый темплейт — мне не пришлось возиться с спрайтами, векторами. Но это не решило всех моих проблем — мне нужны были другие иконки и другие изображения.
Я сделал самую грубую ошибку из тех ошибок что можно сделать. Я выбрал .png как формат по умолчанию для изображений, у меня было представление что png оптимизирован для веба. На самом деле для изображений насыщенных цветами (как например фото) — jpeg все-таки остается лучшим форматом, я оставил png для иконок.
Больше ликбеза на эту тему можно найти на страницах гугла [16] (от людей которые понимают в этом больше чем я).
Как человек с инженерным образованием, я знаю цену специализированным инструментам. Они очень часто облегчают работу больше чем one-fits-all инструмент. Можно программировать на notepad'e, но чаще становится нашим основным рабочим инструментом — sublime text, rubymine. В данном случае imageoptim хорош, но не достаточно хорош. Так как у меня было много jpeg файлов, я нашел сравнительный анализ лослесс сжатий — выйграл jpegtran [17].
в gulp это оказалось очень просто:
var jpegtran = require('imagemin-jpegtran');
gulp.task('build-jpg', function () {
gulp.src('./src/img/*.+(jpg|jpeg)')
.pipe(jpegtran({ progressive: true })())
.pipe(gulp.dest('./public/img'));
});
Но выбором только правильного формата все не окончилось. Изображения все-равно были слишком большие. Мой hero background занимал больше половины мегабайта.
У меня нету photoshop'a, а что без него тут делать я не очень понимал. Но друзья подсобили и посоветовали отличный проект TinyJpg [18] — все оказалось слишком просто.
Я все таки решил заинлайнить css. Это немного контринтуитивно, люди советуют держать все это в отдельном файле чтобы стили могли закэшироваться. Есть даже вероятность, что у юзера уже закешировано все это, особенно если используешь популярный фрэймворк.
Я скорее так бы и сделал, если бы использовал bootstrap. Но так как я использовал менее распространеный base и не очень то ожидал что пользовали будут возвращаться на мой сайт — то я решил удалить лишний http запрос.
В gulp это оказалось как обычно проще всего:
<link rel="stylesheet" href="css/styles.css" inline>
Интересная и неожиданная ситуация для меня сложилось с Google Fonts, в темплейте было использовано два разных фонта. И вроде даже разумно оптимизированы:
Но gtmetrix продолжал ругаться на фонты — у них небыло cache headers. Я решил пойти по пути уже предложенному в статье на которую я ссылался в начале [2] и избавился от google fonts. во всех девайсах есть вполне приличные встроеные фонты. Поэтому я оставил вот такой вот набор:
font-family: "Helvetica Neue", "Calibri Light", Roboto, sans-serif;
Вот такой вот получился вебсайт — http://euphorbia.soihok.com/ [20]
А вот последнии метрики с gtmetrix — https://gtmetrix.com/reports/euphorbia.soihok.com/zhMn6OhU [1]
Как утверждают многие СЕОшники — быстрый сайт дает бонусы в гугле. Я если честно на это надеялся, но не проверял. Поэтому здесь мне метриками крыть не получится.
Я часто путешествую и периодический приходится работать с крайне сомнительным соединением — будь то мобильное соединение, отели или просто не развитый интернет где то в Азии. И меня сильно расстраивает что нету мобильных версий у сайтов, что сайты даже для десктопов не оптимизированы.
Я очень много фокусировался чтобы делать быстрый бэкенд, которому не нужно много ресурсов. Но я никогда не фокусировался сильно на фронт-енде, хотя бы потому что считал что 100% показатели иметь не возможно. Но это оказалось, хоть и не просто, но возможно. Более того, можно пойти дальше и ускорить более "требуемого минимума". Все эти принципы и опыт построения быстрых страниц универсальны и последующие сайты ускорять будет гораздо легче и быстрее! Об этом лишь надо начать думать, где-то там на подсознании! И ваши пользователи скажут вам спасибо и будут возвращаться.
Желаю быстрых сайтов всем нам!
* "самый быстрый сайт в Таиланде" — это мой "кричащий" заголовок, я не берусь это утверждать со 100% уверенностью. Но большинство сайтов что я видел в Тайланде — не самые быстрые.
Автор: lunaticman
Источник [21]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/front-e-nd/235916
Ссылки в тексте:
[1] Image: https://gtmetrix.com/reports/euphorbia.soihok.com/zhMn6OhU
[2] молодой и шутливый человек который ускорял страницу с reactjs: https://hackernoon.com/10-things-i-learned-making-the-fastest-site-in-the-world-18a0e1cdf4a7#.bpdgu76it
[3] Страницы в интернете прилично обросли жиром: http://royal.pingdom.com/2011/11/21/web-pages-getting-bloated-here-is-why/
[4] минималистичные сайты: http://www.howtodigitalnomad.com/
[5] моих друзей: https://ristrettogram.com/
[6] http://getbase.org: http://getbase.org
[7] http://getskeleton.com/: http://getskeleton.com/
[8] http://fluidable.com/: http://fluidable.com/
[9] http://purecss.io/: http://purecss.io/
[10] хостинг: https://www.reg.ru/?rlink=reflink-717
[11] ограничений по трафику: https://www.quora.com/What-are-bandwidth-and-traffic-limits-for-GitHub-pages/answer/Rachel-Berry-9
[12] nearlyfreespeech.net: http://nearlyfreespeech.net/
[13] он все равно создает новый поток для каждого соединения: https://stackoverflow.com/questions/5171639/creation-of-new-process-for-each-request-of-web-page
[14] оригинальный page speed: https://developers.google.com/speed/pagespeed/insights/
[15] html5-boilerplate: https://github.com/h5bp/server-configs-apache/blob/master/dist/.htaccess
[16] на страницах гугла: https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/image-optimization
[17] выйграл jpegtran: http://compression.ca/act/act-jpeg.html
[18] TinyJpg: http://tinyjpg.com
[19] WebFontLoader: https://github.com/typekit/webfontloader
[20] http://euphorbia.soihok.com/: http://euphorbia.soihok.com/
[21] Источник: https://habrahabr.ru/post/319542/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.