Após fazer pesquisar no site da MDN, W3chools e rodar testes no meu navegador e no measurethat, descobri algumas coisas interessantes sobre os 3 metodos. Como eles variam em velocidade e funcionalidade, montei um post para poder explicar como cheguei na minha resposta.. segue abaixo um resumo dela:
A performance
Resolvi pesquisar para saber qual seria a melhor opção. Segundo o site https://measurethat.net/Benchmarks/Show/54/0/classname-vs-setattribute-vs-classlist, alguém já havia se perguntado o mesmo. Eles fizeram o seguinte teste que rodei no Chrome, Edge e Firefox:
1º lugar: className
2º lugar: setAttribute (exceto Edge)
3º lugar: classList
*Resultado em operações por segundo
Na prática
Mesmo sendo bem claro, o teste acima não é um absoluto, devemos levar em consideração outros fatores como manipulação, funcionalidades e boas práticas.
className: Permite a manipulação das classes no formato string, nesse caso tendo uma string com todas as classes escritas dentro e permitindo a manipulação dos dados neste formato. Por ser uma funcionalidade antiga, é utilizado por diversos navegadores
setAttribute: O set atribute simplesmente faz isso, define o valor dentro de um atributo. Existe o getAttribute que permite visualizar este valor, mas a manipulação é limitada a isso.
classList: Coloca as classes dentro de uma lista para serem manipuladas de forma ordenada através de diversos métodos específicos. A nível de funcionalidade é a mais prática, mas além de ter uma performance inferior, não foi implementada em navegadores mais antigos.
Conclusão
Acredito que o className e o classList sejam os melhores candidatos. Se você precisa de performance e está apenas definindo e apagando classes, utilize o className. Agora se você tem um sistema que precisa procurar por classes dentro da tag ou adicionar apenas se não existe, poupe o esforço de criar uma lógica para isso e utilize o classList.
Para a versão completa desta resposta, veja o post: http://www.mundojs.com.br/blog/b00020.html