...

суббота, 20 июля 2019 г.

[Перевод] 7 советов по оптимизации CSS для ускорения загрузки страниц

В современном вебе, время загрузки страницы сайта — одна из важнейших метрик. Даже миллисекунды могу оказывать огромное влияние на Вашу прибыль и медленная загрузка страницы может легко навредить Вашим показателям конверсии. Существует много инструментов и техник, которые Вы можете применить для ускорения Вашего вебсайта. В этой статье мы рассмотрим лучшие советы по оптимизации CSS, которые Вы можете использовать для повышения производительности интерфейса.

image

Примечание от переводившего
Большая просьба снисходительно отнестись к замеченным ошибкам и сообщить о них.
Спасибо.

1. Найдите узкие места производительности


Самое главное при всех видах оптимизации — начать с тщательного аудита. К счастью, существует много инструментов для диагностики CSS, которые могут помочь Вам найти имеющиеся узкие места в производительности. Первое и самое главное, Вы можете использовать «Инструменты разработчика» в Вашем браузере, чтобы проверить, насколько быстро загружаются данные. В большинстве браузеров открыть «Инструменты разработчика» можно, нажав клавишу F12.

Например, в «Инструментах разработчика» браузера Firefox Вы можете узнать размер и время загрузки всех CSS-файлов, загружаемых на Вашей странице, используя закладку «Network». Вы также можете проверить, насколько быстро Ваши CSS-файлы загружаются с использованием или без использования кэширования. Поскольку здесь показываются внешние CSS, такие как файлы шрифтов Google Fonts и CSS-файлы, загруженные из сторонних CDN-серверов, Вы можете найти много источников, о которых даже не знали ранее

image

Pingdom Tools и Lighthouse от Google — еще два бесплатных инструмента, которые разработчики часто используют для анализа скорости сайта и производительности интерфейса. Pingdom Tools, например, даёт Вам несколько полезных советов по оптимизации CSS, при запуске простого теста скорости вебсайта.

image

2. Минифицируйте и сжимайте CSS-файлы


Большинство вебсайтов используют несколько CSS файлов. Хотя в большинстве случаев использование модульных CSS-файлов считается лучшим решением, загрузка каждого отдельного файла может занимать некоторое время. Но именно по этой причине существуют инструменты для минификации и сжатия CSS. Если Вы используете их с умом, это может значительно сократить время загрузки страницы.

Существуют онлайн-сервисы, такие как CSS Minify, которые позволяют Вам минифицировать CSS-файл просто скопировав его в простую форму. Такой тип сервисов может хорошо работать с небольшими проектами. Тем не менее, их использование может стать обременительным и трудоемким в ситуациях с большими проектами, которые включают множество CSS-файлов. В таких ситуациях лучше отдать предпочтение автоматизированным решениям.

В наши дни, большинство инструментов сборки позволяют выполнять сжатие автоматически. Например, Webpack по умолчанию возвращает все файлы проекта как минифицированный пакет. PostCSS также имеет умные плагины, такие как CSS Nano, которые не только минифицируют Ваши файлы, но также производят над ними множество специальных оптимизаций.

image

3. Используйте Flexbox и CSS Grid


Если при написании CSS Вы всё еще полагаетесь исключительно на традиционную блочную модель и выравниваете элементы на странице, используя margin, padding и float, Вам следует рассмотреть переход на более современные методы, именуемые Flexbox и CSS Grid. Они позволят Вам реализовывать сложные макеты гораздо меньшим количеством кода.

Используя старые подходы, Вам придется использовать много трюков и ухищрений даже для таких простых вещей, как центрирование элементов по вертикали. Однако, это не относится к Flexbox и CSS Grid. Хотя освоение новых подходов может занять некоторое время, оно стоит того, поскольку размер Ваших CSS-файлов будет намного меньше. Это особенно актуально для Flexbox, который на данный момент имеет очень хорошую поддержку браузерами (98.3% глобально).

image

Хотя CSS Grid поддерживается браузерами не так хорошо (92.03% глобально), уже можно использовать этот подход, если Вы не должны обеспечивать поддержку старых браузеров или готовы реализовать фолбек.

image

4. Используйте тег <link> вместо правила @import


Существует два основных метода загрузки CSS-файлов на веб-страницу:
  1. добавить в раздел <head> HTML-страницы, используя тег <link>
  2. импортировать из других таблиц стилей, используя CSS-объявление @import

Вам необходимо добавить объявление @import в начало основного файла CSS. В большинстве случаев, этот подход используется для загрузки небольших ресурсов, таких как шрифты и другие элементы дизайна. На первый взгляд, это может выглядеть хорошим решением, однако, браузеру требуется гораздо больше времени для загрузки дополнительных таблиц стилей, чем в ситуации, когда HTML-страница загружает их напрямую, используя тег .

Когда Вы добавляете более одного CSS-файла на HTML-страницу, всегда учитывайте специфичность в CSS. Начинайте с общей таблицы стилей, а затем указывайте более специфичные. Вам нужно следовать этому принципу, потому что таблицы стилей, добавленные позже, переопределяют правила предыдущих CSS-файлов. Пример, когда CSS-файлы добавляются в правильном порядке:

<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="page.css">
<link rel="stylesheet" href="component.css">

5. Используйте градиенты и SVG вместо изображений

Загрузка всех изображений на веб-странице может отнимать много времени. Для сокращения этого времени, разработчики используют множество методов оптимизации изображений, таких как загрузка изображений из внешнего CDN или использование инструментов сжатия изображений, таких как TinyJPG. Эти решения могут существенно помочь, однако в некоторых ситуациях использование ресурсоёмких JPG и PNG изображений можно заменить CSS-эффектами.

Например, Вы можете использовать градиенты вместо огромных фоновых изображений, которые могут немного замедлить работу браузера посетителя Вашей страницы. Можно использовать градиентные функции CSS для создания линейных, радиальных и повторяющихся градиентов. С помощью этих встроенных в CSS функций Вы можете задавать не только цвета, но также и угол градиента.

Следующее правило, например, создаёт красивый градиентный фон, который загружается намного быстрее, чем любые изображения:

