Создайте гладкую библиотеку перелистывания страниц формата H5

Байду внешний интерфейс JavaScript HTML CSS

задний план

С ростом популярности мобильных маркетинговых страниц в последние годы родился китайский термин «H5». Наиболее распространенная форма H5 похожа на эффект перелистывания страниц слайда.

Когда нам нужно сделать H5, самый быстрый способ — использовать какую-нибудь скользящую библиотеку подключаемых модулей, например ту, которую производит iDangero.us.Swiper, производство Baidu BE-FEiSlider. Благодаря мощным функциям конфигурации, предоставляемым этими библиотеками перелистывания страниц, мы можем добиться крутых эффектов перелистывания страниц. Конечно, эти библиотеки также поддерживают такие конфигурации, как автовоспроизведение, переключение по щелчку и индикация текущей страницы, поэтому их также можно использовать на веб-страницах для достижения некоторых целей. Эффект веб-карусели.

Байду H5Swiper и iSlider также успешно использовались в качестве среды перелистывания страниц для среды выполнения H5.С увеличением количества пользователей также возникали некоторые проблемы:
1. Платформа H5 плохо совместима с этими библиотеками, некоторые элементы конфигурации недоступны, а некоторые необходимые функции необходимо реализовать "хакерским" способом.
2. Некоторые H5 имеют много элементов и анимаций.При перелистывании страниц на младших моделях будут "заикания" и "залипания" при перелистывании страниц, и пользовательский опыт не очень хороший.

И мы надеемся, что библиотека перелистывания страниц H5 может идеально соответствовать функциям самой платформы, сохраняя при этом небольшой размер, она может быть «гладкой как шелк» при перелистывании страниц. Так мы начали (цзы) бригаду исследований (зао) исследований (лунь).

Начинать

При разработке структуры скользящего экрана H5 первый вопрос: следует ли странице за движением пальца? Это также первый вопрос «Девяти вопросов о практике разработки Sliding Screen H5» от команды Tencent ISUX (первоначальный источник этой статьи теперь 404, вы можете увидеть его на других веб-сайтах перепечатки), вот изображение этой статьи для иллюстрации этой проблемы.

不跟随手指滑动 跟随手指滑动

Левый:Не следуйте за пальцем, правое изображение:Проведите пальцем.

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

Начало

На картинке ниже представлена ​​наиболее интуитивно понятная версия H5, которая следует за движением пальца: все «страницы» последовательно соединяются сверху вниз, от конца к концу. Нужно пояснить, что "страница" здесь в кавычках, потому что на самом деле они всеdiv, упомянутые ниже страницы относятся к этимdiv. В то же время у нас есть пример наиболее распространенного слайда вертикально, горизонтально сочувствие.

swiper-basic.png

Основная схема

Ширина и высота этих дивов 100% высоты контейнера, видимая область средняя часть, слушаемtouchstart, touchmove, touchendСобытия, аналогичные принципу перетаскивания мышью:
1. touchstart, запишите начальную точку;
2. touchmoveРассчитайте расстояние скольжения в режиме реального времени, чтобы все страницы находились вдоль оси Y вместеtranslateэто расстояние.
3. touchendПри можно получить конечное расстояние скольжения и сравнить его с установленным порогом. Войдите в стадию автоматического управления страницей: если она больше порога, пусть страница перейдет на следующую страницу, а если меньше порога, она вернется в исходное положение.

Глубокое погружение

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

Что является узким местом производительности?

Наша цель: в случае «еще три и один низкий» (больше страниц, больше элементов, больше анимаций и низкая конфигурация) при скольжении для перелистывания страниц будет как можно меньше лагов.

Давайте рассмотрим эту проблему в двух частях: до того, как палец покинет экран, и после того, как палец покинет экран.

прежде чем покинуть экран

В настоящее время наиболее ресурсоемкими операциями являются: когдаtouchmoveПри срабатывании вычисляется расстояние, которое нужно переместить,всеВсе страницы должны быть перемещены на одинаковое расстояние по оси Y. На данный момент манипуляции с DOM неизбежны, а манипуляции с DOM очень «дорогие», плюсtouchmoveЕсли событие запускается часто, а обработка производительности недостаточно хороша, легко застрять.

Чтобы оптимизировать производительность, мы, естественно, думаем о стратегии:Уменьшите манипуляции с DOM.

