Криокамера  для  статикиАлексей  АндросовСтарший  разработчик  интерфейсовЯ.Субботник,  Киев,  27  апреля  2013  года
Обо  мне  aandrosov@yandex-­team.ru      @doochik●    По  образованию  –  специалист  по  защитеинформации●    6  лет  в  ...
Я.Почта  (mail.yandex.ru)●    Одностраничное  AJAX-­приложение  на  11  языках●    Отдельные  версии  для  мобильных  и  д...
Частые  релизы+ Проще  собирать+ Быстрее  протестировать+ Проще  откатывать  в  случае  проблем04
Частые  релизы:  проблемы− Каждый  релиз  инвалидириует  кеш  статики− У  пользователей  плохо  работает  браузерный  кеш−...
Мы  нашли  решение  –freeze
И  получили  хорошийрезультат07
Как  все  начиналось
Вставляем  скрипты  и  стили<link href="//mysite.lv/css/_style.css"/><script src="//mysite.lv/js/_script.js"/>Кеширования ...
Добавляем  кеширующиезаголовкиКешириуют  обычно  «навечно»  и  добавляют  версию  в  URL,  чтобыинвалидировать  статику<li...
Уносим  на  отдельный  домен  иCDN<link href="//yandex.st/prj/css/_style.css?ver=1.0.0"/><script src="//yandex.st/prj/js/_...
Версии  раскладываем  попапками  без  проблем  переключаемся  между  версиями<link href="//yandex.st/prj/1.0.0/_style.css"...
Грузим  картинки  в  CSS.page {background: url("i/bg.png")}Полный  путь  до  изображения  выглядит  так://yandex.st/prj/1....
Грузим  картинки  в  JS$(.insert).html(<img src="+ PRJ.STATIC + /i/ico.png"/>);Полный  путь  до  изображения  выглядит  та...
И  тут  мы  выпускаемновую  версию!
Теперь  ссылки  выглядят  так<link href="//yandex.st/prj/ 1.0.1 /_style.css"/><script src="//yandex.st/prj/ 1.0.1 /_script...
А  ведь  картинки  непоменялись!
Что  же  не  так?Нечестно  заставлять  пользователя  грузить  всюстатику,  если  поменялась  только  часть18
Чего  мы  хотим?Чтобы  файлы  перезагружались  пользователем,  когда  ониреально  изменились19
ВариантыМожно  управлять  версиями  самостоятельно+ Просто− Неудобно− Сложно  покрыть  все  файлы− Большая  вероятность  о...
ВариантыМожно  добавлять  к  урлу  ревизию  файла  из  VCS+ Не  надо  ничего  делать  руками− Сложно  реализовать− Сложно ...
Что  делаем  мыГрузим  файлы  не  по  урлу  с  версией,  а  по  урлу  с  хеш-­суммой.page {background: url("//yandex.st/pr...
С  помощьюborschik  0.3.0+bit.ly/borschik23
Что  такое  borschik●    Это  текстовый  процессор  для  файлов  на  node.js●    Умеет  склеивать  файлы●    Умеет  преобр...
CSS
CSSborschik  умеет●    раскрыть  @import  и  собрать  всё  в  один  файл●    минимизировать●    freeze  картинок  и  шрифт...
Сначала  пишем  конфигКонфиг  –  файл  с  именем  .borschik{"paths": {"_freeze": "//yandex.st/prj/_freeze"},"freeze_paths"...
Берем  CSS.class {background: url("1.png");}01.02.03.28
Запускаем$ borschik --input 1.css --freeze yes --minimize no01.29
Все  готово!.class {background: url("_freeze/jUK5O9GsS2gPWOhRMeBxR0GThf0.png");}01.02.03.30
JS
Тут  немного  сложнее●    Вставлять  картинку  можно  бесконечно  разными  способами●    Урл  может  быть  динамическим32
Наше  решениеМы  написали  технологию  для  borschik  для  фриза  картинок  в  JSпо  аналогии  с  CSSВам  надо  всего  лиш...
JS:  статический  урл  докартинкиnew Image().src = borschik.link(1.png)$ borschik --tech js-link --input 1.jsnew Image().s...
JS:  статический  урл  докартинкиborschik.link  при  разработке  выглядит  вот  такborschik.link = function(link) {return ...
JS:  динамический  урл  докартинкиnew Image().src = borschik.link(@icon- + name + -png);Тут  ничего  не  меняется,  а  пра...
JS:  динамический  урл  докартинкиОбъявляем  JSON  с  entity:{"icon-test-png": "1.png"}$ borschik --tech json-links --inpu...
JS:  динамический  урл  докартинкиvar links = {};borschik.addLinks = function(json) {for (var link in json) {links[link] =...
JS:  динамический  урл  докартинкиborschik.link = function(link) {if (link.charAt(0) === @) {return links[link.substr(1)];...
JS:  динамический  урл  докартинкиСобираем  всё  вместе…boschik.addLinks(/* borschik:include:_images.json */);new Image()....
JS:  динамический  урл  докартинки…  и  всё  работает!boschik.addLinks({"icon-test-png":"_freeze/jUK5O9GsS2gOhRMeBxR0GThf0...
А  теперь  зафризимсами  файлы!
borschik  и  тут  поможет$ borschik freeze --input path/to/dir --output freeze-info.json01.02.03.43
После  запуска  получаем  JSON$ borschik freeze --input js{"js/index.js":"434046cd5d1b54ae2374868a7363d7d8.js","js/setup.j...
Как  это  выглядит  в  Я.Почте{"js/message.ru.js":"43...40.js""js/message.en.js":"46...cd.js""js/setup.ru.js":"5d...1b.js"...
Почему  мы  делаем  так?●    У  нас  модульная  динамическая  загрузка  и  подгрузка.  Урлыподменяются  на  лету.●    В  б...
А  у  меня  простоHTML-­страница,  и  яхочу  фриз!
Решение  для  ленивых$ borschik --tech html --input 1.htmlНа  статической  странице  зафризит:●    Картинки●    JS●    CSS...
Было<html><head><link rel="stylesheet" href="1.css"/></head><body><!-- <img src="1.png"> --><img src="1.png"><script src="...
Стало<html><head><link rel="stylesheet" href="//yandex.st/prj/_/n8mJAmyb...s2s6y0.css"/></head><body><!-- <img src="1.png"...
Важные  моменты●    В  каждый  файл  (JS/CSS)  стоит  добавить  описание,  иначе  потомне  понять  где  кто.  Например,/*!...
Измеряем  результат
Нам  помогут●    window.performance.timing  или  new  Date().Считаем  domContentLoad  и  onload.●    window.performance.we...
domready  меньше  на  15%54
Наши  цифры:  эффективностьфриза  платформы  (24  релиза)bootstrap.css 75%* 10Кбbootstrap.js 50% 16кбCSS 64% 320КбJS 22% 3...
Наши  цифры:  эффективностьфриза  платформы  (24  релиза)Суммарный  размер  новой  статики  (без  gzip)  –  727КбПосле  фр...
Наши  цифры:  эффективностьфриза  почты  (19  релизов)JS YateОбщее 18%  /  460Кб 27%  /  360КбАдресная  книга 73%  /  30Кб...
Наши  цифры:  эффективностьфриза  почты  (19  релизов)Суммарный  размер  новой  статики  (без  gzip)  –  1,6МбПосле  фриза...
Почему  это  касается  и  вас?●    Вне  зависимости  от  размера  статику  надо  загрузить●    Чем  чаще  пользователь  к ...
Что  вы  получите●    Уменьшите  нагрузку  на  статический  кластер●    Супер-­дешёвые  хотфиксы.Изменили  один  файл  -­ ...
Алексей  АндросовСтарший  разработчик  интерфейсов  aandrosov@yandex-­team.ru  @doochik  github.com/doochik
Upcoming SlideShare
Loading in …5
×

Алексей Андросов "Криокамера для статики"

1,153 views
1,089 views

Published on

Все знакомы с различными способами ускорения загрузки страницы. Эта тема уже давно исследована. Но в обычной ситуации при выпуске новой версии сайта у пользователя сбрасывается кеш, и ему приходится заново загружать все статические ресурсы, что увеличивает время загрузки страницы. Как сделать так, чтобы пользователь скачивал только действительно изменившиеся ресурсы? В докладе речь идет о простом, но мощном опенсорсном инструменте borschik (https://github.com/veged/borschik), который поможет ускорить загрузку в условиях постоянных релизов.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,153
On SlideShare
0
From Embeds
0
Number of Embeds
764
Actions
Shares
0
Downloads
4
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Алексей Андросов "Криокамера для статики"

  1. 1. Криокамера  для  статикиАлексей  АндросовСтарший  разработчик  интерфейсовЯ.Субботник,  Киев,  27  апреля  2013  года
  2. 2. Обо  мне  aandrosov@yandex-­team.ru    @doochik●    По  образованию  –  специалист  по  защитеинформации●    6  лет  в  Яндексе,  2  года  ведущий  разработчикфронтенда  в  Я.Почте●    Люблю  копаться  в  браузерах  и  внедрять  новые  фичи  из  HTML5●    Можете  спрашивать  про  JS,  CSS  и  frontend  в  целом02
  3. 3. Я.Почта  (mail.yandex.ru)●    Одностраничное  AJAX-­приложение  на  11  языках●    Отдельные  версии  для  мобильных  и  для  старых  браузеров●    Месячная  аудитория:  26  млн●    Общий  объем  загружаемой  статики  >1  Мб●    12  frontend  разработчиков●    2  релиза  в  неделю03
  4. 4. Частые  релизы+ Проще  собирать+ Быстрее  протестировать+ Проще  откатывать  в  случае  проблем04
  5. 5. Частые  релизы:  проблемы− Каждый  релиз  инвалидириует  кеш  статики− У  пользователей  плохо  работает  браузерный  кеш− Увеличивается  время  загрузки  почты05
  6. 6. Мы  нашли  решение  –freeze
  7. 7. И  получили  хорошийрезультат07
  8. 8. Как  все  начиналось
  9. 9. Вставляем  скрипты  и  стили<link href="//mysite.lv/css/_style.css"/><script src="//mysite.lv/js/_script.js"/>Кеширования  статики  еще  нет01.02.09
  10. 10. Добавляем  кеширующиезаголовкиКешириуют  обычно  «навечно»  и  добавляют  версию  в  URL,  чтобыинвалидировать  статику<link href="//mysite.lv/css/_style.css?ver=1.0.0"/><script src="//mysite.lv/js/_script.js?ver=1.0.0"/>01.02.10
  11. 11. Уносим  на  отдельный  домен  иCDN<link href="//yandex.st/prj/css/_style.css?ver=1.0.0"/><script src="//yandex.st/prj/js/_script.js?ver=1.0.0"/>01.02.11
  12. 12. Версии  раскладываем  попапками  без  проблем  переключаемся  между  версиями<link href="//yandex.st/prj/1.0.0/_style.css"/><script src="//yandex.st/prj/1.0.0/_script.js"/>01.02.12
  13. 13. Грузим  картинки  в  CSS.page {background: url("i/bg.png")}Полный  путь  до  изображения  выглядит  так://yandex.st/prj/1.0.0/i/bg.png01.02.03.01.13
  14. 14. Грузим  картинки  в  JS$(.insert).html(<img src="+ PRJ.STATIC + /i/ico.png"/>);Полный  путь  до  изображения  выглядит  так://yandex.st/prj/1.0.0/i/ico.png01.02.03.01.14
  15. 15. И  тут  мы  выпускаемновую  версию!
  16. 16. Теперь  ссылки  выглядят  так<link href="//yandex.st/prj/ 1.0.1 /_style.css"/><script src="//yandex.st/prj/ 1.0.1 /_script.js"></script>И  картинки  грузятся  по  другим  урлам//yandex.st/prj/ 1.0.1 /i/ico.png//yandex.st/prj/ 1.0.1 /i/bg.png01.02.01.02.16
  17. 17. А  ведь  картинки  непоменялись!
  18. 18. Что  же  не  так?Нечестно  заставлять  пользователя  грузить  всюстатику,  если  поменялась  только  часть18
  19. 19. Чего  мы  хотим?Чтобы  файлы  перезагружались  пользователем,  когда  ониреально  изменились19
  20. 20. ВариантыМожно  управлять  версиями  самостоятельно+ Просто− Неудобно− Сложно  покрыть  все  файлы− Большая  вероятность  ошибок20
  21. 21. ВариантыМожно  добавлять  к  урлу  ревизию  файла  из  VCS+ Не  надо  ничего  делать  руками− Сложно  реализовать− Сложно  покрыть  все  файлы21
  22. 22. Что  делаем  мыГрузим  файлы  не  по  урлу  с  версией,  а  по  урлу  с  хеш-­суммой.page {background: url("//yandex.st/prj/_/jUK5O9GsS2gPWOhR.png")}01.02.03.22
  23. 23. С  помощьюborschik  0.3.0+bit.ly/borschik23
  24. 24. Что  такое  borschik●    Это  текстовый  процессор  для  файлов  на  node.js●    Умеет  склеивать  файлы●    Умеет  преобразовывать  файлы●    Умеет  минимизировать  файлы●    Поддерживает  «из  коробки»  CSS  и  JS●    Можно  расширять  своими  «технологиями»24
  25. 25. CSS
  26. 26. CSSborschik  умеет●    раскрыть  @import  и  собрать  всё  в  один  файл●    минимизировать●    freeze  картинок  и  шрифтов26
  27. 27. Сначала  пишем  конфигКонфиг  –  файл  с  именем  .borschik{"paths": {"_freeze": "//yandex.st/prj/_freeze"},"freeze_paths": {".": "_freeze"}}01.02.03.04.05.06.07.08.27
  28. 28. Берем  CSS.class {background: url("1.png");}01.02.03.28
  29. 29. Запускаем$ borschik --input 1.css --freeze yes --minimize no01.29
  30. 30. Все  готово!.class {background: url("_freeze/jUK5O9GsS2gPWOhRMeBxR0GThf0.png");}01.02.03.30
  31. 31. JS
  32. 32. Тут  немного  сложнее●    Вставлять  картинку  можно  бесконечно  разными  способами●    Урл  может  быть  динамическим32
  33. 33. Наше  решениеМы  написали  технологию  для  borschik  для  фриза  картинок  в  JSпо  аналогии  с  CSSВам  надо  всего  лишь  несложно  разметить  картинки33
  34. 34. JS:  статический  урл  докартинкиnew Image().src = borschik.link(1.png)$ borschik --tech js-link --input 1.jsnew Image().src = "_freeze/jUK5O9GsS2gPWOhRMeBxRGThf0.png"01.01.01.34
  35. 35. JS:  статический  урл  докартинкиborschik.link  при  разработке  выглядит  вот  такborschik.link = function(link) {return link;}В  продакшене  можно  убрать01.02.03.35
  36. 36. JS:  динамический  урл  докартинкиnew Image().src = borschik.link(@icon- + name + -png);Тут  ничего  не  меняется,  а  правильный  урл  до  картинки  отдастborschik.entity01.36
  37. 37. JS:  динамический  урл  докартинкиОбъявляем  JSON  с  entity:{"icon-test-png": "1.png"}$ borschik --tech json-links --input images.json{"icon-test-png":"_freeze/jUK5O9GsS2gPWOhRMeBxR0GThf0.png"}01.01.01.37
  38. 38. JS:  динамический  урл  докартинкиvar links = {};borschik.addLinks = function(json) {for (var link in json) {links[link] = json[link];}};01.02.03.04.05.06.38
  39. 39. JS:  динамический  урл  докартинкиborschik.link = function(link) {if (link.charAt(0) === @) {return links[link.substr(1)];}return link;}01.02.03.04.05.06.39
  40. 40. JS:  динамический  урл  докартинкиСобираем  всё  вместе…boschik.addLinks(/* borschik:include:_images.json */);new Image().src = borschik.link(@icon- + name + -png);Собираем$ borschik --minimize no --input 1.js01.02.01.40
  41. 41. JS:  динамический  урл  докартинки…  и  всё  работает!boschik.addLinks({"icon-test-png":"_freeze/jUK5O9GsS2gOhRMeBxR0GThf0.png"});new Image().src = borschik.link(@icon- + name + -png);01.02.03.04.41
  42. 42. А  теперь  зафризимсами  файлы!
  43. 43. borschik  и  тут  поможет$ borschik freeze --input path/to/dir --output freeze-info.json01.02.03.43
  44. 44. После  запуска  получаем  JSON$ borschik freeze --input js{"js/index.js":"434046cd5d1b54ae2374868a7363d7d8.js","js/setup.js":"bcbf293578cfda2d4543d401d12e2e49.js"}Можно  отдать  в  конфиг  RequireJS,  например.01.01.02.03.04.44
  45. 45. Как  это  выглядит  в  Я.Почте{"js/message.ru.js":"43...40.js""js/message.en.js":"46...cd.js""js/setup.ru.js":"5d...1b.js""js/setup.en.js":"54...ae.js""css/blue.css":"23...74.js""css/green.css":"a7...d8.js"}01.02.03.04.05.06.07.08.45
  46. 46. Почему  мы  делаем  так?●    У  нас  модульная  динамическая  загрузка  и  подгрузка.  Урлыподменяются  на  лету.●    В  браузер  выгружаются  только  информация  для  нужной  парытема+язык.46
  47. 47. А  у  меня  простоHTML-­страница,  и  яхочу  фриз!
  48. 48. Решение  для  ленивых$ borschik --tech html --input 1.htmlНа  статической  странице  зафризит:●    Картинки●    JS●    CSS01.48
  49. 49. Было<html><head><link rel="stylesheet" href="1.css"/></head><body><!-- <img src="1.png"> --><img src="1.png"><script src="1.js"></script></body></html>01.02.03.04.05.06.07.08.09.10.49
  50. 50. Стало<html><head><link rel="stylesheet" href="//yandex.st/prj/_/n8mJAmyb...s2s6y0.css"/></head><body><!-- <img src="1.png"> --><img src="//yandex.st/prj/_/jUK5O9GsS2gPWOhRMeBxR0GThf0.png"><script src="//yandex.st/prj/_/1qHhHrD9m5i9sdDbCe590URPaBw.js"></script></body></html>01.02.03.04.05.06.07.08.09.10.50
  51. 51. Важные  моменты●    В  каждый  файл  (JS/CSS)  стоит  добавить  описание,  иначе  потомне  понять  где  кто.  Например,/*!mail:weather*/.class{...}"mail:setup";(function(){...})();●    Из  файлов  придется  убрать  всё,  что  содержит  текущую  версию.Иначе  файлы  каждый  раз  будут  разные.01.02.51
  52. 52. Измеряем  результат
  53. 53. Нам  помогут●    window.performance.timing  или  new  Date().Считаем  domContentLoad  и  onload.●    window.performance.webkitGetEntries  (Chrome  25+).Можно  считать  время  загрузки  отдельных  ресурсов.53
  54. 54. domready  меньше  на  15%54
  55. 55. Наши  цифры:  эффективностьфриза  платформы  (24  релиза)bootstrap.css 75%* 10Кбbootstrap.js 50% 16кбCSS 64% 320КбJS 22% 330КбYate-­шаблоны 50% 51Кб*  Доля  неизменившихся  файлов55
  56. 56. Наши  цифры:  эффективностьфриза  платформы  (24  релиза)Суммарный  размер  новой  статики  (без  gzip)  –  727КбПосле  фриза  (в  среднем)  –  400КбЭкономия  для  пользователя  –  45%56
  57. 57. Наши  цифры:  эффективностьфриза  почты  (19  релизов)JS YateОбщее 18%  /  460Кб 27%  /  360КбАдресная  книга 73%  /  30Кб 73%  /  50КбНаписание  письма 46%  /  120Кб 37%  /  60КбПросмотр  письма 64%  /  40Кб 64%  /  50КбНастройки 64%  /  35Кб 64%  /  150КбWYSWYG 100%  /  280Кб -­57
  58. 58. Наши  цифры:  эффективностьфриза  почты  (19  релизов)Суммарный  размер  новой  статики  (без  gzip)  –  1,6МбПосле  фриза  (в  среднем)  –  863КбЭкономия  для  пользователя  –  47%58
  59. 59. Почему  это  касается  и  вас?●    Вне  зависимости  от  размера  статику  надо  загрузить●    Чем  чаще  пользователь  к  вам  приходит,  тем  больше  он  качает●    Пользователи  не  будут  ждать  медленного  сайта– bit.ly/goog-­speed-­matters– bit.ly/msft-­goog-­slow-­page59
  60. 60. Что  вы  получите●    Уменьшите  нагрузку  на  статический  кластер●    Супер-­дешёвые  хотфиксы.Изменили  один  файл  -­  пользователи  выкачили  один  файл●    Дешёвые  релизы.Пользователи  выкачивают  то,  что  реально  изменилось●    Релиз  хоть  каждый  день!  60
  61. 61. Алексей  АндросовСтарший  разработчик  интерфейсов  aandrosov@yandex-­team.ru  @doochik  github.com/doochik

×