Meu novo portfólio

Post interativo contando como meu novo portfolio foi desenvolvido.

290 views


Meu portfólio é o meu laboratório pessoal para experimentar e testar novas tecnologias, e hoje posso dizer que está do jeito que sempre sonhei: um espaço no qual consigo compartilhar meus projetos e minha visão de tecnologia, tanto como designer quanto como desenvolvedor ✨

Este projeto na verdade começou em Março de 2023, inspirado por alguns projetos que postarei abaixo e pela vontade de estudar e aplicar as novas features do Next.js 14, como: React Server Components, Suspense API e SSR Streaming. Além disso, queria aplicar novas tendências de design, com foco em micro-interações, sons e animações 3D.

Por fim, quis resolver alguns problemas da versão anterior, como: limitações na escrita de posts/cases de projetos, já que utilizava Markdown e GraphQL com um CMS headless (Hygraph), além de alguns problemas em resoluções de tela específicas, devido a estrutura da página inicial.

Inspirações

Lista de portfólios e sites que me inspiraram:

Novas funcionalidades

O Hygraph é um CMS headless muito poderoso e ao mesmo tempo simples. Porém, estava encantado com o poder do Markdown com JSX, o famoso MDX. Há bastante tempo escrevo posts do blog e cases de projeto em Markdown, então a migração foi bastante tranquila. Mas o mais interessante nessa nova versão foi poder criar componentes em JSX e adicioná-los de forma simples aos meus conteúdos, principalmente, nas páginas do projeto, criando demos e componentes interativos que fazem parte de todo storytelling e enriquecem a experiência de visualização, como na página do projeto Fitcard Design Team.

Atualmente meu fluxo de publicação de conteúdo é escrever em Markdown, gerar um novo build e fazer deploy para produção. Simples e pouco automatizado mas que me atende muito bem devido a finalidade desse projeto.

Next.js e React Server Components

O Next.js continuou sendo minha escolha por ser atualmente a forma mais comum de se trabalhar com Server Components dentro do React. Como performance era um dos meus requisitos, fazia e ainda faz bastante sentido trabalhar com Next.js, mesmo com alguns caveats, já que ainda é algo novo dentro desse ecossistema.

Uma das coisas que mais gostei é como a sintaxe para requisições é mais simples, com uma ótima legibilidade e que acaba evitando alguns bugs. Abaixo, uma diferença entre uma requisição para buscar posts do blog antes com useEffect, igual os Incas, e agora com server components.

1function Projects({ params: { locale } }: GenerateMetadataProps) {
2 const [projects, setProjects] = useState([]);
3
4 useEffect(() => {
5 const fetchProjects = async () => {
6 try {
7 const projectList = await getProjectList(locale);
8 setProjects(projectList);
9 } catch (error) {
10 console.error('Erro ao buscar a lista de projetos', error);
11 }
12 };
13
14 fetchProjects();
15 }, [locale]);
16
17 return (
18 <>
19 {projects.map(({ title, description, slug, role, year }) => (
20 <Project
21 key={slug}
22 title={title}
23 description={description}
24 link={`/project/${slug}`}
25 role={role}
26 year={year}
27 />
28 ))}
29 </>
30 );
31}

Aqui tem um post muito interessante sobre esse novo paradigma, e enquanto eu escrevia esse post, a Vercel lançou um App Router Playground muito legal exibindo todas as features dessa nova versão.

CSS

Com os Server Components, muitas bibliotecas de estilização deixaram de ser funcionais, como Styled Components e o fantástico Stitches, por exemplo, devido à necessidade de compilar CSS no lado do servidor. E com isso, uma nova era de bibliotecas "zero runtime" está surgindo no mercado.

Acabei escolhendo por utilizar PandaCSS (criado pelos mesmos criadores do Chackra UI), muito por conta de sua ótima documentação, e pela integração fantástica com Typescript. Além disso, é bastante simples a configuração e expansão de tokens do design system do seu projeto. Porém, também tive alguns percalços:

  • Sempre que precisava criar um novo keyframe com CSS, tinha que editar o arquivo de configuração da biblioteca para criar um "token", ao invés de simplesmente declarar o keyframe no arquivo de estilo;
  • Por ser relativamente nova, a biblioteca ainda não tem um plugin funcional para editores de código (VSCode no meu caso), para autocompletes no intellisense da IDE, o que acaba afetando a produtividade.

Talvez hoje minha escolha seria diferente, já que na época não conhecia o vanilla-extract, que tem uma API muito parecida com a do Stitches, que foi a melhor DX que já tive com CSS.

Internacionalização (i18n)

Já faz algum tempo que estou posicionando minha marca em outros idiomas, e ter um portfólio em Inglês é essencial. Felizmente existe um jeito simples e eficiente de lidar com internacionalização no Next.js: next-intl

Embora a estrutura de App Router do Next >13 seja um pouco complexa, a configuração da biblioteca de idiomas segue um formato bastante universal, sendo necessário um arquivo de dicionário de palavras com todas as traduções necessárias.