Он состоит из двух частей: элементы, сокращающие манипуляции с DOM, и атрибуты, сокращающие манипуляции с DOM. Например, страница, которую нельзя увидеть, не участвует в анимации. Последний, например, изменяет только одно или несколько свойств css элемента.

Элементы, уменьшающие манипуляции с DOM

В первой простой версии примераtouchmoveПри срабатываниивсеВсе страницы перемещаются по оси Y. На самом деле в этом нет необходимости, потому что значительная часть страницы невидима. Вообще, сколько страниц нам нужно для работы хотя бы? Ответ - два. Напомним, что когда мы прокручиваем, мы можем видеть не более двух страниц одновременно. Этот метод увеличивает производительность в геометрической прогрессии по сравнению со всеми страницами, перемещаемыми вместе.

Атрибуты, уменьшающие манипуляции с DOM

Основное значение этого метода заключается в том, что вам нужно манипулировать DOM только один раз, а не дважды. На самом деле, для анимации слайдов нам просто нужно изменитьtransformЗначение , другие операции DOM (добавление класса, изменение innerHTML элемента) и т. д. не могут быть выполнены.

Получили предварительное решение: при инициализации все страницы помещаются в контейнер одновременно, кроме двух используемых нами страниц,displayсвойства установлены наnone.touchmove, только эти две страницыtransformСвойства изменились.

touchmoveпроцесс, мы можем записать его в виде математического выражения:

s=f(x),x∈[0,sideLength]

x представляет расстояние, на которое скользит палец, s представляет расстояние скольжения страницы, sideLength — это длина текущей скользящей стороны, а если она скользит по оси Y, это высота страницы. Написанное здесь, оно очень похоже на популярную концепцию «управление данными». Все, что нам нужно реализовать, — это функцию рендеринга, ввод — интерактивные данные пользователя, а вывод — представление страницы.

После ухода с экрана

Когда палец покидает экран, мы уже знаем результат этого свайпа (вверх или вниз? перелистывание страницы или отскок?), мы хотим добиться только эффекта анимации, у нас есть два варианта:
Вариант 1: повторное использованиеtouchmoveВизуализация логики, в зависимости от скорости слайда пальца, используйтеrequestAnimationFrameанимация управления;
Вариант 2: Используйте анимацию перехода css3;

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

Эксперимент по производительности анимации

Чтобы сравнить производительность двух схем на анимации перелистывания страниц H5, возьмем чуть более сложный пример:

H5: H5 завербован Baidu беспилотными транспортными средствами
Анимация: листать со страницы 1 на страницу 2.
Процессор: 6 * замедление
Браузер: Chrome 61.0.3163.100 (64-разрядная версия)

js схема анимации:кликните сюда
css схема анимации:кликните сюда

js 动画

js схема анимации перелистывания страниц, результат профиля

css 动画

CSS схема анимации перелистывания страниц, результат профиля

С помощью экспериментов мы можем видеть, что в процессе анимации js частота кадров в основном поддерживается на уровне около 30 кадров в секунду. Анимация CSS в основном составляет около 60 кадров в секунду. И в процессе анимации очевидно, что анимация js застряла. Это особенно актуально для некоторых моделей Android с относительно низкими конфигурациями процессора и видеокарты. Студенты, интересующиеся этим вопросом, могут взглянуть на ветку raf библиотеки swiper, которая является js, используемой в этом сравнительном тесте.

Поэтому, хотя схема анимации js выглядит более «изящной», она может использовать концепцию «управления данными» для унифицированного решения проблем процесса скольжения и процесса анимации. На самом деле есть узкое место в производительности, мы можем использовать схему анимации css только для обеспечения производительности после отрыва пальца от экрана. Это как раз фраза «То, что можно сделать с помощью css, никогда не должно решаться с помощью js».

план реализации

На следующем рисунке наглядно показана основная идея нашей реализации, всего на двух страницах:
currentPage: Текущая страница
activePageследующая страница, которая будет обращена к

Остальные страницы загружаются в структуру DOM при инициализации, ноdisplayзаnoneиz-indexоба0. Здесь отображается состояние «каскадирования» для более яркого отображения.

swiper-basic.png

Схема Swiper

