Склонен не доверять результатам данного теста, тесты какие-то слишком синтетические. Я ради эксперимента провел аналогичный сравнительный анализ на одном из последних своих проектов: два теста на двух сборках проекта — одна с картинками в файлах, другая с картинками в data:uri (в data:uri добавлялись только иконки, причем оптимизированные с помощью imageOptim, размер не более 2х кб на каждую). И результаты в FF (версии 21, 22) получились ровным счетом обратные, в сборке с data:uri событие window.onload срабатывало в среднем в 3-4 раза быстрее. Для чистоты эксперимента — в Сhrome и FF nightly 25.0a1 data:uri быстрее в 2 раза
Не стал вдаваться в поддробности по поводу тегов без псевдоэлементов, спасибо за дополнение.
А по поводу иконок — опять таки, если иконка прямо относится к тексту, то используйте img, если нет — все что угодно, но при этом по возможности семантично (лишние теги плодить не имеет смысла).
И, кстати, забыл упомянуть, что если верстка проекта нацелена на хорошие браузеры (IE9+) то есть еще возможность использовать множественные бэкграунды, для избавления от лишних тегов.
Если все ради того, чтобы ускорить набор кода, то я вам советую выбрать хороший редактор. Например: webstorm с плагином emmet, live templates и автоматической подстановкой (включая размеры картинок) по клавише tab
Если картинка несет смысловое значение (относится к тесту) то следует использовать отдельные файлы изображений, тэг img с аттрибутом alt.
Если же картинка играет роль иконки, бэкграунда и не несет смыслового значения, то лучше всего задавать ее в качестве background-image для нужного тега. (найдено на stackoverflow)
При этом очистить html-код от мусорных тегов, вроде предложенных вами <i class="some-image"></i> или предложенных в комментириях <span class="some-image"></span> помогут псевдоэлементы ::before и ::after коих целых 2 на каждый тег (за исключением input)
Генерация спрайтов — задача тривиальная и решенная уже много-много раз (полный список решений). Тем более, последнее время использование data:uri считается более лучшим, так как экономит память и количество запросов к серверу, и, в качестве бонуса, избавляет от головной боли слежения за версией спрайта (если сайт обновляется и с некоторой периодичностью в спрайт добавляются новые иконки).
Так, собственно вопрос, зачем еще одно решение задаче, которая уже давно решена?
У нас приложение целиком построено на данных из REST API (собственно апи предоставляет данные для сайта и для iOS приложения, и это апи с сайтом никак не связано). Поэтому сделать данные синхронными можно только добавив между пользователем и API промежуточное звено, которое получит данные из API и отдаст их клиенту вместе со страницей. Я думаю, что это звено лишнее.
Пример реализации мне нравится, стоит попробовать, спасибо!
Так, а если модуль ничего не делает, кроме как предоставляет удобный интерфейс доступа к данным. То есть например на основе параметра settings.currency предоставляет функцию getPrice (которая внутри себя содержит всю логику просчета цены исходя из настроек). Ну и помимо этого, дополняет данные функциями уведомления об изменении этих данных, а так же непосредственно предоставляет интерфейс изменения этих данных. То есть наш модуль это модель в MV* (например модуль возвращает объект на основе Backbone.Model, с данными загруженными из API). Соответственно отсутствие данных = отсутствие объекта-модели = невозможность работы приложения, которая обрабатывается в штатном режиме (то есть для всей системы наш модуль — это и есть данные, и только сам модуль определяет откуда реальные данные берутся, из файла, из АПИ, может быть несколько запросов к АПИ и т.п.)
Ок, тогда задам другой вопрос. Как лучше спроектировать архитектуру проекта в таком случае:
Храним в API данные пользователя и некоторые настройки отображения сайта (например, в какой валюте отображать цены и что-нибудь подобное).
Есть много модулей (профиль пользователя, настройки, корзина, карточка товара и т.п.) которые непосредственно зависят от данных пользователя (например авторизован пользователь или нет, от его настроек и т.п.).
Получается, что каждый из этих модулей будет так или иначе запрашивать данные из API (следовательно для каждого из них нужно продумывать вариант исключений — что делать, если данные не загрузились), а так же добавлять логику работы с этими данными (например значение user.settings.currency="rub" означает что все цены нужно умножить на 30, ну и т.д.)
У меня в голове сложилась мысль, что лучше всего для таких данных API сделать модуль-интерфейс, который загрузит данные и предоставит к ним удобный интерфейс взаимодействия (причем как на чтение, так и на запись). Ну и самый очевидный вариант реализации — асинхронный provide. (или я что-то упускаю или смотрю не в ту сторону?)
Конечно, можно попробовать наполнить модуль минимальным набором данных «по умолчанию» (на случай проблем с доступом к API) и реализовать механизм оповещений об обновлении данных (его так или иначе реализовывать придется, если данные можно изменять), но все таки, на момент первого обращения к модулю хотелось бы получить его стабильное состояние (с загруженными или дефолтными [если загрузка невозможна], но окончательными данными) с которыми можно работать. (чтобы например избежать лишнего пересчета: сначала все делаем по данным дефолта, а как пришли данные из API — по полученным).
Быть может я просто зациклился на одном варианте реализации и не вижу «леса за деревьями», не помешал бы свежий профессиональны взгляд :)
Асинхронный provide модулей очень нужен, когда модуль изолирован от данных (например, все данные получаются из REST API). Поэтому, пока модуль не получит данные и не инициализирует свое состояние — он бесполезен в использовании (если от него зависят другие модули, могут возникнуть коллизии из-за асинхронности загрузки данных в модуль).
В LMD как я понимаю сейчвс реализовать такой модуль возможности нет?
Процентов на 90 что использовался php. Однако официально Артему не разрешили рассказывать о хостинге, движках и прочей информации, касающейся тонкостей реализации))
Спасибо. Мы уже работаем над развитием сервиса и в ближайшее время мы собираемся прикрутить RSS и email-рассылку: это поможет пользователям узнать о приближающихся конференциях, о их начале и завершении, а так же рассылки помогут пользователям найти свои вопросы и ответы на них.
data:uri
(вdata:uri
добавлялись только иконки, причем оптимизированные с помощью imageOptim, размер не более 2х кб на каждую). И результаты в FF (версии 21, 22) получились ровным счетом обратные, в сборке сdata:uri
событиеwindow.onload
срабатывало в среднем в 3-4 раза быстрее. Для чистоты эксперимента — в Сhrome и FF nightly 25.0a1data:uri
быстрее в 2 разаА по поводу иконок — опять таки, если иконка прямо относится к тексту, то используйте img, если нет — все что угодно, но при этом по возможности семантично (лишние теги плодить не имеет смысла).
И, кстати, забыл упомянуть, что если верстка проекта нацелена на хорошие браузеры (IE9+) то есть еще возможность использовать множественные бэкграунды, для избавления от лишних тегов.
tab
img
с аттрибутомalt
.Если же картинка играет роль иконки, бэкграунда и не несет смыслового значения, то лучше всего задавать ее в качестве
background-image
для нужного тега. (найдено на stackoverflow)При этом очистить html-код от мусорных тегов, вроде предложенных вами
<i class="some-image"></i>
или предложенных в комментириях<span class="some-image"></span>
помогут псевдоэлементы::before
и::after
коих целых 2 на каждый тег (за исключениемinput
)Генерация спрайтов — задача тривиальная и решенная уже много-много раз (полный список решений). Тем более, последнее время использование
data:uri
считается более лучшим, так как экономит память и количество запросов к серверу, и, в качестве бонуса, избавляет от головной боли слежения за версией спрайта (если сайт обновляется и с некоторой периодичностью в спрайт добавляются новые иконки).Так, собственно вопрос, зачем еще одно решение задаче, которая уже давно решена?
Пример реализации мне нравится, стоит попробовать, спасибо!
settings.currency
предоставляет функциюgetPrice
(которая внутри себя содержит всю логику просчета цены исходя из настроек). Ну и помимо этого, дополняет данные функциями уведомления об изменении этих данных, а так же непосредственно предоставляет интерфейс изменения этих данных. То есть наш модуль это модель в MV* (например модуль возвращает объект на основе Backbone.Model, с данными загруженными из API). Соответственно отсутствие данных = отсутствие объекта-модели = невозможность работы приложения, которая обрабатывается в штатном режиме (то есть для всей системы наш модуль — это и есть данные, и только сам модуль определяет откуда реальные данные берутся, из файла, из АПИ, может быть несколько запросов к АПИ и т.п.)Храним в API данные пользователя и некоторые настройки отображения сайта (например, в какой валюте отображать цены и что-нибудь подобное).
Есть много модулей (профиль пользователя, настройки, корзина, карточка товара и т.п.) которые непосредственно зависят от данных пользователя (например авторизован пользователь или нет, от его настроек и т.п.).
Получается, что каждый из этих модулей будет так или иначе запрашивать данные из API (следовательно для каждого из них нужно продумывать вариант исключений — что делать, если данные не загрузились), а так же добавлять логику работы с этими данными (например значение
user.settings.currency="rub"
означает что все цены нужно умножить на 30, ну и т.д.)У меня в голове сложилась мысль, что лучше всего для таких данных API сделать модуль-интерфейс, который загрузит данные и предоставит к ним удобный интерфейс взаимодействия (причем как на чтение, так и на запись). Ну и самый очевидный вариант реализации — асинхронный provide. (или я что-то упускаю или смотрю не в ту сторону?)
Конечно, можно попробовать наполнить модуль минимальным набором данных «по умолчанию» (на случай проблем с доступом к API) и реализовать механизм оповещений об обновлении данных (его так или иначе реализовывать придется, если данные можно изменять), но все таки, на момент первого обращения к модулю хотелось бы получить его стабильное состояние (с загруженными или дефолтными [если загрузка невозможна], но окончательными данными) с которыми можно работать. (чтобы например избежать лишнего пересчета: сначала все делаем по данным дефолта, а как пришли данные из API — по полученным).
Быть может я просто зациклился на одном варианте реализации и не вижу «леса за деревьями», не помешал бы свежий профессиональны взгляд :)
В LMD как я понимаю сейчвс реализовать такой модуль возможности нет?