Не отправляйте устаревший код javascript в современные браузеры
Особенно это важно в эпоху адаптивного веб-дизайна, когда на первый план выходит способность front-end адаптироваться к широкому диапазону различных устройств и при этом обеспечивать оптимальное качество просмотра.
Раньше дизайнер создавал макет дизайна в Photoshop , который затем переносился в HTML и CSS . На сегодняшний день технологические изменения заставляют переосмыслить эту концепцию. Мы больше не можем предсказать, какой браузер, разрешение или устройство будут использоваться для просмотра сайта. Ушли в прошлое те времена, когда большинство компьютеров использовало фиксированное разрешение 1024 на 768 пикселей, и можно было разрабатывать сайты со статическими размерами.
В данной статье мы рассмотрим текущую статистику по просмотрам веб-страниц, приведем перечень средств, которые помогают решать различные проблемы совместимости.
Текущая ситуация
Общемировая статистика за 2015 год показывает, что топ-14 используемых разрешений экрана находятся в диапазоне от 1920 на 1080 до 320 на 480 пикселей.
Хотя Windows 7 ( 31,20% ) до сих пор удерживает большую долю рынка, мобильные платформы начинают заменять традиционные, стационарные.
Github больше не поддерживает IE 7 и 8 . Кроме этого часть функционала Twitter не работает в IE8 . И, наконец, популярный фреймворк не будет поддерживать IE8 , начиная с 4 версии .
Тем не менее, статистика использования может варьироваться в зависимости от региона: 6,11% пользователей в Китае в 2015 году по-прежнему просматривали страницы через IE8 . Если принять во внимание, что в Китае было около 724400000 интернет-пользователей, можно понять, что в этом году примерно 44200000 китайцев продолжают использовать IE8 .
Поэтому региональные рынки, специфические клиенты и требования отрасли могут существенно отличаться. Особенно это касается корпоративных и правительственных учреждений.
Проанализируйте свою аудиторию
Основной принцип здесь такой: чем выше требуемая кроссбраузерность, тем больше времени потребуется на разработку, что приводит к увеличению стоимости проекта. Чтобы принять взвешенное, экономически обоснованное решение, нужно задать себе следующие вопросы:
- Какова ваша целевая аудитория?
- На какой географический регион нужно настроить таргетинг?
- Какие браузеры и устройства используют ваши посетители?
- Существуют ли в компании или отрасли технические факторы, которые заставляют вас поддерживать конкретные версии старых браузеров?
- Каковы с точки зрения электронной коммерции коэффициенты конверсии и рентабельности различных групп пользователей по версиям браузеров?
Ответив на эти вопросы с помощью статистических данных, например, из Google Analytics , можно получить объективную картину.
Проблемы в устаревших браузерах и различные подходы к разработке
Адаптивный веб-дизайн во многом зависит от медиа-запросов, с помощью которых изменяется CSS для различных разрешений экрана. Кроме этого современные сайты характеризуются использованием семантических элементов HTML5 (например, <header>, <nav>, <section>, <aside>, <footer>) для группировки компонентов дизайна. Селекторы CSS3 используются для выбора конкретных элементов и дальнейшего назначения стилей (например, [attribute*=value] , :checked , :nth-child(n) , :not(selector) , :last-child)) . И, наконец, адаптивная типографика часто задается с помощью единиц REM ( root em ).
Это подводит нас к следующим техническим сложностям при реализации CSS кроссбраузерности:
- Медиа-запросы CSS3 : не поддерживается в IE6 , 7 и 8 ;
- Семантические элементы HTML5 : не поддерживается в IE6 , 7 и 8 ;
- Селекторы CSS3 : не поддерживается в IE6 . Только частично поддерживаются в IE7 и 8 ;
- Единицы REM : не поддерживается в IE6 , 7 и 8 . Только частично поддерживаются в IE9 и 10 ;
- Лимит количества правил CSS : IE9 и ниже поддерживают только 4095 CSS-селекторов . Правила после 4095-ого селектора не применяются.
Указанные выше ошибки будут иметь наибольшее влияние на стратегию, применяемую при реализации адаптивного дизайна.
Существуют две основных стратегии разработки: постепенное упрощение и прогрессивное улучшение .
С другой стороны, пользователям старых браузеров и медленного интернет-соединения будет предлагаться графически усеченная, но все еще функциональная версия сайта.
Подобный подход при реализации кроссбраузерности предполагает начало разработки с простой версии, к которой затем добавляются более сложные элементы. Старые браузеры смогут отображать сайт с базовым уровнем опыта взаимодействия. А новые функции HTML / CSS / JavaScript будут доступны в браузерах, которые могут реально их использовать.
В противоположность этому, постепенное упрощение обеспечивает полнофункциональный уровень UX в современных браузерах. А затем постепенно уменьшает его сложность для старых браузеров за счет графики, но, не касаясь функционала. Идея заключается в том, чтобы начать разработку с новейших веб-стандартов, а затем попытаться минимизировать проблемы, связанные со старыми браузерами.
Какой подход выберете вы, зависит от личных предпочтений и условий проекта:
- Прогрессивное улучшение обеспечивает большую стабильность, так как вы можете постепенно добавлять новые функции для современных браузеров. Но оно требует более тщательного планирования;
- Некоторые разработчики утверждают, что нет смысла поддерживать устаревшие браузеры и должны использоваться новейшие технологии. Поддержка современных браузеров дает намного лучший опыт взаимодействия;
- Существует мнение, что прогрессивное улучшение мертво, так как множество JavaScript-приложений не работают надлежащим образом при этом подходе;
- Веб-доступность для общественных учреждений может быть определена в юридических требованиях конкретных территориальных образований, и это может повлечь необходимость применения особого подхода.
Учитывая появление таких инструментов для определения функций, как Modernizr , лично я склоняюсь к использованию постепенного упрощения и черного списка браузеров при разработке совместимых сайтов.
Чтобы как можно скорее обнаружить потенциальные проблемы кроссбраузерности JavaScript , нужно в процессе разработки тестировать сайт в различных браузерах и разрешениях. Существуют различные программные эмуляторы, которые могут нам помочь:
Normalize.css и CSS Autoprefixer
Обычно я начинаю новые проекты в CDN со сброса CSS с помощью Normalize.css , который обеспечивает лучшую кроссбраузерность при определении стилей HTML-элементов , используемых по умолчанию, вплоть до Internet Explorer 8 . Normalize.css сохраняет нужные стили элементов, нормализует их внешний вид и исправляет ряд ошибок и несоответствий в различных браузерах.
Кроме этого многие устаревшие браузеры не могут интерпретировать неизвестные элементы HTML и свойства CSS . Когда браузер встречает фрагмент HTML или CSS , который он не понимает, то игнорирует его и продолжает процесс отображения. Многие приложения используют вендорные префиксы, чтобы добавить новые, экспериментальные или нестандартные функции CSS до их реализации в спецификации:
Проблема заключается в том, что префиксы неудобны в использовании и с ними связано много ошибок. Поэтому я использую плагин CSS Autoprefixer в сочетании с Grunt .
В качестве примера рассмотрим следующий класс CSS :
С помощью CSS Autoprefixer он преобразуется в:
Условные комментарии
Если нужно создать резервный CSS или включить кроссбраузерность JavaScript для ранних версий Internet Explorer , то можете использовать условные комментарии . Они поддерживаются в Internet Explorer 5-9 , они используют синтаксис комментариев HTML в сочетании с логическими значениями. В зависимости от логического значения ( true или false ) код внутри тегов комментариев будет выводиться или скрываться в соответствующих версиях браузера:
Код автоматически скрывается во всех браузерах, не поддерживающих условные комментарии. Наглядным примером того, как условные комментарии могут быть эффективно использованы на практике, является HTML5 Boilerplate , который добавляет специфические классы CSS для устаревших версий Internet Explorer :
Полифиллы
Ниже приведено несколько полифиллов, предназначенных для устранения проблем кроссбраузерности сайта, указанных в пункте 3:
Для использования указанных полифиллов, их нужно добавить из CDN или в виде файла в корректном формате внутри условных комментариев в разделе <head> (не забудьте включить одну из необходимых для Selectivizr библиотек JavaScript ):
Определение функций с помощью Modernizr
Библиотека Modernizr , написанная на JavaScript , поможет проверить кроссбраузерность сайта: поддерживается ли в различных браузерах конкретная функция HTML5 или CSS3 . Если функция не доступна, то может быть загружен альтернативный CSS или JavaScript-код .
Идея заключается в том, чтобы напрямую определять функциональные возможности браузера, а не пытаться установить его конкретную версию. И на основании этого выводить его функциональные возможности, что является менее эффективным и надежным способом.
Стоит отметить, что Modernizr не добавляет недостающие функции в браузер. Поэтому вам нужно будет предоставить код из резервного CSS или полифилла.
Для начала необходимо скачать полнофункциональную сборку. Позже, когда вы будете готовы к разработке, можно создать пользовательскую сборку со специфическими функциями, которые вы тестируете. Все, что нужно сделать, это добавить класс .no-js в HTML-тег сайта и включить скрипт Modernizr в разделе head после любого CSS-файла :
Класс .no-js используется, чтобы проверить, включен ли JavaScript в браузере пользователя. Если он включен, Modernizr заменит .no-js классом .js . Функция тестирования Modernizr анализирует, поддерживается ли в браузере конкретная функция и генерирует ряд классов, которые добавляются в HTML-элемент . Google Chrome 47.0.2526.111 , например, будет возвращать следующие классы объектов.
В настоящее время Modernizr доступен в качестве глобального объекта, который можно вызвать в сочетании с названием функции, чтобы проверить существует ли она. Он возвращает логическое значение ( true или false ).
Рассмотрим два простых примера CSS и JavaScript .
Пример решения проблем CSS кроссбраузерности: проверка поддержки SVG и предоставление в качестве резервного варианта PNG
Пример JavaScript: определение border-radius и добавление соответствующих классов CSS
Округление углов рамки не поддерживается в IE8 и ниже. Мы можем создавать различные CSS-классы , которые применяются в зависимости от наличия функции border-radius :
Теперь можно использовать JavaScript , чтобы сохранить целевой идентификатор в качестве переменной, а затем через условие добавить классы CSS :
Заключение
Когда речь идет об адаптивном веб-дизайне в устаревших браузерах, не существует какого-то универсального решения. Важно проанализировать аудиторию ресурса, чтобы получить представление о реальной численности пользователей браузеров. Затем нужно тщательно протестировать сайт, чтобы выявить потенциальные проблемы кроссбраузерности.
Тщательно выбирая правильные полифиллы, добавляемые в условных комментариях, можно обойти отсутствие наиболее существенных функций HTML5 . Кроме этого возможность определения с помощью Modernizr является удобным способом предоставить резервные CSS и JavaScript для устаревших браузеров, в которых отсутствует поддержка современного функционала HTML5 и CSS3 .
Дайте знать, что вы думаете по данной теме материала в комментариях. Мы очень благодарим вас за ваши комментарии, подписки, лайки, отклики, дизлайки!
Пожалуйста, опубликуйте ваши комментарии по текущей теме статьи. За комментарии, отклики, дизлайки, лайки, подписки огромное вам спасибо!
google speed test (Сократите глубину вложенности критических запросов)
PageSpeed Insights ругается на оптимизацию, не могу найти причину такого показателя
PageSpeed Insights Ругается на ужасный показатель, причину того найти не могу, сжал изображения насколько это было возможно с 50 до 9мб, убрал лишний код и подключения, в чем может быть проблема, .
Ошибка PageSpeed Insights: Тайм-аут при получении основного ресурса
Оптимизировал сайт, следуя рекомендациям Google, добился показателя 94/96 в PageSpeed Insights. Но сейчас, когда пробую проверить сайт через этот сервис, выдается ошибка: "Тайм-аут при получении .
Nginx Pagespeed нестабильные показатели
Существует сервер, на нём связка nginx -> apache -> fastcgi-php. Nginx скомпилирован с последним модулем pagespeed (ngx_pagespeed 1.12.34.2-0). На сервере крутится несколько сайтов, для всех хочется .
Удалить js скрипты на мобильной версий
Cumulative Layout Shift (CLS) выдает ошибку даже на пустой html файл
Подскажите на что конкретно гугл ругается? Файл абсолютно пустой, нет css, нет js, нет картинок, и нет абсолютно никакого смещения контента, ничего внешнего не подключается
Оптимизация скорости загрузки сайта, в режиме 3g не до конца загружается страница
Не работает PageSpeed
При попытке проверить скорость загрузки сайта вылетает ошибка Lighthouse returned error: PROTOCOL_TIMEOUT. Истекло время ожидания ответа от протокола DevTools. Метод: Runtime.evaluate. (.
Laravel Mix 2 создать 2 версии файла
В PageSpeed Insights появилась новая метрика "Не отправляйте устаревший код JavaScript в современные браузеры" …frontend/item.js?v=1.11.71 6,0 KiB …frontend/item.js?v=1.11.71:1:190879 @.
Как оптимизировать CLS (Google Page Speed)?
Есть несколько страниц, где никудышный показатель CLS в Google Page Speed. Контент на страницах - текст, изображение, много текста. Изображения на разных страницах могут быть разного разрешения. Кроме .
5,240 1 1 золотой знак 7 7 серебряных знаков 28 28 бронзовых знаков
Оценка скорости сайта без учета скриптов "яндекс-метрики"
На данный момент пытаюсь повысить скорость загрузки главной страницы сайта, оценку изменений произвожу через Google PageSpeed и Performance в консоли Chrome. Но результаты сильно разнятся от теста к .
Как сжать полупрозрачное изображение для прохождения рекомендаций по Pagespeed?
При оптимизации сайта в Pagespeed получаю предупреждение: "Настройте подходящий размер изображений" - потенциальная экономия 0,46с и "Используйте современные форматы изображений".
4,274 6 6 золотых знаков 29 29 серебряных знаков 74 74 бронзовых знака
Не включается сжатие текстовых ресурсов по рекомендации PageSpeed Insights
1,504 3 3 золотых знака 19 19 серебряных знаков 34 34 бронзовых знака
Оптимизация кеша для статических объектов
Передать нужный код для каждого браузера – непростая задача.
В этой статье рассмотрим несколько вариантов, как эту задачу можно решить.
Передача современного кода современным браузером может очень сильно повысить производительность. Ваши JavaScript-пакеты смогут содержать более компактный или оптимизированный современный синтаксис и поддерживать старые браузеры.
Среди инструментов для разработчиков доминирует паттерн module/nomodule декларативной загрузки современного или legacy-кода, который предоставляет браузерам источники и позволяет решать, какие из них использовать:
К сожалению, не всё так просто. Показанный выше подход на основе HTML инициирует перезагрузку скриптов в Edge и Safari.
Что можно сделать?
В зависимости от браузера нам нужно доставить один из вариантов скомпилированных скриптов, но пара старых браузеров не поддерживают весь необходимый для этого синтаксис.
Во-первых, есть Safari Fix. Safari 10.1 поддерживает JS-модули, а не атрибут nomodule в скриптах, что позволяет ему исполнять и современный, и legacy-код. Однако нестандартное событие beforeload , поддерживаемое Safari 10 & 11, можно использовать для полифиллинга nomodule .
Способ первый: динамическая загрузка
Можно обойти эти проблемы, реализовав маленький загрузчик скриптов. Аналогично тому, как работает LoadCSS. Вместо того, чтобы надеяться на реализацию в браузерах ES-модулей и атрибута nomodule , можно попытаться выполнить модульный скрипт в качестве «проверки лакмусовой бумажкой», а на основании результата выбрать загрузку современного или legacy-кода.
Но при таком подходе необходимо дождаться выполнения «лакмусового» модульного скрипта, прежде чем внедрять правильный скрипт. Это происходит, потому что <sсript type="module"> всегда работает асинхронно. Но есть способ получше!
Можно реализовать независимый вариант, проверяя, поддерживается ли nomodule в браузере. Это означает, что мы будем рассматривать браузеры вроде Safari 10.1 как устаревшие, даже если они поддерживают модули. Но это может быть к лучшему. Вот соответствующий код:
Это можно быстро превратить в функцию, которая загружает современный или legacy-код, а также обеспечивает асинхронность их загрузки:
Какой же здесь компромисс?
Предварительная загрузка
Поскольку решение полностью динамическое, браузер не сможет обнаружить наши JavaScript-ресурсы до тех пор, пока не запустит загрузочный (bootstrapping) код, который мы написали для вставки современных или legacy-скриптов. Обычно браузер сканирует HTML в поисках ресурсов, которые он может загрузить заранее. Эта проблема решается, но не идеально: можно с помощью <link rеl=modulеpreload> предварительно загружать современную версию пакета в современных браузерах.
К сожалению, пока что только Chrome поддерживает modulepreload .
Вот как это решение может выглядеть в эксплуатации:
Также нужно отметить, что список браузеров, поддерживающих JS-модули, почти аналогичен тем, которые поддерживают <link rеl=preload> . Для каких-то сайтов может быть целесообразным использование <link rеl=preload as=script crossorigin> вместо modulepreload . Производительность может ухудшиться, поскольку классическая предварительная загрузка скриптов не подразумевает равномерного выполнения парсинга с течением времени, как в случае с modulepreload .
Способ второй: отслеживание User Agent
У меня нет подходящего примера кода, поскольку отслеживание User Agent — задача нетривиальная. Но зато вы можете почитать прекрасную статью в Smashing Magazine.
По сути всё начинается с того же <scriрt src=bundle.js> в HTML для всех браузеров. Когда запрашивается bundle.js, сервер парсит строку User Agent запрашивающего браузера и выбирает, какой JavaScript возвращать — современный или legacy, в зависимости от того, как был распознан браузер.
- Поскольку требуются умные серверы, этот подход не будет работать в условиях статического развёртывания (генераторы статических сайтов, Netlify и т.д.).
- Кэширование для этих JavaScript URL теперь зависит от User Agent, который очень изменчив.
- Определение UA затруднено и может приводить к ложной классификации.
- Строку User Agent легко спуфить, и каждый день появляются новые UA.
Для сайтов, которые уже генерируют HTML на сервере в ответ на каждый запрос, это может быть эффективным переходом к загрузке современных скриптов.
Способ третий: штрафуем старые браузеры
Негативный эффект паттерна module/nomodule виден в старых версиях Chrome, Firefox и Safari — их количество очень невелико, поскольку браузеры обновляются автоматически. С Edge 16-18 ситуация иная, но есть надежда: новые версии Edge будут использовать движок отрисовки на основе Chromium, который не имеет таких проблем.
Для некоторых приложений это было бы идеальным компромиссом: загружать современную версию кода в 90 % браузеров, а в старые — отдавать legacy-код. Нагрузка в старых браузерах повысится.
К слову, ни один из User Agent’ов, для которых такая перезагрузка является проблемой, не занимают значимую долю мобильного рынка. Так что источником всех этих лишних байтов вряд ли будут мобильные устройства или устройства со слабым процессором.
Если вы создаёте сайт, к которому обращаются в основном мобильные или свежие браузеры, то для большинства этих пользователей подойдёт простейший вид паттерна module/nomodule. Только удостоверьтесь, что вы добавили фикс Safari 10.1, если к вам заходят более старые iOS-устройства.
Способ четвёртый: применяйте условия использования пакетов
Хорошим решением будет использовать nomodule для условной загрузки пакетов с кодом, который не нужен в современных браузерах, например, с полифиллами. При таком подходе в худшем случае полифиллы будут загружены или даже выполнены (в Safari 10.1), но эффект от этого будет ограничен «переполифиллингом». Учитывая, что сегодня преобладает подход с загрузкой и выполнением полифиллов во всех браузерах, это может быть достойным улучшением.
Можно сконфигурировать Angular CLI для использования этого подхода с полифиллами, как продемонстрировал Минко Гечев. Узнав об этом подходе, я понял, что можно включить автоматическую инъекцию полифиллов в preact-cli — этот PR демонстрирует, насколько легко можно внедрить эту методику.
А если вы используете WebPack, то есть удобный плагин для html-webpack-plugin , который облегчает добавление nomodule в пакеты с полифиллами.
Так что же выбрать?
Ответ зависит от вашей ситуации. Если вы создаёте клиентское приложение, и ваш HTML содержит чуть больше, чем <sсript> , то вам может потребоваться первый способ.
Если вы создаёте сайт, который отрисовывается на сервере, и можете позволить себе кэширование, то вам может подойти второй способ.
Если вы используете универсальный рендеринг, выигрыш в производительности, предлагаемый сканированием до загрузки, может оказаться очень важным. Поэтому обратите внимание на третий или четвёртый способы. Выбирайте то, что подходит для вашей архитектуры.
Лично я выбираю, ориентируясь на длительность парсинга на мобильных устройствах, а не на стоимость загрузки в десктопных версиях. Мобильные пользователи воспринимают парсинг и расходы на передачу данных как фактические расходы (расход заряда батареи и плату за передачу данных), тогда как пользователи десктопа не имеют таких ограничений. Также я исхожу из оптимизации под 90% пользователей — основная аудитория моих проектов пользуется современными и/или мобильными браузерами.
согласно MDN, мы должны определенно не использовать .свойство keyCode. Он устарел:
в школах w3 этот факт воспроизводится, и есть только боковая нота, говорящая, что .keyCode предоставляется только для совместимости и что последняя версия спецификации событий DOM рекомендует использовать .key собственность вместо.
проблема в том, что .key не поддерживаются браузерами, так что мы должны использовать? Я что-то упускаю?
вы должны рассмотреть их, это правильный путь, если вы хотите поддержку кросс-браузера.
Это может быть легче, если вы реализуете что-то вроде этого.
MDN уже предоставил решение:
кроме того, что все код, , который, аргументом charcode и keyIdentifier не рекомендуется :
charCode и keyIdentifier нестандартные особенности.
keyIdentifier удаляется с Chrome 54 и Opera 41.0
keyCode возвращает 0, на событие нажатия клавиши с обычными символами на FF.
содержит соответствующее значение ключевого атрибута к клавише нажата
на момент написания этой статьи key свойство поддерживается всеми основными браузерами: Firefox 52, Chrome 55, Safari 10.1, Opera 46. Кроме Internet Explorer 11, который имеет : нестандартные идентификаторы ключей и неправильное поведение с AltGraph. Подробнее
Если это важно и / или обратная совместимость, то вы можете использовать обнаружение функций, как в следующем коде :
заметил, что key значение отличается от keyCode или which свойства : содержит имя ключа, а не его код. Если вашей программе нужны коды символов, вы можете использовать charCodeAt() . Для отдельных печатаемых символов вы можете использовать charCodeAt() , если вы имеете дело с ключами, значения которых содержат несколько символов, таких как ArrowUp скорее всего: вы тестируете специальные ключи и предпринимаете соответствующие действия. Поэтому постарайтесь реализации таблица значений ключей и соответствующих им коды charCodeArr["ArrowUp"]=38 , charCodeArr["Enter"]=13 , charCodeArr[Escape]=27 . и так далее, пожалуйста, взгляните на Ключевые Значения и соответствующие коды
может быть, вы хотите рассмотреть возможность прямой совместимости i.e используйте устаревшие свойства, пока они доступны, и только при удалении переключитесь на новые :
TLDR: я бы посоветовал вам должны использовать новый event.key и event.code свойства вместо устаревших. IE и Edge поддерживают эти свойства, но пока не поддерживают новые имена ключей. Для них есть небольшой полифилл, который заставляет их выводить стандартные имена ключей / кодов:
Я пришел к этому вопросу в поисках причины того же MDN предупреждение как OP. После поиска еще немного, проблема с keyCode становится более ясной:
проблема с использованием keyCode что не-английские клавиатуры могут произвести различные выходы и даже клавиатуры с различными планами могут произвести несогласованные результаты. Кроме того, был случай
на практике, keyCode и charCode непоследовательны на разных платформах и даже одна и та же реализация в разных операционных системах или с использованием разных локализаций.
эти функции никогда официально не указывались, и текущие реализации браузера существенно различаются. Большой объем устаревшего контента, включая библиотеки сценариев, которые полагаются на обнаружение агента пользователя и соответствующие действия, означают, что любая попытка формализовать эти устаревшие атрибуты и события будет рисковать сломать столько контента, сколько это исправит или позволит. Кроме того, эти атрибуты не подходят для международного использования и не касаются проблем доступности.
Итак, после установления причины, по которой был заменен устаревший код ключа, давайте посмотрим, что вам нужно сделать сегодня:
делай то, что я делаю. Мне просто все равно. MDN может сказать, что он устарел, но если они не предоставляют альтернативу (за исключением keyIdentifier), то вы должны использовать устаревшую версию.
Читайте также: