[Flutter] Flutter na WEB e o uso de Web Workers Javascript
O flutter/Dart em sua versão mobile consegue fazer coisas extraórdinárias usando isolates, embora a execução principal da linguagem seja singlethread baseada em Event Loop podemos ter acesso a espaço de memórias isoladas e executar desempenho massivo sem comprometer a interface visual com freezes desnecessários, porém na web isso não é possível por conta das características do ambiente.
Por causa disso alguns navegadores disponilizam formas de usar workers(trabalhadores) de uma forma que possamos executar determinadas ações sem travar a execução do event loop principal o que nos ajuda em diversas atividades na web. E tentarei hoje mostrar como implementar o uso desses workers utilizando o Flutter na web.
Para iniciar precisamos importar o pacote html do dart.
import 'dart:html';
Em seguida no diretório principal de um projeto flutter existe uma pasta web e adicionamos nessa pasta um arquivo .js com o código do nosso worker.
Um exemplo é o seguinte
self.onmessage = async function (event) {
self.postMessage(
"Message from JS: Começando o cálculo de fibonacci: " + event.data
);
var value = Number(event.data);
let fibo = fibonacci(value);
self.postMessage("Message from JS: Resultado do fibonacci " + fibo);
};
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
o event.data carregará todos os valores que iremos receber do Dart.
self.postMessage é a forma de voltarmos os valores para o dart.
Então tudo o que o for possível no imaginário nesse contexto web por meio do js poderá executar/processar e voltar para o Dart o resultado feito.
Voltando ao Flutter/Dart precisaremos declarar uma variável que carrega o nome do arquivo do worker.
final Worker worker = Worker('worker.js');
agora poderemos utilizar o worker da forma que imaginamos sempre validando se o worker é suportado pelo navegador que estamos executando o código.
if (Worker.supported) {
final dt = DateTime.now();
worker.postMessage('40');
worker.onMessage.listen((event) {
setState(() {
text = event.data;
});
print('Tempo de execução: ${DateTime.now().difference(dt)}');
});
} else {
print('Web Worker não suportado pelo navegador!');
}
utilizando worker.postMessage para enviar dados para o worker e ouvindo no worker.onMessage o retorno desses dados. e sempre que terminarmos a execução do worker podemos termina-lo por executar:
worker.terminate();
Dessa forma simples podemos aproveitar dos benefícios desses workers para executar códigos em background, utilizar de notificações e processamento massivo na web sem travar a interface do usuário e tudo mais que a criatividade permitir realizar com essa ferramenta tão poderosa presente em alguns navegadores