{
"app": {
"title": "Jonathan Felipe - Design-driven Developer",
"back": "Voltar",
"audioBrowserSupport": "Seu browser não suporta o elemento audio :(",
"clickToCopy": "Clique para copiar :)",
"spotifyNotPlaying": "Sem música tocando no momento"
}
}

Animações 3D com Three.js

Aqui a coisa começa a ficar legal! O Three.js é uma biblioteca já bastante conhecida e antiga (se levarmos em conta a “vida útil” dessas bibliotecas). Lançada em 2010, ainda hoje é referência em animações 3D para Web, mas nunca tive a oportunidade de trabalhar com ela, e me lancei um desafio de aprender seus conceitos básicos.

Depois de uns experimentos no Codepen, decidi usar a animação de uma esfera com suas vértices modificadas com o algoritmo de perlin noise (usando Javascript), para serem usados como “thumbnails” dos meus projetos. O legal é que a intensidade dos ruídos é calculada de forma aleatória. Logo, a esfera de um projeto nunca será igual a do outro.

Está na minha lista de tarefas aprender e experimentar ainda mais sobre essa biblioteca muito poderosa.

Sons e micro-interações

Através da minha especialização em Design Emocional, estou aprendendo bastante sobre como podemos gerar novas experiências (aprendizados) e interações memoráveis com nossos produtos.

Quanto mais sentidos do corpo humano invocamos, mais chance de criar uma memória positiva (ou negativa também), e com isso, decidi utilizar sons de feedback em algumas interações realizadas pelo mouse do usuário, que podem ser perceptíveis ao clicar em qualquer item do menu principal no topo da página, e em outras situações esporádicas. Sem abusar muito, com volume e equalização padronizada e com controle total do usuário através de um seletor no rodapé da página.

Quanto às micro-interações, elas estão presentes em praticamente todos os elementos que realizam alguma ação dentro do portfólio, mas além disso, escolhi a página 404 para criar easter eggs e colocar em prática outros experimentos, mas vou deixar você visitar e conferir por conta própria 😏

Página de experimentos

Uma adição muito bem-vinda foi uma página para reunir meus experimentos mais "refinados". Estou sempre aprendendo com a mão na massa, e ter um espaço para publicar resultados legais desses aprendizados me incentiva ainda mais.

A ideia nesta página foi explorar o conceito de experimentação trazendo elementos visuais do Figma, similar ao que tinha feito no meu outro projeto pessoal I love micro-interactions. Para ser honesto, sou o tipo de desenvolvedor que fica horas polindo um elemento visual minúsculo na tela, pois acredito que esses pequenos detalhes fazem toda a diferença no resultado final.

Performance

Como desenvolvedor front-end, meu foco sempre foi em criar uma aplicação performática. Sou da época em que cada otimização pequena tinha um grande impacto para o usuário, desde minificar CSS e JS manualmente, até ativar compressão GZIP e cache pelo .htaccess 🥸

Hoje é dia dependendo de qual framework escolhemos, essas otimizações já vem configuradas automaticamente, além é claro, das próprias otimizações nativas dos navegadores, que hoje em dia estão muito mais "developer friendly" do que antes.

Com o Next.js pude explorar novas features que na verdade já estão sendo desenvolvidas pela equipe do React há bastante tempo, como a Suspense API e o Lazy Loading (ou Dynamic Import).

Em páginas com listagem de posts e projetos, estou utilizando o Suspense com um layout de loading criado com elemento da biblioteca react-loading-skeleton, por exemplo.

Em casos onde precisamos criar um estado de loading para uma página inteira, podemos utilizar arquivos com a nomenclatura loading.tsx, como descrito na documentação oficial.

Outro ponto super positivo de utilizar Suspense API dentro do Next.js, é usufruir do SSR Streaming para que "pedaços" de sua aplicação sejam disponibilizados ao usuário de forma paralela, otimizando bastante o tempo de carregamento e fazendo com que partes de sua aplicação sejam interativas sem precisar carregar toda a página.

Image placeholder

O componente Image do Next.js é ótimo por padrão. Ter otimização de imagens de forma automatizada era o sonho de todo desenvolvedor anos atrás, e com esse componente, ganhamos ainda mais opções para otimizar arquivos estáticos de imagem.

Uma das props que mais utilizo junto ao componente Image é a placeholder com valor blur, para gerar uma imagem de fundo enquanto a imagem principal está sendo baixada pelo navegador. Porém, essa técnica não funciona com imagens que não são importadas de forma estática para sua aplicação.

Para remediar esse cenário, criei um componente ImageExtended que recebe uma prop blurHash (gerada através do site blurha.sh) e converte essa hash para o formato base64, interpretado pelo Next.js. Isso foi possível graças a este post sobre o assunto. Arrasta o mouse na imagem abaixo para conferir a diferença:

Conclusão

Não tem felicidade maior para mim do que escrever um post interativo como esse! Claro que dá bastante trabalho mas ao mesmo tempo é um estímulo à criatividade imaginar como posso criar elementos que ornam com todo o conteúdo da página. Além disso, é claro, consegui explorar bastante os conceitos que acredito que se tornarão regra nos próximos anos.

Espero que esse post te inspire de alguma forma, e qualquer coisa, me chame em alguma rede social por aí 😏