Como reduzir o tamanho do pacote - estratégia de classe de uma letra em módulos css

Melhoramos a compactação de pacotes configuráveis ​​em 40% do tamanho do arquivo, substituindo o hash padrão por um prefixo de uma letra + hash do caminho do arquivo.

Os módulos CSS permitem escrever componentes Bird e Cat, com estilos em arquivos com o mesmo nome styles.css e .block classes em cada um, e essas classes serão diferentes para cada um desses componentes.

/* Bird / styles.css */
.block { }
.name { }
/* Cat / styles.css */
.block { }
.name { }

Não há nada de complicado aqui: o webpack faz o hash de cada classe de todos os arquivos usando a configuração "[hash: base64: 8]". Todas as classes serão renomeadas e links afixados para entender de onde veio a classe. Na versão básica do assembly, teremos um arquivo styles.css para styles e styles.js para links ao trabalhar com js.

Continuando o caso de teste, obtemos 4 classes independentes com nomes estranhos como k3bvEft8:

/* Bird */
.k3bvEft8 { }
.f2tp3lA9 { }
/* Cat */
.epIUQ_6W { }
.oRzvA1Gb { }

Execute a montagem de produção e compacte os arquivos. No estande, um arquivo css de 300Kb foi empacotado em 70Kb usando gzip [ou 50Kb usando brotli]. A compactação é pequena porque os hashes são seqüências geradas aleatoriamente que são compactadas muito mal. Os algoritmos de compressão não veem sequências e são forçados a lembrar os locais de cada símbolo, ou seja, transfira o conteúdo dessas seções como está, sem compactação.

Algo precisa ser feito com isso. Mas o que? Durante a operação, o webpack lê a árvore de arquivos de forma assíncrona e também passa por nomes de classes. Cada vez de uma maneira diferente. A única coisa com a qual você pode se apegar é a ordem dos nomes dentro de css - é constante (caso contrário, tudo irá quebrar, em css a ordem é importante). O número da posição da classe no arquivo é codificado em um prefixo de uma letra. Você pode usar a codificação em 52 ([a-zA-Z] +) ou 64 ([a-zA-Z0-9 _-] +) caracteres. O principal aqui é não esquecer de colocar um prefixo de proteção em casos com um número ou hífen.

/* Bird */
.a { }
.b { }
/* Cat */
.c { }
.d { }

Parece ter uma boa aparência - os nomes são compactados o máximo possível. Mas o problema é que o webpack é assíncrono, e cada inicialização, e especialmente quando os assemblies simultâneos do servidor e do cliente são iniciados em paralelo, recebem arquivos de maneira caótica, assim como os nomes das classes. Obrigado pela velocidade, mas aqui isso interfere.

/* Bird */
.c { }
.d { }
/* Cat */
.a { }
.b { }

Você vê, detectou uma incompatibilidade de ordem de arquivo.

Corrigimos esse comportamento lembrando o arquivo, de onde as classes vieram e seu número de posição.

/* Bird */
.a { }
.b { }
/* Cat */
.a { }
.b { }

Salve o pedido dentro dos arquivos. Mas você precisa, de alguma forma, distinguir os arquivos um do outro. Um hash do caminho do arquivo ajudará a evitar confusões.

/* Bird */
.a_k3bvEft8 { }
.b_k3bvEft8 { }
/* Cat */
.a_oRzvA1Gb { }
.b_oRzvA1Gb { }

('_' não é necessário aqui, é apenas para fins ilustrativos. O hash tem um comprimento estável, diferente do prefixo, e não pode haver colisões).

Obtivemos nomes de classes absolutamente exclusivos para o projeto, mas contendo sequências repetidas.

Em nosso projeto, dos arquivos css 50 Kb e js 47 Kb, obtivemos css 30 Kb e js 28 Kb [58 Kb no total, brotli].
Economizando quase 40Kb. O tamanho do css crítico e o tamanho do html diminuirão ligeiramente.

Resta escrever uma classe para processar dados do webpack e fazer uma chamada na configuração do css-loader (getLocalIdent)

PS Você pode ir além e salvar os caminhos do arquivo, classificá-los e também substituí-los usando uma estratégia de letra única, mas isso é pior em termos de cache de longo prazo, além de fazer várias passagens na montagem e montar o cliente / servidor sequencialmente.

PS2 Você pode experimentar seu projeto agora, se usar o código aqui

PS3. Na produção, compactamos os arquivos * .css e * style.js em 93%. Transferimos 71,6Kb de 1,1Mb do arquivo descompactado (brotli)

All Articles