Nada pior ao cozinhar com um dispositivo móvel do que a tela desligando no meio de uma etapa da receita. Saiba como o site de culinária BettyCrocker.com usou a API Wake Lock para evitar isso.
Por quase um século, a Betty Crocker foi a fonte de instruções modernas de culinária e de desenvolvimento de receitas confiáveis nos Estados Unidos. Lançado em 1997, o site BettyCrocker.com hoje recebe mais de 12 milhões de visitantes por mês. Depois de implementar a API Wake Lock, os indicadores de intenção de compra foram cerca de 300% maiores para usuários do recurso em comparação com todos os usuários.
Os apps para iOS e Android desativados
Lançado com muito alarde em 2014, a Betty Crocker removeu recentemente os apps da Apple App Store e da Google Play Store depois que eles perderam a prioridade. Por muito tempo, a equipe da Betty Crocker preferiu adicionar novos recursos ao site para dispositivos móveis em vez de apps para iOS/Android. A plataforma técnica em que os apps iOS/Android foram criados estava desatualizada, e a empresa não tinha recursos para atualizar e manter os apps no futuro. O app da Web também era objetivamente muito maior em termos de tráfego, mais moderno e mais fácil de aprimorar.
No entanto, os apps para iOS/Android tinham um recurso incrível que os usuários adoravam:
Dica de culinária para millennials: o app para dispositivos móveis @BettyCrocker não fica escuro nem bloqueia quando você está seguindo uma receita. —@AvaBeilke
80% das pessoas cozinham com um dispositivo na cozinha, mas o escurecimento e o bloqueio da tela são um problema. O que @BettyCrocker fez? O app foi atualizado para NÃO ficar escuro quando os usuários estão em uma receita. —@KatieTweedy
Como trazer o recurso mais importante para a Web com a API Wake Lock
Ao cozinhar com um dispositivo, não há nada mais frustrante do que tocar na tela com as mãos sujas ou até mesmo com o nariz quando a tela desliga. Betty Crocker se perguntou como poderia transferir o recurso mais importante dos apps iOS/Android para o app da Web. Foi quando ela soube do Project Fugu e da API Wake Lock.
A API Wake Lock oferece uma maneira de impedir que o dispositivo desative ou bloqueie a tela. Esse recurso permite novas experiências que, até agora, exigiam um app iOS/Android. A API Wake Lock reduz a necessidade de soluções alternativas hackeadas e potencialmente com alto consumo de energia.
Solicitar um wake lock
Para solicitar um bloqueio de ativação, chame o método navigator.wakeLock.request()
que retorna um objeto WakeLockSentinel
. Você vai usar esse objeto como um
valor de sentinela.
O navegador pode recusar a solicitação por vários motivos
(por exemplo, porque a bateria está muito baixa).
Portanto, é uma boa prática agrupar a chamada em uma instrução try…catch
.
Como liberar um wake lock
Você também precisa de uma maneira de liberar um bloqueio de ativação,
que é alcançado chamando o método release()
do objeto WakeLockSentinel
.
Se você quiser liberar automaticamente a trava de ativação após um determinado período,
use window.setTimeout()
para chamar release()
, conforme mostrado no exemplo abaixo.
// The wake lock sentinel.
let wakeLock = null;
// Function that attempts to request a wake lock.
const requestWakeLock = async () => {
try {
wakeLock = await navigator.wakeLock.request('screen');
wakeLock.addEventListener('release', () => {
console.log('Wake Lock was released');
});
console.log('Wake Lock is active');
} catch (err) {
console.error(`${err.name}, ${err.message}`);
}
};
// Request a wake lock…
await requestWakeLock();
// …and release it again after 5s.
window.setTimeout(() => {
wakeLock.release();
wakeLock = null;
}, 5000);
A implementação
Com o novo app da Web, os usuários podem navegar facilmente por uma receita, concluir etapas e até mesmo sair sem que a tela seja bloqueada. Para alcançar esse objetivo, a equipe primeiro criou um protótipo de front-end rápido como prova de conceito e para coletar informações de UX.
Depois que o protótipo se mostrou útil, eles projetaram um componente Vue.js que poderia ser compartilhado em todas as marcas (BettyCrocker, Pillsbury e Tablespoon). Embora apenas a Betty Crocker tivesse apps para iOS e Android, os três sites têm uma base de código compartilhada, então eles puderam implementar o componente uma vez e implantá-lo em todos os lugares, conforme mostrado nas capturas de tela abaixo.
Ao desenvolver o componente com base no framework modernizado do novo site,
o foco foi na
camada ViewModel
do padrão MVVM.
A equipe também programou pensando na interoperabilidade
para permitir a funcionalidade em frameworks legados e novos do site.
Para acompanhar a visibilidade e a usabilidade, a Betty Crocker integrou o acompanhamento de análise para eventos principais no ciclo de vida do bloqueio de tela. A equipe usou o gerenciamento de recursos para implantar o componente de bloqueio de tela em um único site para o lançamento inicial da produção e, em seguida, implantou o recurso no restante dos sites após monitorar o uso e a integridade da página. Eles continuam monitorando os dados de análise com base no uso desse componente.
Como um recurso de segurança para os usuários, a equipe criou um tempo limite forçado para desativar o wakelock após uma hora de inatividade. A implementação final que eles escolheram foi, no curto prazo, um botão de alternância em todas as páginas de receitas nos sites. No longo prazo, eles imaginam uma visualização de página de receita reformulada.
O contêiner do wake lock
var wakeLockControl = () => {
return import(/* webpackChunkName: 'wakeLock' */ './wakeLock');
};
export default {
components: {
wakeLockControl: wakeLockControl,
},
data() {
return {
config: {},
wakeLockComponent: '',
};
},
methods: {
init: function(config) {
this.config = config || {};
if ('wakeLock' in navigator && 'request' in navigator.wakeLock) {
this.wakeLockComponent = 'wakeLockControl';
} else {
console.log('Browser not supported');
}
},
},
};
O componente do wake lock
<template>
<div class="wakeLock">
<div class="textAbove"></div>
<label class="switch" :aria-label="settingsInternal.textAbove">
<input type="checkbox" @change="onChange()" v-model="isChecked">
<span class="slider round"></span>
</label>
</div>
</template>
<script type="text/javascript">
import debounce from 'lodash.debounce';
const scrollDebounceMs = 1000;
export default {
props: {
settings: { type: Object },
},
data() {
return {
settingsInternal: this.settings || {},
isChecked: false,
wakeLock: null,
timerId: 0,
};
},
created() {
this.$_raiseAnalyticsEvent('Wake Lock Toggle Available');
},
methods: {
onChange: function() {
if (this.isChecked) {
this.$_requestWakeLock();
} else {
this.$_releaseWakeLock();
}
},
$_requestWakeLock: async function() {
try {
this.wakeLock = await navigator.wakeLock.request('screen');
//Start new timer
this.$_handleAbortTimer();
//Only add event listeners after wake lock is successfully enabled
document.addEventListener(
'visibilitychange',
this.$_handleVisibilityChange,
);
window.addEventListener(
'scroll',
debounce(this.$_handleAbortTimer, scrollDebounceMs),
);
this.$_raiseAnalyticsEvent('Wake Lock Toggle Enabled');
} catch (e) {
this.isChecked = false;
}
},
$_releaseWakeLock: function() {
try {
this.wakeLock.release();
this.wakeLock = null;
//Clear timer
this.$_handleAbortTimer();
//Clean up event listeners
document.removeEventListener(
'visibilitychange',
this.$_handleVisibilityChange,
);
window.removeEventListener(
'scroll',
debounce(this.$_handleAbortTimer, scrollDebounceMs),
);
} catch (e) {
console.log(`Wake Lock Release Error: ${e.name}, ${e.message}`);
}
},
$_handleAbortTimer: function() {
//If there is an existing timer then clear it and set to zero
if (this.timerId !== 0) {
clearTimeout(this.timerId);
this.timerId = 0;
}
//Start new timer; Will be triggered from toggle enabled or scroll event
if (this.isChecked) {
this.timerId = setTimeout(
this.$_releaseWakeLock,
this.settingsInternal.timeoutDurationMs,
);
}
},
$_handleVisibilityChange: function() {
//Handle navigating away from page/tab
if (this.isChecked) {
this.$_releaseWakeLock();
this.isChecked = false;
}
},
$_raiseAnalyticsEvent: function(eventType) {
let eventParams = {
EventType: eventType,
Position: window.location.pathname || '',
};
Analytics.raiseEvent(eventParams);
},
},
};
</script>
Resultados
O componente Vue.js foi implantado nos três sites e apresentou ótimos resultados. No período de 10 de dezembro de 2019 a 10 de janeiro de 2020, o site BettyCrocker.com registrou as seguintes métricas:
- De todos os usuários da Betty Crocker com um navegador compatível com a API Wake Lock, 3,5% deles ativaram o recurso imediatamente, tornando-o uma das cinco principais ações.
- A duração da sessão dos usuários que ativaram o bloqueio de ativação foi 3,1 vezes maior do que a dos usuários que não ativaram.
- A taxa de rejeição de usuários que ativaram o wake lock foi 50% menor do que para aqueles que não usaram esse recurso.
- Os indicadores de intenção de compra foram cerca de 300% maiores para os usuários de bloqueio de tela em comparação com todos os usuários.
3.1×
Sessão longa
50%
Menor taxa de rejeição
300%
Indicadores de intenção de compra mais altos
Conclusões
Betty Crocker teve resultados fantásticos usando a API Wake Lock. Para testar o recurso, pesquise sua receita favorita em qualquer um dos sites (BettyCrocker, Pillsbury ou Tablespoon) e ative a opção Impedir que a tela escureça enquanto você cozinha.
Os casos de uso de bloqueios de ativação não param nos sites de receitas. Outros exemplos são apps de cartão de embarque ou de ingresso que precisam manter a tela ativa até que o código de barras seja digitalizado, apps no estilo de quiosque que mantêm a tela ativa continuamente ou apps de apresentação baseados na Web que impedem que a tela entre no modo de suspensão durante uma apresentação.
Reunimos tudo o que você precisa saber sobre a API Wake Lock em um artigo completo neste site. Boa leitura e bom apetite!
Agradecimentos
A foto da pessoa amassando massa é cortesia de Julian Hochgesang no Unsplash.