div {
    background: linear-gradient(45deg, lightgreen, royalblue);
}

Для более сложных градиентов и текстур, Вы также можете использовать генераторы, такие как CSSmatic (на изображении ниже) и ColorZilla

image

Помимо градиентов, традиционные JPG и PNG изображения Вы также можете можете заменить масштабируемой векторной графикой (SVG). Она не только быстрее загружается, но также Вам требуется загрузить лишь одну версию изображения. Это обусловлено тем, что SVG-изображение может масштабироваться до любых размеров без потери качества в связи с его векторной природой. Кроме того, Вы также можете стилизовать SVG с помощью CSS, как обычный HTML-файл.

6. Избегайте правила !important


Хотя правило !important может быть настоящей находкой в определенных ситуациях, его следует использовать только в крайнем случае. Это правило создаёт исключение из каскада. То есть, когда Вы добавляете !important в CSS-объявление, оно переопределяет любые другие объявления, даже те, которые имеют большую специфичность. Вот как выглядит его синтаксис:
h1 {
   margin-bottom: 20px !important;
}

Если в CSS присутствует много правил !important, браузер пользователя должен будет проводить дополнительные проверки в коде, что может дополнительно замедлить страницу. Хорошим тоном считается никогда не использовать !important для всего сайта или при создании темы или плагина. Если есть возможность, используйте это правило только в ситуациях, когда хотите переопределить CSS из сторонней библиотеки.

7. Рефакторинг CSS


Хотя рефакторинг CSS редко бывает легкой задачей, зачастую это может значительно повысить производительность веб-сайта. Например, когда Ваши CSS-файлы слишком большие, или Вам досталась устаревшая кодовая база, или у Вас очень плохое время загрузки страницы, что серьезно вредит Вашей конверсии. Цель рефакторинга CSS — сделать Ваш код более изящным, легко поддерживаемым и быстрее загружаемым.

Рефакторинг CSS — это многоступенчатый процесс, в ходе которого Вам нужно проанализировать каждый аспект Вашего CSS кода. Вам нужно проверить следующие моменты:

  • присутствуют ли неиспользуемые или дублирующие CSS-правила или ресурсы
  • возможно ли использование более современных техник, таких как Flexbox и CSS Grid
  • не используется ли слишком много специфичности (посчитать это можно с помощью визуального калькулятора специфичности)
  • грамотно ли организована структура CSS-файлов (например, легче поддерживать меньшие файлы, чем большИе)
  • стоит ли начать использовать инструменты автоматической сборки
  • и многое другое.

Прежде чем приступить к рефакторингу, установите измеримые цели и выберите критерии, по которым будете ориентироваться, такие как скорость загрузки страницы или время первого отрисованного содержимого, чтобы Вы могли сравнить их значения до и после.

Также не забудьте использовать систему контроля версий, такую как Git. В этом случае, если что-то пойдет не так, Вы сможете вернуться к предыдущей версии кода.

Подводя итоги


Существует множество советов по оптимизации CSS, которые можно использовать для повышения производительности Вашего веб-сайта. Большинство из них просты в реализации, но могут существенно повлиять на время загрузки Вашей страницы. Более быстрая загрузка страниц не только повышает удобство использования, но также помогает улучшить позиции в Google и другие поисковых системах.

Кроме лучших практик оптимизации CSS, Вы можете использовать и другие техники ускорения загрузки, такие как кэширование, Google AMP и HTTPS протокол. Если Вы хотите узнать о них больше, можете также ознакомиться с нашей статьей 10-step guide to improve website loading speed

Let's block ads! (Why?)

[Из песочницы] Продвинутый Debug

Debug Area — полезная функция в работе iOS разработчика в Xcode. Как только мы начинаем осваивать разработку под iOS, и пытаемся отойти от привычного и любимого print метода, и найти более быстрые и удобные методы понимания состояния системы в определенный период мы начинаем изучать область дебага (Debug Area).

Скорее всего, в Debug панель ваш взгляд упадёт до того, как вы будете понимать, что именно там происходит. При первом падении приложения нижнее меню открывается автоматически, оно изначально может послужить помощью для понимания проблемы (Вспомним старую добрую “Fatal error: Index out of range”), в основном в самом начале вы не будете понимать, что от нас хочет Xcode и приметесь гуглить ошибки, но по ходу роста всё больше и больше информации станет понятной.

С самого начала программист старается оптимизировать свою работу. Для этого мы стремимся понять в какой момент наша программа перешла в некорректное состояние. И тут в зависимости от точки в которой находится эволюция программиста, методы могут разниться. Сначала как правильно Debug осуществляется методом “print()”, потом идёт расстановка Breakpoints и вызов методов “po”, далее ознакомление с Debug Variable Input (области рядом с консолью в Xcode), а далее приходит понимание и способов компиляции кода в процессе остановки на Breakpoint методов — “expression” (По крайней мере, такая была эволюция у меня).

Давайте попробуем разные способы которые нам помогут понять и изменить состояние нашего приложения. Самые простые вроде “print()”, и “po” рассматривать не будем, я думаю, вы и так понимаете их суть и умеете применять.

Создадим простое приложение с одним экраном в котором будем всего один тип ячеек (TableViewcell) c двумя элементами внутри: UIImageView и UILabel. В ячейках будем писать её порядковый номер, а в картинку ставить либо image1, либо image2.

Метод tableViewCellForRowAtIndexPath будет создавать для нас ячейки, проставлять данные и возвращать:

image
Данный метод будет генерировать такую таблицу:

image

Breakpoint


Давайте остановим нашу программу и допишем какой-нибудь текст в наш Label.

1. Ставим Breakpoint:

image

2. Программа остановила выполнение на 55 строке, сразу после присваивания текста. Так как мы находимся на строке, расположенной в зоне видимости ячейки, мы можем взаимодействовать с нашей ячейкой.

3. Пишем в консоли команду изменить текст ячейки:

image

4. Убираем наш Breakpoint и нажимаем кнопку «продолжить выполнения программы».

5. На экране нашего телефона видимо, что всё успешно получилось:

image

