html - selectors - Por que os navegadores correspondem aos seletores CSS da direita para a esquerda?




css selector sequence (2)

Os seletores de CSS são correspondidos pelos mecanismos de navegação da direita para a esquerda. Então, eles primeiro encontram as crianças e depois checam seus pais para ver se elas combinam com o resto das partes da regra.

  1. Por que é isso?
  2. É só porque a especificação diz?
  3. Isso afeta o layout final se ele foi avaliado da esquerda para a direita?

Para mim, a maneira mais simples de fazer isso seria usar os seletores com o menor número de elementos. So IDs primeiro (como eles devem retornar apenas 1 elemento). Então, talvez classes ou um elemento que tenha o menor número de nós - por exemplo, pode haver apenas um intervalo na página, portanto vá diretamente para esse nó com qualquer regra que faça referência a um intervalo.

Aqui estão alguns links para fazer backup das minhas reivindicações

  1. http://code.google.com/speed/page-speed/docs/rendering.html
  2. https://developer.mozilla.org/en/Writing_Efficient_CSS

Parece que isso é feito desta forma para evitar ter que olhar para todos os filhos dos pais (que podem ser muitos), em vez de todos os pais de um filho, que deve ser um. Mesmo que o DOM seja profundo, ele só consideraria um nó por nível, em vez de múltiplos na correspondência de RTL. É mais fácil / rápido avaliar os seletores CSS LTR ou RTL?


A análise da direita para a esquerda, também chamada de análise de baixo para cima, é realmente eficiente para o navegador.

Considere o seguinte:

#menu ul li a { color: #00f; }

O navegador primeiro verifica a , depois li , depois ul e depois #menu .

Isso ocorre porque, como o navegador está varrendo a página, ele precisa apenas olhar para o elemento / nó atual e todos os nós / elementos anteriores que ele digitalizou.

A coisa a notar é que o navegador começa a processar o momento em que obtém uma tag / nó completa e não precisa esperar pela página inteira, exceto quando encontra um script, e nesse caso pausa temporariamente e conclui a execução do script e, em seguida avança.

Se ocorrer o contrário, será ineficiente porque o navegador encontrou o elemento que estava digitalizando na primeira verificação, mas foi forçado a continuar procurando no documento todos os seletores adicionais. Para isso, o navegador precisa ter todo o html e pode precisar digitalizar toda a página antes de iniciar a pintura css.

Isso é contrário ao modo como a maioria das bibliotecas analisa o dom. Lá o dom é construído e não é necessário escanear toda a página, apenas encontre o primeiro elemento e, em seguida, siga os outros dentro dele.


Lembre-se de que, quando um navegador faz correspondência de seletor, ele tem um elemento (aquele para o qual está tentando determinar o estilo) e todas as suas regras e seus seletores, e precisa descobrir quais regras correspondem ao elemento. Isso é diferente da coisa usual do jQuery, digamos, onde você tem apenas um seletor e precisa encontrar todos os elementos que correspondem a esse seletor.

Se você tivesse apenas um seletor e apenas um elemento para comparar com esse seletor, a esquerda para a direita faria mais sentido em alguns casos. Mas isso decididamente não é a situação do navegador. O navegador está tentando processar o Gmail ou qualquer outra coisa e tem o <span> que está tentando estilizar e as mais de 10.000 regras que o Gmail coloca em sua folha de estilo (não estou aumentando esse número).

Em particular, na situação, o navegador está olhando para a maioria dos seletores que está considerando não coincidirem com o elemento em questão. Portanto, o problema é decidir se um seletor não corresponde o mais rápido possível; se isso requer um pouco de trabalho extra nos casos que combinam, você ainda ganha devido a todo o trabalho que você salva nos casos que não combinam.

Se você começar apenas combinando a parte mais à direita do seletor com o seu elemento, então as chances são de que ele não vai corresponder e está feito. Se corresponder, você terá que fazer mais trabalho, mas apenas proporcional à profundidade da sua árvore, o que não é tão grande na maioria dos casos.

Por outro lado, se você começar combinando a parte mais à esquerda do seletor ... com o que você combina? Você precisa começar a andar pelo DOM, procurando por nós que correspondam a ele. Apenas descobrir que não há nada que corresponda à parte mais à esquerda pode demorar um pouco.

Portanto, os navegadores correspondem à direita. Ele fornece um ponto de partida óbvio e permite que você se livre da maioria dos seletores candidatos muito rapidamente. Você pode ver alguns dados em http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665 (embora a notação seja confusa), mas o resultado é que, em particular, para o Gmail dois anos atrás, para 70% dos pares (regra, elemento), você poderia decidir que a regra não corresponde depois de examinar as partes tag / class / id do seletor mais à direita da regra. O número correspondente para a suíte de testes de desempenho de pageload da Mozilla foi de 72%. Então, vale a pena tentar livrar-se desses 2/3 de todas as regras o mais rápido possível e só se preocupar com o 1/3 restante.

Observe também que existem outras otimizações que os navegadores já fazem para evitar até mesmo tentar combinar regras que definitivamente não corresponderão. Por exemplo, se o seletor mais à direita tiver um id e esse id não corresponder ao id do elemento, não haverá tentativa de corresponder esse seletor àquele elemento no Gecko: o conjunto de "seletores com IDs" que são tentados vem de uma pesquisa hashtable no ID do elemento. Então, isso é 70% das regras que têm uma boa chance de correspondência que ainda não correspondem depois de considerar apenas a tag / class / id do seletor mais à direita.





css-selectors