Чтобы облегчить доступ к страницам, мы используем двусвязный список для сохранения структуры страницы. каждыйpageимеютprevиnextуказать на предыдущий и следующийpage.
Нам нужно сосредоточиться на том, как определитьactivePage? То есть следующая страница для перехода. Ответ очень прост, ведь когда пользователь начинает касаться экрана и свайпать, можно определить:
1. Расстояние скольжения x activepage = currentPage.next
2. Расстояние от скольжения X> 0 означает, что страница скользит вниз, в это времяactivepage = currentPage.prev

расширять

эффект перелистывания страниц

Эффект перелистывания страниц в нашем примере является наиболее распространенным эффектом скольжения. Как расширить поддержку куба, флипа и других эффектов? Вы можете вернуться к разделу «до того, как палец покинет экран», мы предлагаем s = f (x), где x — расстояние, на которое пользователь провел пальцем, а s — расстояние, на которое пролистнул страницу. Мы можем расширить s, чтобы стать «угол переворота страницы» или «коэффициент масштабирования страницы», чтобы поддерживать другие эффекты.

На самом деле, когда мы скользим, мы используем сам css3.transformатрибут, который будетtranslate, rotate, scaleПравильная комбинация может создавать постоянно меняющиеся эффекты перелистывания страниц.

более приятная анимация

Это относится к функции времени анимации, взяв в качестве примера простейший эффект скольжения. Если это линейная функция, скорость, с которой пользователь скользит, всегда равна скорости, с которой скользит страница. «Ощущение» должно быть более гладким и чувствительным: в начале скорость скольжения страницы выше, чем скорость скольжения пользователя. Когда страница переворачивается, они становятся одинаковыми. После определенного момента страница скользит на единицу. Скорость начинает постепенно уменьшаться по сравнению со скоростью скольжения пользователя, и скорость выражается как расстояние, а связь между x и s может быть получена следующим образом:

swiper-basic.png
График x и s (x по горизонтальной оси, s по вертикальной оси)

Здесь я должен упомянуть еще две схемы анимации: анимацию js и анимацию css.

Одним из преимуществ схемы анимации js является то, что вы можете точно контролировать ход анимации, что невозможно с помощью css. Например, когда пользователь покидает экран, когда x = 0,8, из-за того же используемого рендеринга js может знать, что x находится в позиции 0,8, когда палец покидает экран Следующая анимация завершается requestAnimationFrame, и весь процесс гладкий и полный.

И css анимация отличается, css анимация устанавливается только до начала анимацииanimation-timing-function, когда пользователь покидает экран при x = 0,8, исходный процесс скольжения, управляемый js, прерывается, и для завершения остальной части анимации используется css, css не может быть динамически рассчитан в соответствии с моментом, когда палец покидает экранanimation-timing-function, поэтому в точке соединения их скорость не совпадает, что повлияет на общий эффект анимации.

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

Резюме и перспективы

В этой статье описываются некоторые проблемы, возникшие при разработке «гладкой как шелк» библиотеки перелистывания страниц H5, и соответствующие решения. После того, как базовая модель скользящего перелистывания страниц установлена, она фокусируется на вопросах производительности, которые подразделяются напрежде чем покинуть экраниПосле ухода с экранадва этапа. Предыдущий этап в основном был сосредоточен на уменьшении манипуляций с DOM. Последний этап фокусируется на производительности анимации и сравнивает данные о производительности js-анимации и css-анимации и, наконец, делает вывод, что css-анимация используется после того, как палец покидает экран. Кроме того, мы также основываемся на идее «управляемой данными», вэффект перелистывания страницифункция анимацииДве части были расширены, функции библиотеки перелистывания страниц были расширены, а Эффект отображения H5.

В этой статье я пытаюсь объяснить весь процесс с помощью идеи, основанной на данных, но из-за проблем с производительностью я могу лишь временно отказаться от нее и надеюсь найти лучшее решение в будущем. Из-за ограниченного уровня в тексте неизбежно будут ошибки.Приглашаем всех критиковать и исправлять, учиться и развиваться вместе. благодарныйSwiperиisliderВдохновение от библиотеки перелистывания страниц, особая благодарность и@Ronnyбурное обсуждение.

Здесь адрес банка swiper:GitHub.com/post-ex-team/так называемые…. Код, используемый в основной ветке, в настоящее время используется онлайн Baidu H5. Ветка raf — это упомянутая в статье схема js-анимации.