expression выполняет выражение и возвращает значение на текущем потоке.

Edited Breakpoint


Но, что если нам понадобиться изменить текст в большом количестве ячеек? Или мы уже в процессе выполнения программы поняли, что нам надо поменять?

Мы можем оптимизировать выполнение этой операции и немного ускорить работу, сделать изменение текста в ячейки тогда, когда он доходит до Breakpoint и продолжить выполнять программу, это сократит много времени и позволит не печатать одно и тоже для каждой ячейки.

Для этого нам понадобиться немного модифицировать наш Breakpoint, прописать туда дополнительно код, который будет в зоне видимости нашей ячейки менять её текст и продолжать работу программы.

  1. Создаем breakpoint.
  2. Левой кнопкой мыши по стрелочке breakpoint’a.
  3. Нажимаем Edit Breakpoint.
  4. Condition — условия при котором Breakpoint сработает, сейчас он нам не нужен.
  5. Ignore — сколько раз пропустить Breakpoint прежде чем он сработает (тоже не то).
  6. А вот Action — то, что надо, выбираем тип действий Debugger Command.
  7. Пишем выражение которое нам нужен выполнить:
  8. expression cell.desriptionTextOutlet.text = "\(indexPath.item) mission complite”.
  9. Ставим галочку — Продолжить выполнение после успешного выполнения команды.

image

9. Пробуем.

image

Это успех, получилось изменить текст для каждой ячейки во время формирования таблицы, и нам не пришлось жертвовать временем и прописывать операции для каждой.

Breakpoint function


Всегда бывают моменты когда в нашем приложении происходит что-то, что мы не можем объяснить, текст не меняется или меняется больше чем необходимо, казалось бы Breakpoint в таком случае ставить некуда. Но это не совсем так, если вы знаете Obj-C, и знаете какой метод выполняет компилятор который вы хотите отследить вы можете поставить на него Breakpoint и в следующий раз, когда метод вызовется, приложение остановиться в процессе выполнения Assembler кода.

1. В Breakpoint навигаторе выбираем Symbolic Breakpoint.

image

2. Мы хотим отследить метод установки текста в ячейке, пишем -[UILabel setText:].

image

3. Нулевого аргумента не существует, и счет начинается с первого. Первый пойманный метод не тот, что нам нужен (он устанавливаем текущее время в статус бар), а второй как раз наш:

4. Под “$arg1” храниться описание объекта.

5. Под “$arg2” храниться selector функции.

6. Под “$arg3” храниться текст получаемый методом.

Ок, с этим вроде бы понятно. Но иногда возникают ситуации, когда установкой одного текста в статус бар дело не ограничивается, и надо отследить выполнение метода в конкретном контроллере, что же делать? Можно включить Breakpoint подобный тому, что мы установили ранее, но установив его позицию в коде. Что это значит? Мы точно знаем, что наш view появится когда мы будем устанавливать текст в ячейку, значит самое то поставить его во viewDidLoad или после создания ячейки.

Для создания breakpoint мы устанавливаем его на линии, и в action прописываем следующий код:

breakpoint set --one-shot true --name "-[UILabel setText:]”

breakpoint set —one-shot true — создаем breakpoint
—name — имя символьного breakpoint
“-[UILabel setText:]” вызываемый метод

Вот что получилось:

image

Skip Lines

А что если мы заподозрили, что какая-то строка кода портит нам всю программу? В процессе выполнения кода можно избежать выполнения определенной строки кода так:

  1. Ставим breakpoint на строку, которую мы не хотели бы выполнять.
  2. Когда выполнение остановиться, перетаскиваем его в строку, с которой хотим продолжить выполнение программы (забавно, но это не всегда работает, ниже вариант без перетаскивания).

Так же есть другой вариант, который позволит оптимизировать пропускание строк, — это прописывание соответствующей команды в “edit breakpoint”. Команда является рискованной, так как суть таких скачков — это избавить нас от ребилда, но если вы пропустите инициализацию объекта и попытаетесь к нему обратиться программа упадёт.

image

Остановим нашу программу на инициализации картинки, и не будем вообще присваивать картинку ячейке, для этого нам надо пропустить пять строк кода и вернуть ячейку без картинки, для этого на текущем потоке мы пропускаем выполнение следующих пяти строк кода, и продолжаем выполнение программы:
<
img src=«hsto.org/webt/ud/1q/vi/ud1qviab0b7yahv-s8yydt5ouna.png» alt=«image»/>

Звучит довольно неплохо, но картинку всё же присвоить хочется, давайте добавим метод присвоения в breakpoint:

image

Удачная комбинация, теперь у нас в каждой ячейке только один тип картинки.

Watchpoint


Еще одна удобная функция в дебагере — это отслеживание значений в программе, watchpoints. Watchpoint чем то похожа на KVO, мы ставим breakpoint на изменение состояния объекта, и каждый раз, когда он меняет своё состояние, процесс выполнения программы останавливается, и мы можем посмотреть значение и места, откуда и кем было изменено значение. Например, я поставил watchpoint на ячейку, что бы узнать, что происходит в момент листания таблицы и иницилизации новой ячейки. Список команд получился очень большой, поэтому его я приводить не буду просто упомяну некоторые: выполнения layout view находящихся внутри ячейки и простановка constraint, анимация, простановка состояний для ячейки и многое-многое другое.

Для простановки watchpoint на значение необходимо остановить выполнение программы breakpoint в области видимости свойств, который вы хотите отслеживать, выбрать свойство в “debug variable” панели и выбрать watch “<параметр>”.

image

Для того, что бы снять watchpoint с переменной надо заглянуть в breakpoint navigator, там вместе с остальными breakpoint будет находиться и наш watchpoint.

Breakpoint UI Change


Иногда нам надо узнать больше об объекте, который мы пытаемся отдебажить. Самый простой вариант — это использовать “po”, для вывода информации об объекте, и там же посмотреть на расположение объекта в памяти. Но бывает, что мы не имеем прямой ссылки на объект, он не представлен в API view, на которой лежит или возможно скрыт библиотекой. Один из вариантов использовать View Hierarchy, но это не всегда удобно да и понять, что вы нашли нужный view не всегда сложно. Можно попробовать использовать команду:
expression self.view.recursiveDescription()

Она есть в Obj-C но в Swift её убрали из за особенностей работы языка выполнить мы её не можем, но так как на Debuger работает с Obj-C, в теории ему можно скормить эту команду, и он поймёт, что вы от него хотите. Для выполнения кода Obj-C в консоли необходимо ввести команду:
expression -l objc -O - - [`self.view` recursiveDescription] 

Что вы тут видите? Я вижу довольно не удобную конструкцию, к котором можно было бы привыкнуть со временем, но лучше мы не будем этого делать, а используем typealias для упрощения команды:
command alias poc expression -l objc -O —

Теперь наша команда сокращается и упрощается, но продолжает делать работу:
poc [`self.view` recursiveDescription]

Будет ли она работать после закрытия Xcode или в другом проекте? Увы, нет. Но это можно исправить! Создав файл .lldbinit и вписав туда наш alias. Если не знаете как, вот инструкция по пунктам:

1. Создаете файл .lldbinit (в качестве прототипа можете взять .gitignore, он относится к тому же типу текстовых невидимых файлов).

2. Напишите в этом файле ровно следующую команду:

 command alias poc expression -l objc -O - - 

3. Файл поместите в папку по адесу “MacintoshHD/Users/”.

И так мы получили описание всех view, представленных на экране. Давайте попробуем посмотреть, что мы сможем сделать с адресом объектов в памяти. Для Swift тут имеется метод с недостатоком, надо всё время приводить тип объекта в памяти к определенному значению:

po unsafeBitCast(0x105508410, to: UIImageView.self)

Теперь мы видимо положение нашей картинки в ячейке, давайте её подвинем что бы она была по центу ячейки и имела отступ с боку 20 px.

image

Бывает не сразу заметно изменение, а необходимо снять с debug приложение что бы заметить изменение.

Но если мы хотим видеть нечто подобное в каждой ячейки, надо ускорить выполнение команд, можно написать на Python несколько скриптов которые будут работать на нас (как добавлять скрипты можно посмотреть здесь www.raywenderlich.com/612-custom-lldb-commands-in-practice), и если вы умеете обращаться с Python и хотите написать на нём для lldb то вам пригодиться.

Я же решил написать расширение для класса UIView, который просто будет двигать view в нужном направлении, мне показалось так будет меньше проблем с подключением новых скриптов к LLDB и не сложно для любого iOS программиста (иначе надо осваивать Python для LLDB).

Я не стал искать место объекта в памяти и приводить его в нужный класс, что бы потом взять frame, это так же займет слишком много времени. Вопрос решился написанием функции в расширении UIView:

image

К сожалению, она плохо работает с ячейками, скорее всего из за того, что в момент исполнения команды flush не все позиции ячейки просчитаны и она не появилась на экране (мы пока не вернули tableViewCell). С остальными статическими элементами оно работает отлично.

Зная положение view в иерархии, мы можем получить к нему доступ и менять его положение.

А теперь обратная ситуация, когда мы можем получить доступ к ViewHierarchy и хотим оттуда получить данные о view. В Xcode есть возможность просматривать иерархию view в процессе выполнения программы, так же там можно просмотреть цвета, расположение, типы и привязки к другим объектам в том числе. Давайте попробуем получить доступ к constraints нашего UIImageView.

Для получения данных о constraint:

1. Нажмите на Debug View Hierarchy.
2. Включите Clipped Content на панели внизу появившегося экрана.
3. Включите Constraints на той же панели.
4. Выберите Contraint.
5. В меню нажмите Edit -> Copy (Command + C).
6. Копируется привязка вот такого вида: ((NSLayoutConstraint *)0x2838a39d0).
7. И теперь, так же как мы меняем её через код так же можно поменять и в lldb:
expression [((NSLayoutConstraint *)0x2838a39d0) setConstant: 60]
8. После нажатия кнопки продолжить, элемент обновит своё положение на экране.

Таким же образом можно менять цвета, текст и многое другое:

expression [(UILabel *)0x102d0a260] setTextColor: UIColor.whiteColor]

Demo проект получился слишком простым (60 строк кода во ViewController), большую часть кода, который я написал, представлена в статье, так что сложности в воспроизведении тестового проекта не возникнет.

P.S.: Если есть вопросы или замечания пишите. Посматривайте WWDC и Дебажте как Pro.

Советую так же ознакомиться с материалами:

Вдохновлялся Advanced Debugger WWDC 18 Session
Команды Debugger
Добавление скриптов Python в LLDB Xcode

Let's block ads! (Why?)

Вот это поворот: почему Apple изменила требования к разработчикам приложений

В прошлом месяце Apple опубликовала изменения в гайдлайнах для разработчиков приложений под iOS. Они коснулись, в том числе, приложений для родительского контроля и обеспечения конфиденциальности детей. Причем часть новых рекомендаций идет вразрез с решениями, которые Apple приняла несколькими месяцами ранее. Обсуждаем требования к приложениям в App Store, которые вступят в силу 3 сентября этого года, и разбираемся в причинах — а также возможных долгоиграющих последствиях — этой ситуации.


Фото — Aziz Acharki — Unsplash

Что изменилось — коротко


Помимо презентации нового Mac Pro, Pro Display XDR и iOS 13 в начале июня Apple анонсировала и определенные изменения в гайдлайнах для разработчиков приложений. Короткий пост обо всех этих изменениях вышел в новостном разделе портала Apple Developer 3 июня.

Одно из нововведений, которое вызвало особенно бурную реакцию американских СМИ, — запрет на использование «сторонних аналитических сервисов или рекламы» в приложениях для детей (разделы 1.3 и 5.1.4 гайдлайнов). Как указано в пункте 5.1.4, «сбор и передача данных третьей стороне приложениями из категории «Дети» запрещены». Требование действует для новых приложений, а существующие нужно привести в соответствие до 3 сентября 2019 года.

