- Uso de Image Maps:
Image Map permite que se tenha apenas uma imagem com múltiplos links nesta imagem. Ou seja, não é necessário, ao criar uma toolbar por exemplo, ter várias imagens, uma para cada link. É possível ter apenas uma imagem maior, cujas partes desta imagem possuem diferentes links. Isso é feito através do uso de Image Map. - Combinar arquivos em um único:
Ao invés de fazer 4 requisições para 4 diferentes arquivos de JavaScript (JS), você pode combinar os 4 arquivos em um único, e fazer apenas uma requição Http. Em sendo um engenheiro de software, isso me parece estranho, pois vai contra a modularização. Mas, se pudermos ter esta modularização em tempo de desenvolvimento, e e combinar estes arquivos em tempo de deploy, teremos assim o melhor dos dois mundos.
A mesma coisa vale para arquivos CSS: é possível combinar os diferentes arquivos CSS em um único. Combinar arquivos pode ser desafiador quando os scripts e arquivos css variam de página para página, mas tentar fazer esta junção em um único arquivo pode ser vantajoso. Se você conseguir fazer esta combinação automaticamente como parte do seu processo de Deploy, isso pode ficar transparente para o desenvolvedor, e assim conseguir fazer menos Requests HTTP, melhorando a performance final da sua página.
Numa situação ideal, sua página poderia ter apenas um arquivo javascript e um arquivo CSS.
Em algumas situações em que a página faz uso de diferentes bibliotecas javascript e ainda possui scripts próprios, a combinação pode dar ganhos em torno de 40% no carregamento da página. - CSS Sprites
CSS sprites é uma técnica usada para se criar apenas um arquivo de imagem que conbina várias imagens que serão usadas independentes umas das outras através de estilos CSS. Ou seja, existe apenas um arquivo de imagem que é resultado da combinação de algumas imagens a serem usadas independentemente. Para conseguir usar cada parte da grande imagem de forma a mostrar apenas a parte que interessa de cada vez, usa-se estilos CSS. Por exemplo:
Desta forma, podemos ter uma imagem grande de, por exemplo, 200px por 200px, mas estamos apresentando apenas uma parte dela, de 26 por 26 px.
O uso de CSS Sprites, combinado com o uso de Cache de imagens, é uma excelente forma de usar múltiplos ícones em uma página, porém fazendo apenas um Request para carregar a única imagem grande. Você pode ver mais a respeito deste assunto no artigo de Dave Shea chamado "CSS Sprites: Image Slicing's Kiss of Death".
Web Sites de Alta Performance, Parte 3: Faça menos Requests HTTP
Web Sites de Alta Performance, Parte 2: Visão Geral de HTTP
Web Sites de Alta Performance, Parte 1: A Regra do 80-20 da uma Página Web
Este post é o primeiro de uma série que irei denominar de Web Sites de Alta Performance. Esta série é inspirada e baseada no livro High Performance Web Sites de Steve Souders, na posição de Chief Performance Yahoo!. O livro é fino, leve e bastante objetivo. Esta série tem o objetivo de resumir as técnicas apontadas por Souders.
É possível ver muito claramente quais são todos os recursos carregados pelo browser para que a página final seja apresentada corretamente para o usuário: Html da página em si, imagens, arquivos CSS, arquivos Javascript. Cada recurso desse é um request feito ao servidor para que ele seja encontrado e baixado. Uma ferramenta de análise desses recursos sendo baixados é muito importante para podermos ver como nossa página está hoje e como ela estará depois de aplicadas as técnicas que serão expostas nesta série de posts do meu blog. Acho que o Firefox também deve ter algum plugin que fornece este tipo de informação.