Кроме того, к детям имеют непосредственное отношение и нововведения пунктов 5.4 и 5.5. По новым правилам, приложения, осуществляющие функции родительского контроля, могут «в ограниченных случаях» использовать технологию управления мобильными устройствами (Mobile Device Management, MDM) и API NEVPNManager. При этом в Apple подчеркивают, что «приложения должны иметь полезную функциональность или развлекательную ценность вне зависимости от возраста пользователя» — будь то ребенок или взрослый.

Почему решили изменить политики — и именно сейчас


В гайдлайнах Apple ссылаются прежде всего на требования американских и европейских законодателей, а именно на Закон о защите конфиденциальности детей в интернете (Children’s Online Privacy Protection Act, COPPA) и GDPR. Но отмечают, что при создании детских приложений нужно учитывать и опыт других стран и их требований к защите персональных данных.

Правда, есть основания предполагать, что сами по себе COPPA и GDPR — не единственная причина ограничений. Некоторые СМИ напрямую связывают изменение политик с резонансным отчетом Wall Street Journal, согласно которому 79 из 80 протестированных ими приложений из App Store использовали в среднем по четыре трекинговых системы для сбора аналитики, показа рекламы или маркетинговых целей.

Журналисты отдельно остановились на одном из «детских» приложений, которое сохраняло имя и возраст ребенка, а также информацию о его действиях в приложении, а затем передавало данные Facebook. Критика Wall Street Journal оказалась особенно болезненной — незадолго до этого Apple запустили рекламную кампанию, слоганом которой стала фраза: «Все, что происходит в вашем iPhone, остается на вашем iPhone».

Авторы материала выражали несогласие не столько с самим фактом сбора и передачи данных, а с непрозрачностью всей системы, при которой пользователь не знает, что в действительности делает то или иное приложение. В Apple в ответ выпустили заявление о том, что компания не вмешивается в отношения между разработчиком и пользователем, но в будущем планирует работать над улучшением безопасности и сохранности персональных данных.

И новые политики, видимо, стали результатом этой работы. Неслучайны и послабления в пунктах 5.4-5.5. Дело в том, что еще в апреле Apple наложила ряд ограничений на приложения, реализующие функции родительского контроля и использующие технологии MDM. Компания тогда объяснила ситуацию тем, что приложения нарушали политики App Store, еще с 2017-го года предписывавшие разработчикам отказаться от MDM-функциональности.


Фото — Tyler Gardon — Unsplash

Однако «репрессиям» приложения подверглись сравнительно недавно, после того, как в iOS 12 появился сходный по функциям сервис Screen Time. Ситуация вызвала вопросы не только у независимых разработчиков приложений, но и у американского правительства — примечательно, что пост об изменении гайдлайнов и отмене «запрета на MDM» вышел в тот же день, что и материал New York Times с информацией о том, что Apple хотят проверить на предмет нарушения антимонопольного законодательства США в связи с ситуацией в App Store.

Кто еще теперь озабочен защитой конфиденциальности детей


Случай с Apple — не единичный. В похожей ситуации чуть раньше оказалась Google, которая два месяца назад также выпустила обновление политик в отношении приложений для детей, доступных в Google Play. На этот шаг компанию побудила пойти разбирательство Федеральной торговой комиссии США (FTC), согласно которому компания не обеспечивала соблюдения разработчиками приложений требований закона COPPA.

Помимо Google Play под прицелом FTC оказался и YouTube. Согласно данным комиссии, сервис также не соответствует требованиям уже упомянутого Закона о защите конфиденциальности детей в интернете. По мнению Washington Post, ситуация с YouTube сигнализирует, что Федеральная торговая комиссия хочет серьезно усилить контроль в этой сфере — он значительно ослаб с момента вступления COPPA в силу в 1998 году.

Правда, и YouTube оказался далеко не первым сервисом, который попал в поле зрения FTC. Комиссия уже успела оштрафовать ряд компаний, выпускающих приложения для детей, на рекордные $ 5,8 млн за несоблюдение COPPA.

Возвращаясь к Apple: что думают разработчики


Большинство критиков сходятся во мнении, что политика компании как минимум непоследовательна, что и подтверждают изменения в правилах. Wall Street Journal идет дальше и заявляет, что если и искать крайнего в ситуации с несанкционированным использованием персональных данных, то основная вина будет лежать на Apple, а не на разработчиках.


Фото — Rita Morais — Unsplash

Кстати, кое-кто из них уже высказался по поводу новых политик. Одной из компаний, которые подпадают под действие новых требований, стала PBS и ее подразделение PBS Kids (этот канал, к примеру, транслировал «Улицу Сезам» с 1969 по 2016 годы). PBS пояснили, что теперь они не смогут адекватно оценивать эффективность работы приложений и, как следствие, улучшать их функциональность и образовательные возможности.

Как отметила генеральный директор канала Пола Кергер (Paula Kerger), PBS будут вынуждены убрать приложения из App Store, при том, что сейчас ими пользуются миллионы детей. В PBS считают, что принятие таких решений без учета мнения самих разработчиков недопустимо. «Мы хотим донести мысль, что нам нравится работать с этими платформами [такими как App Store], они дают нам потрясающий охват. Сядьте и поговорите с нами», — комментирует ситуацию Кергер.

По поводу обновления политик высказались на Hacker News и форуме Apple Developer. Большинство поддержало Apple в стремлении оградить детей от рекламы, однако некоторые отметили, что сама формулировка, которую использовали в гайдлайне, позволяет трактовать новые правила двояко.

Так, п.1.3 содержит фразу «Apps in the Kids Category may not include third-party advertising or analytics» (дословно «Приложения в категории «Дети» не могут включать стороннюю аналитику и рекламу»). Остается неясно, к чему в этом случае относится прилагательное «сторонний» (third-party) — к рекламе и аналитическим сервисам или только к рекламе.

Во втором случае компании все-таки могут использовать собственные разработки и применять их для непосредственного анализа поведения пользователей.


Один из комментаторов в треде на Reddit отметил, что если бы компания хотела дать непротиворечивое указание, то сформулировала бы требование иначе (Apps in the Kids Category must not include analytics or third-party advertising). А официальная формулировка дает Apple право «казнить или миловать» разработчиков по своему усмотрению.

Выводы


Последние события, похоже, вынуждают пересмотреть статус-кво крупных ИТ-корпораций. Что касается Apple, то все чаще звучит мнение о том, что компания должна выбрать сторону, и не может оставаться владельцем App Store и одновременно игроком на рынке приложений. К каким результатам приведет текущая политика компании, предстоит увидеть в ближайшее время.
Посты из наших блогов и социальных сетей:

Персональные данные: особенности публичного облака
Получение OV и EV сертификата — что нужно знать?
Как IaaS помогает франчайзи «1С»: опыт 1cloud
Эволюция архитектуры облака 1cloud
Как обезопасить Linux-систему: 10 советов

F.A.Q. по частному облаку от 1cloud
Мифы об облачных технологиях

В OIN больше трех тысяч лицензиатов — что это значит для открытого ПО
Как оценить производительность СХД на Linux: бенчмаркинг с помощью открытых инструментов

Let's block ads! (Why?)

Эксперимент Instagram по скрытию счетчика лайков расширяется еще на 6 стран

Около трех месяцев назад Instagram начал эксперимент над небольшим процентом канадских пользователей. Возможность просмотра количества лайков фото и ведео была отключена для всех, кроме самих авторов контента. На этой неделе эксперимент был расширен еще на шесть стран.
Instagram не делится комментариями по ходу процесса, но, судя по тому, что исследование решено продолжить, оно дает свои результаты. Как говорит об идее эксперимента сама компания, “мы хотим, чтобы юзеры, просматривающие ваш контент, вникали в сам контент, а не в количесво заработанных им плюсиков.” Новыми странами, в которых пройдет исследование, станут Ирландия, Италия, Япония, Бразилия, Австралия, Новая Зеландия.

Пользователи смотрят на лайки, как на критерий успешности – меряются количеством, даже платят за них. Если посты не получают достаточного признания, некоторые люди удаляют их, чтобы создать эффект ‘успешного’ профиля. В теории, скрытие счетчика лайков в ленте для всех, кроме самого автора, сохранит для него представление о том, кому и насколько понравился контент, без необходимости излишне беспокоится об этом. И его посты начнут в большей степени выражать его глубокий духовный мир, нежели стремление в погоне за лайками.

Источник: https://techcrunch.com

Let's block ads! (Why?)

Google готовит спецверсию Android для кнопочных телефонов

Несмотря на то, что рынок мобильных устройств заполонили гаджеты с сенсорными экранами и без физической клавиатуры, кнопочные телефоны никуда не ушли. Наоборот, с течением времени спрос на такие устройства растет. Осознавая этот тренд, компания Google готовит операционную систему для кнопочных телефонов. ОС — Android, адаптированный для гаджетов такого типа.

На фотографиях, которые были выложены ресурсом 9to5Google, показан кнопочный телефон, который очень похож на Nokia 220, с собственной операционной системой. Возможно, это устройство представляет собой обновленную модель Nokia 220, которая создана компанией специально для участия в тестах с «кнопочным» Android.
Насколько можно видеть, интерфейс операционной системы, которая показана на экране, очень сильно отличается от интерфейса обычного Android. Тем не менее, цветовая гамма и общая стилистика сохранена прежней. Тем не менее, здесь нет рабочего стола, привычного пользователям смартфонов.

image

На главном экране есть иконки камеры, меню, браузера, YouTube (они расположены в нижней части дисплея, видимо, в качестве часто используемых приложений), виден индикатор заряда батареи, индикатор сети и другие элементы. Насколько можно понять, на этом телефоне способен работать и голосовой ассистент.

По меню можно перемещаться обычным способом — при помощи кнопок позиционирования. Есть и две дополнительные кнопки, которые были стандартом для классических телефонов Nokia, включая те из них, что были в Symbian-устройствах.

Ресурс 9to5Google ранее уже публиковал предполагаемый внешний вид Android для кнопочных телефонов. Возможно, сотрудники Google постепенно адаптируют систему под кнопочные телефоны, делая ее более удобной. Так, если раньше в нижней части экрана располагалась строка поиска, то сейчас, как и говорилось выше — иконки приложений и сервисов.

В качестве браузера используется Chrome, который также адаптирован под кнопочное управление. Адресной строки не видно, но, вероятно, она появится позже, либо же она проявляется при нажатии на определенную кнопку.

На данный момент неизвестно, можно ли устанавливать дополнительные приложения, и есть ли Google Play на ОС для кнопочных телефонов. Тем не менее, хорошо заметно приложение YouTube, которое, возможно, было установлено позже самим пользователем.

Несмотря на то, что снимки выглядят вполне реальными, пока ничего не известно о том, будет ли корпорация Google выпускать на рынок адаптированную под кнопочные системы ОС или нет.

Let's block ads! (Why?)

[Из песочницы] Как мы запускали роботов в маленький Чернобыль

Рождение концепции Remote Reality

История нашего «безумного» проекта началась три года назад, когда размышляя о будущих перспективах развития игровой индустрии, мой друг Леша сказал:

«Представь себе будущее, в котором люди в виде развлечения, из любой части мира управляют на игровом полигоне настоящими роботами, как «аватарами»».


image

Идея изначально показалась нам достаточно интересной и не сложной в реализации. Мы тут же «засели» за поиски похожих проектов и с удивлением обнаружили, что никто, ничего подобного не делал. Это казалось странным, ведь идея лежала буквально «на поверхности». Мы нашли множество следов любительских проектов создания прототипов в виде шасси с камерой на основе Arduino, но никто так и не довел ни один проект до логического завершения. Позднее, преодолевая казалось бесконечные трудности и проблемы, мы поняли причину отсутствия аналогов, но изначально идея нам казалось крайне простой и быстро реализуемой.

Следующую неделю мы посвятили проработке концепции. Мы представляли себе десятки разновидностей роботов с разными возможностями и сотни игровых полигонов, между которыми игроки могут мгновенно перемещаться через «телепорт». Любой желающий, на основе нашего «решения», имел возможность построить свой собственный игровой полигон самого разного масштаба.