- Request de cada componente;
- Requests que não ocorrem em paralelo (scripts não são baixados em paralelo);
- Parse de Html, CSS e Javascript;
- Renderização final
Servindo JavaScript e CSS com velocidade
Vale a leitura.
InfoQ CheatSheets: dicas que ajudam
Eu sei, eu sei....
Tenho andado totalmente sumido.... essa vida tá a maior correria....
o InfoQ tem se tornado leitura obrigatória para mim. Muito bom, prático, com boas entrevistas, vídeos, PDFs, etc.
A última dica que vi no InfoQ foi descobrir o "FREE Cheatsheets for Developers". Muito legal.
Lá tem aqueles PDFs curtos, com dievrsas dicas. Cada PDF é sobre um assunto. No momento, são eles:
- RSS and Atom
- GlassFish Application Server
- IntelliJ IDEA
- Silverlight 2
- Flexible Rails: Flex 3 on Rails 2
- Design Patterns
- jQuery Selectors
- Dependency Injection in EJB 3
- Windows PowerShell
- Spring Configuration
- Getting Started with Eclipse
Abcs
Detalhe do Grails com Eclipse
Pessoal
eu já passei maus bocados uma vez por causa da questão que irei escrever aqui. Hoje, meu companheiro de desenvolvimento João Paulo passou pelo mesmo problema...Depois de algum tempo ele resolveu me perguntar, e lendo o erro que ele me passou, não deu outra, era o problema que já passei.
Quando você ler um erro como este:
No signature of method: Requestmap.save() is applicable for argument types: () values: {}
(é claro que no seu caso a sua classe de domain não será Requestmap, será Pessoa, Categoria, Produto, sei lá o que)
Uma das possíveis causas disso é uma configuração no eclipse, que faz com que o Eclipse compile as classes groovy, gerando os arquivos .class . Neste caso, o grails, ao rodar a aplicação com "grails run-app"
, ele também compila, aí tudo se perde.
Não deixe de configurar o Eclipse para não compilar os arquivos de groovy. Para isso:
- Clique com botão direito no seu projeto, no eclipse
- Selecione "Groovy project Properties"
- Marque a opção "Disable Groovy Compiler Generating Class Files"
Abcs
Felipe
Grails 1.0.1 e many-to-many com GORM DSL
Oi pessoal,
primeiro queria divulgar o forum do GrailsBrasil ( www.grailsbrasil.com ). Um ótimo espaço para os brazucas, que cada vez mais descobrem e se encantam com o Grails.
Em seguida, queria falar, com certo atraso, da tão esperada Release 1.0 do Grails, que na verdade já está na 1.0.1. Isso é uma grande notícia.
Por último, a razão deste post....
O Grails 1.0.1 possui o GORM DSL, que oferece grande facilidade para controlar detalhes do mapeamento objeto relacional dos objetos de domínio. Ao migrar uma aplicação do grails 0.6 para o 1.0.1, quis alterar alguns detalhes do mapeamento, já que agoraeu conseguiria isso sem precisar apelar para mapeamento Hibernate com XML.
O problema que eu queria resolver era:
Digamos que eu tenha uma classe Usuario e outra Privilegio, com um relacionamento many-to-many entre elas. Logo teremos:
class Usuario {
String nome
static hasMany = [privilegios:Privilegio]
}
class Privilegio {
String nome
static hasMany = [usuarios:Usuario]
static belongsTo = Usuario
}
Com as classes acima, o grails gera as seguintes tabelas:
usuario
id
nome
privilegio
id
nome
usuario_priv
usuarios_id (que é uma FK para privilegio.id)
privilegios_id (que é uma FK para usuario.id)
É isso mesmo: o campo usuarios_id é uma chave estrangeira para o id da tabela privilegio; e o campo privilegios_id é uma chave estrangeira para o id da tabela usuario. A explicação pra isso está aqui (vejam o comentário do Graeme).Eu não sei quanto a vocês, mas pra mim isso soa muito estranho. Mas é assim mesmo que o grails gera por padrão. A forma que eu gosto de trabalhar é com campos no singular e com o nome do campo da chave estangeira condizente com o nome da tabela de referência:
usuario_priv.usuario_id = usuario.id
usuario_priv.privilegio_id = privilegio.id
Para isso, então, eu antigamente teria que fazer o mapemanto com XML do hibernate (já fiz vários para outras aplicações com grails). Mas agora na versão atual posso fazer o que quero com o GORM DSL. E é isso que quero mostrar, pois há um detalhe que precisei fazer alguns testes até entender o comportamento do Grails com essa DSL. Vamos lá...
class Usuario {
String nome
static hasMany = [privilegios:Privilegio]
static mapping = {
privilegios column:'usuario_id', joinTable:'usuario_priv'
}
}
class Privilegio {
String priv
static hasMany = [usuarios:Usuario]
static belongsTo = Usuario
static mapping = {
usuarios column:'privilegio_id', joinTable:'usuario_priv'
}
}
O que eu acho curioso e anti-intuitivo no código acima, é que numa primeira tentativa eu coloquei:
Mas isso acabou sendo errado. Na verdade temos que colocar como nome da coluna (para ter o resultado que eu esperava), o nome da classe em que me encontro, e não o nome do atributo de relacionamento. Em fim: o correto é o código acima completo das classe Usuario e Privilegio, e não o código acima com fundo avermelhado.class Usuario {static mapping = {
privilegios column:'privilegio_id', joinTable:'usuario_priv'
}
}
Fiz questão de colocar isso aqui, pois a documentação não me parece muito clara quanto a isso. (talvez eu é que tenha entendido errado a documentação, sei lá....em fim....tá aí pra quem precisar deste detalhe).
Abcs
Felipe