Мы сразу решили, что эти мысли укладываются больше в концепцию развлекательного аттракциона, а не компьютерной игры. Люди любят развлечения и хотят чего-то нового, и мы знали, что им предложить. Как и в любом бизнесе, сразу всплыл вопрос окупаемости, ведь на первый взгляд кажется, что наша физическая модель ограничена количеством роботов. Но умножив роботов на 24 часа и на цену часа в 5-10 долларов, сомнения отпали. Финансовая модель не являлось «Клондайком», но вполне окупалась даже при 10% загрузке.

Очень быстро у нас в голове появилось название новой концепции: Remote Reality, по аналогии с Virtual Reality и Augmented Reality.


image

Как и остальные «экспериментаторы», первым делом, мы взяли машинку на радиоуправлении, поставили на нее китайскую Wi-Fi камеру, установили плату Arduino и наш робот «поехал». Мы попросили нашего знакомого из США подключится к машинке через Интернет. Он смог ездить по нашему офису и мы были в восторге. Задержки управления и видеопотока в несколько секунд нам не казались проблемой.

С этой минуты мы распределили нашу работу на два направления:


  • моделирование и строительство игрового полигона
  • разработка и создание роботов и системы управления

Гулливеры в городе Припять

Начну свой рассказ с полигона. Мы понимали, что люди должны были где-то играть. Место должно быть известное во всем мире, «загадочное» и несложное в технической реализации. Перебирая множество вариантов, нам внезапно пришла в голову мысль о Чернобыле. Чернобыльская зона соответствовала всем нашим требованиями, а главное все возможные будущие поломки и повреждения игрового полигона, можно было списать на пост апокалипсис.

Найдя помещение площадью 200 квадратных метров, мы принялись за работу, которая в итоге длилась два года. Мы рисовали улицы и текстуры домов, создавали трехмерные модели зданий, включая внутренние этажи. Потом вырезали все из ДСП плит и фанеры, собирали здания из сотен разнообразных частей.


image

Мы пытались воссоздать, как можно точнее все текстуры Припяти, «подсматривая» в Google карты. Разумеется, размеры помещения не позволяли нам создать все в точности, а упускать детали не хотелось, поэтому, например, нам пришлось ЧАЭС переместить поближе к Припяти.

Сложно подсчитать сколько сотен досок, десятков листов фанеры, ДВП и прочих «расходников» мы потратили. Последние три месяца мы буквально ползали на четвереньках c кисточками и красками, оформляя дома и этажи. Нам хотелось, чтобы детализация была максимальной. Масштаб города получился 1:16 и дома высотой в 9 этажей были примерно на уровне груди взрослого человека. Находясь в этом городе мы ощущали себя настоящими великанами.


image

Немножко о нас

Тут наверное пришло время рассказать о нашей команде. Изначально, нас было всего двое друзей-инженеров. Задумывая проект, мы понимали, что найти инвестора на такую «авантюрную» идею будет сложно и мы приняли решение делать все за свои деньги. В ходе работ нам помогали многие люди. Кто — то бесплатно, кого-то мы нанимали для помощи.


image

Хорошим примером командной работы послужила история с 3D печатью. Мы собрали свой принтер и печатали первое время детали самостоятельно, пока не пришли к выводу, что нельзя быть специалистом во всем. Печать занимала у нас много времени, части деталей были большого размера и неожиданный брак в конце печати детали портил нам все планы. В итоге, мы нашли «узкого» специалиста по 3D печати, который стал в последствии частью нашей команды. Разделив наши мечты, он помогал нам изготавливать корпуса роботов просто по себестоимости пластика.

Собирая роботов, мы не могли так же обойтись без помощи токаря. В этом нам помогал один из друзей. Строительные работы на полигоне требовали зачастую не стандартных и сложных решений, нам очень повезло встретить ребят, которые тоже нам активно помогали в этих вопросах.

Проекту очень повезло с художником оформителем, его талант оказался бесценным.


image

image

image

Чтобы максимально сэкономить на строительстве игровой арены, нам практически все приходилось делать самим. Но кроме большого полигона была еще и техническая часть…


Победа над задержкой видео сигнала

Наверняка вопросы инженерной реализации проекта Вам будут более интересны, чем описание нашего “градостроительства”.

Вернемся к моменту, когда, как Вы помните, мы поставили камеру на “тележку” и смогли ей управлять. Вслед за этим пришла пора выбрать железо и технологии для создания наших роботов. Тут нас ждал первый сюрприз: перебрав десяток камер, мы так и не смогли добиться задержки сигнала при котором управление роботом через интернет было бы комфортным. Все осложнялось временем, которое требовалось, чтобы заказать образцы камер в Китае и их протестировать.


image

Мы хотели сделать систему управления роботами полностью в браузере без всяких «скачайте наш замечательный клиент» и устаревших Flash плееров. Это значительно сузило список технологий и камер, которые их поддерживают. Мы долго экспериментировали с передачей видеопотока в формате MJPEG, но в итоге отказались от этой идеи. Эти эксперименты стоили нам потери полугода времени. Мы даже полностью собрали первых пять роботов и запустили открытое тестирование для всех желающих, но...

Живые тесты показали неспособность роутера обработать огромный видеопоток по радиоканалу от нескольких роботов в формате MJPEG, как только мы не пытались оптимизировать разрешение картинки. Видео поток с одного робота не получалось сделать менее 20-30 МБит, что делало невозможным стабильную одновременную работу планируемых нами 20 роботов. Также мы не смогли найти готового решения передачи звука без задержки. Это привело к тому, что нам пришлось искать заново подходящую для наших задач технологию.

В итоге наш выбор остановился на WebRTC. Это обеспечило нам передачу видео изображения и звука с задержкой всего 0.2 секунды.


image

Дальше пришло время моделировать и собирать роботов. Чтобы меньше зависеть от внешних поставщиков, все детали наших ботов мы печатали на 3D принтере. Это позволило создать нам максимально компактную модель робота, и оптимально поместить внутрь всю электронику и мощные аккумуляторы.


Система электропитания

Следующий вопрос был связан с электропитанием, ведь нам очень хотелось менять аккумуляторы, как можно реже. Перебрав много готовых вариантов, мы остановились на собственном аккумуляторе, собранном из элементов Panasonic 18650B. Батарея напряжением 17 вольт и емкостью 6800 мАч дала возможность нашим роботов ездить фактически по 10-12 часов на одном заряде.


image

В процессе экспериментов мы успешно «угробили» сотню элементов, потому, что нам хотелось использовать емкость элементов максимально, а напряжение в конце разряда падало очень быстро и наш простой индикатор напряжения, собранный на делителе, не всегда давал точные показания. Но в итоге мы подняли порог минимально допустимого напряжения с 2.5 вольт до 3.2, плюс поставили микросхему для точного контроля напряжения и случаи «смерти» Панасоников прекратились.

В качестве зарядных устройств мы выбрали популярные среди моделистов устройства iMax B6 с опцией заряда в режиме балансировки элементов. Часть аккумуляторов мы “угробили” по причине не правильной калибровки китайских копий iMax B6. Мы соединили пять банок и заряжали их в режиме балансировки. В конце заряда проверялось общее напряжение батареи без разбивки на элементы, а фактически одна банка не была заряжена до конца и «умирала» первой.


Двигатели для роботов

Наверняка многие из Вас задали себе вопрос: а почему 17 вольт? Ответ скрывается в моторах. Моторы — это вторая часть наших «китайских мук» после выбора камер. Мы перебрали много разных моторов. К нашему ужасу, почти все они имели маленький ресурс и быстро выходили из строя. Через 3-4 месяца, в ходе экспериментов, нам удалось найти производителя “нормальных” моторов в плане надежности, но финального решения все еще не было.


image

В обычной машине при передаче усилия с двигателя на колеса ключевую роль играет коробка передач. У нас ее не было. Снижая напряжение на моторах, мы успешно снижали скорость робота, но при этом терялась и его мощность и наши «танчики» не могли медленно развернуться на месте. Вскоре мы решили и эту проблему.

Ох, я сказал, это слово — «танчики».


Почему «танчики»?

Почему именно «танчики»? Ответ прост. Если к задержке камеры добавить неизвестную нам задержку Интернет канала, то какой нибудь житель Австралии сможет комфортно управлять только чем-то относительно медленным. Это был первый аргумент в пользу выбора танков, а второй аргумент, который нас убедил окончательно, заключался в комфортном управлении роботом. Человек привык, нажимая на “стрелочку” вправо, ожидать поворота робота вправо, а без гусениц это было невозможно сделать, ведь только танки поворачивают «на месте». Также мы радовались, ожидаемой «супер проходимости». Заказав в Китае ящик резиновых гусениц, мы принялись печатать «колеса-катки» под гусеницы.


image

Первые же тесты разбили наши мечты в «пух и прах», гусеницы частенько слетали с танка при наезде на низкие препятствия. Изучив основы танковой механики и испробовав разные натяжители и вспомогательные колеса, мы все равно не решили эту проблему. С гусеницами пришлось расстаться. Так, как роботы уже были напечатаны и собраны, нам пришлось искать какое-то быстрое и несложное решение, а оно было одно — хорошие колеса с резиновым протектором. И как же поворот на месте спросите Вы? Мы «выкрутились», связав две оси между собой тонким ремешком от 3D принтера. В общем получился колесный робот с полным приводом и поворотом на месте.


image

Сердце робота

Мы рассказали уже о большинстве элементов нашего робота и ничего не сказали о самой важной составляющей.


image

В основу нашего бота «лег» мини компьютер Raspberry Pi на ОС Linux и специально разработанное ПО, которое позволяет общаться роботу с сервером. Raspberry Pi работает совместно с, разработанной нами, платой контроля и управления. Плата включает в себя микроконтроллер, драйвер моторов, микросхемы обработки сигналов с различных датчиков, модуль точного контроля напряжения АКБ. Для удобства сборки? мы реализовали абсолютно все подключения периферии на отдельных разъемах.


image

Как я уже упоминал ранее, нам часто приходилось менять комплектующие? когда мы сталкивались с непредвиденными проблемами. Так получилось и в это раз. Изначально мы собрали первых роботов на Orange Pi, для экономии. В дальнейшим нам пришлось их заменить на Raspberry Pi 2 B. Но и это был не конец. Нам вскоре опять пришлось заменить этот мини компьютер на версию Raspberry Pi 3 B+ которая имела на борту WiFi модуль 5 Ггц. Но об этом далее.


Настройка Wi-Fi

Следующая проблема, которая нас поджидала, заключалась в Wi-Fi радио канале. О ней мы узнали только, начав тесты сразу 10 роботов в движении. Наш полигон располагался в закрытом подвале и «переотраженка» от железобетонных стен была просто ужасной. Команды управления проходили нормально, а вот видеопоток дико «тормозил», стоило одному из роботов уехать в дальний угол помещения.

Справиться с загрузкой канала нам помог переход с 2.4 ГГц на 5 ГГц. Но сложности на этом не закончились. Если робот заезжал за угол, сигнал падал ниже -80 dBm и начинались «тормоза». Окончательно, мы решили проблему, установив секторную антенну с разнесенным приемом и подняв мощность передатчика до полу ватта. Разумеется, роутер пришлось «подобрать» из сегмента бизнес решений с мощным процессором.

Стоит упомянуть, что мы долго пытались вместо увеличения мощности, настроить режим “бесшовного” роуминга на основе решения Ubiquity, но увы, нужный нам модуль Wi-Fi “отказывался “его поддерживать, а вот iPhone работал великолепно, перемещаясь между несколькими точками доступа.


image

Собрав «десяток» роботов и запустив сервер контроля и управления мы в ноябре 2018 года вышли на Кикстартер. Мы даже не догадывались, что нашу игру вскоре попробуют десятки тысяч человек.

О том, что нас ждало дальше и почему мы почти закрыли проект, читайте в нашей следующей статье (скоро): Первая в мире онлайн игра с RC моделями, управляемыми через интернет


image

Let's block ads! (Why?)