config.assets.compile = true na produção do Rails, por que não?

185

O aplicativo Rails padrão instalado por rails newpossui config.assets.compile = falseem produção.

E a maneira comum de fazer as coisas é executar rake assets:precompileantes de implantar seu aplicativo, para garantir que todos os ativos do pipeline de ativos sejam compilados.

Então, o que acontece se eu começar a config.assets.compile = trueprodução?

Eu não preciso precompilemais correr . O que acredito que acontecerá é a primeira vez que um ativo for solicitado, ele será compilado. Isso será um sucesso na primeira vez (e significa que você geralmente precisa de um tempo de execução js na produção para fazê-lo). Mas, além dessas desvantagens, depois que o ativo foi compilado com preguiça, acho que todo o acesso subsequente a esse ativo não terá impacto no desempenho, o desempenho do aplicativo será exatamente o mesmo dos ativos pré-compilados após essa compilação preguiçosa de primeiro hit inicial. isso é verdade?

Falta alguma coisa? Algum outro motivo para não iniciar a config.assets.compile = trueprodução? Se eu tenho um tempo de execução JS em produção e estou disposto a aceitar a troca de desempenho degradado pelo primeiro acesso de um ativo, em troca de não precisar executar precompile, isso faz sentido?

jrochkind
fonte
1
Aviso, versões mais antigas do pinhões contêm um bug e se config.assets.compile está configurado como verdadeiro, há um risco de vulnerabilidade diretório trasversal ( blog.heroku.com/rails-asset-pipeline-vulnerability )
Mauro
É exatamente assim que o Stackoverflow deve funcionar. Uma pergunta bem escrita e uma resposta bem escrita. Eu amo vocês dois, op e @ richard-hulse.
schmijos

Respostas:

259

Eu escrevi esse pedaço do guia.

Você definitivamente não quer viver compilado na produção.

Quando você compila, é o que acontece:

Toda solicitação de um arquivo em / assets é passada para os Sprockets. Na primeira solicitação de cada ativo, ele é compilado e armazenado em cache em qualquer Rails que esteja usando para cache (geralmente o sistema de arquivos).

Em solicitações subsequentes, o Sprockets recebe a solicitação e precisa procurar o nome do arquivo com impressão digital, verifique se o arquivo (imagem) ou os arquivos (css e js) que compõem o ativo não foram modificados e, se houver uma versão em cache, atenda.

Isso é tudo na pasta de ativos e em qualquer pasta de fornecedor / ativo usada pelos plug-ins.

Isso representa muita sobrecarga, pois, para ser honesto, o código não é otimizado para velocidade.

Isso afetará a rapidez com que os ativos serão transferidos para o cliente e afetará negativamente os tempos de carregamento da página do seu site.

Compare com o padrão:

Quando os ativos são pré-compilados e a compilação está desativada, os ativos são compilados e impressos digitais no public/assets. O Sprockets retorna uma tabela de mapeamento dos nomes de arquivos simples para impressões digitais no Rails, e o Rails grava isso no sistema de arquivos. O arquivo de manifesto (YML no Rails 3 ou JSON com um nome aleatório no Rails 4) é carregado na Memória pelo Rails na inicialização e armazenado em cache para uso pelos métodos auxiliares de ativos.

Isso torna muito rápida a geração de páginas com os recursos corretos das impressões digitais, e a veiculação dos arquivos em si é rápida do servidor da web a partir do sistema de arquivos. Ambos muito mais rápidos que a compilação ao vivo.

Para obter a máxima vantagem do pipeline e das impressões digitais, é necessário definir cabeçalhos de futuro distante no servidor da web e ativar a compactação gzip para arquivos js e css. O Sprockets grava versões compactadas dos ativos que você pode configurar para o servidor, eliminando a necessidade de fazê-lo para cada solicitação.

Isso distribui ativos para o cliente o mais rápido possível e no menor tamanho possível, agilizando a exibição das páginas no lado do cliente e reduzindo as solicitações (com cabeçalho no futuro futuro).

Portanto, se você estiver compilando ao vivo, é:

  1. Muito devagar
  2. Falta compressão
  3. Irá afetar o tempo de renderização das páginas

Versus

  1. O mais rápido possível
  2. Comprimido
  3. Remova a compactação ouvida do servidor (opcional).
  4. Minimize o tempo de renderização das páginas.

Editar: (Resposta ao comentário seguinte)

O pipeline pode ser alterado para pré-compilar na primeira solicitação, mas existem alguns obstáculos importantes para isso. A primeira é que deve haver uma tabela de pesquisa para nomes de impressões digitais ou os métodos auxiliares são muito lentos. Sob um senario de compilação sob demanda, haveria uma maneira de anexar à tabela de pesquisa, à medida que cada novo ativo é compilado ou solicitado.

Além disso, alguém teria que pagar o preço da entrega lenta de ativos por um período desconhecido, até que todos os ativos sejam compilados e no local.

O padrão, onde o preço de compilar tudo é pago off-line de uma só vez, não afeta os visitantes públicos e garante que tudo funcione antes que as coisas sejam lançadas.

O ponto crítico é que ele adiciona muita complexidade aos sistemas de produção.

[Editar, junho de 2015] Se você estiver lendo isso porque está procurando uma solução para tempos de compilação lentos durante uma implantação, considere pré-compilar os ativos localmente. Informações sobre isso estão no guia de pipeline de ativos . Isso permite pré-compilar localmente apenas quando houver uma alteração, confirmar isso e, em seguida, implantar rapidamente, sem estágio de pré-compilação.

Richard Hulse
fonte
1
Obrigado, aceitei sua resposta. Mas agora minha pergunta é: tudo bem, isso não acontece agora, mas é possível que você pense que o Asset Pipeline poderia ter um recurso em que é preguiçosamente compilado na primeira solicitação, fazendo exatamente como pré-compilação, incluindo escrevendo para ./public e atualizando a manifestação da impressão digital?
Jrochkind
Veja acima. Isso é um problema porque Capistrano não funciona para você?
Richard Hulse
Eu não uso Capistrano. Eu não precisava antes, a complexidade adicionada não valia a pena. Talvez o oleoduto de ativos seja o canudo que quebra os camelos e o requer. Na sua opinião, é inviável gerenciar as implantações do Rails com o pipeline de ativos sem capistrano ou similar? É uma pena, para configurações simples que costumava não ser um grande problema fazê-lo manualmente.
Jrochkind
Você realmente precisa do Capistrano for Rails 3.1. Os ativos são compilados em um novo diretório público enquanto o aplicativo antigo ainda está em execução. Quando a compilação é concluída, a nova versão é vinculada a um link simbólico e o servidor é reiniciado automaticamente.
Richard Hulse
"Para obter o máximo proveito do pipeline e das impressões digitais, é necessário definir cabeçalhos de futuro distante no servidor da Web e ativar a compactação gzip para arquivos js e css." - Você pode fornecer algumas instruções ou links sobre como fazer isto?
Isaac Betesh
7

Ter menos sobrecarga com a coisa de pré-compilação.

Precompile everything initially with these settings in production.rb
# Precompile *all* assets, except those that start with underscore
config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/

você pode simplesmente usar imagens e folhas de estilo como "/assets/stylesheet.css" em * .html.erb ou "/assets/web.png"

dbKooper
fonte
6

Para quem usa o Heroku:

Se você implantar no Herkou, ele fará o pré-compilamento automaticamente durante a implantação, se os recursos compilados não forem incluídos (ou seja, public/assetsnão confirmados), portanto não há necessidade config.assets.compile = trueou comprometimento dos recursos pré-compilados.

Os documentos de Heroku estão aqui . Uma CDN é recomendada para remover a carga no recurso dinamômetro.

William Denniss
fonte
1

Não será o mesmo que pré-compilar, mesmo após o primeiro hit: como os arquivos não são gravados no sistema de arquivos, não podem ser atendidos diretamente pelo servidor da web. Algum código ruby ​​sempre estará envolvido, mesmo que apenas leia uma entrada de cache.

Frederick Cheung
fonte
Hmm, eu pensei que precompile=true, com , os recursos compilados seriam gravados no sistema de arquivos. Você tem certeza? Deixe-me verificar ...
jrochkind
1
Bah, acho que você está certo - eles são gravados no sistema de arquivos, mas parece tmp/cacheque public/assetsnão é um local que o servidor da Web possa ver, mas ainda será servido pelo aplicativo rails o servidor da web. blá. está certo, você acha?
jrochkind
Corrigir. Não será tão rápido quanto ter o servidor da Web para buscá-los. Pode não importa se você colocar um CDN como CloudFront na frente de seu aplicativo
Frederick Cheung
1

Conjunto config.asset.compile = false

Adicione ao seu Gemfile

group :assets do gem 'turbo-sprockets-rails3' end

Instale o pacote

Corre rake assets:precompile

Então inicie seu servidor

Mohammed Saleem
fonte
Tanto quanto eu defini o config.asset.compile = true in production.rbarquivo, porque não há nenhum mecanismo de pré-complemento adicionado. Por isso, toda vez que iniciamos o servidor, leva muito tempo para carregar a página (quando a solicitação atinge o processamento da solicitação e a compilação de ativos). Agora eu incluí turbo-sprockets-rails3no Gemfile e execute o comando que rake assets:precompilecompila os ativos anteriormente. Agora eu configuro config.asset.compile = false in production.rbe inicio o servidor, a página é carregada sem demora. (Processando apenas a solicitação sem compilação de ativos)
Mohammed Saleem
2
Vale dizer que turbo-sprockets-rails3só é necessário em Ruby 3
Andre Figueiredo
0

Do guia oficial :

Na primeira solicitação, os ativos são compilados e armazenados em cache, conforme descrito no desenvolvimento acima, e os nomes de manifesto usados ​​nos auxiliares são alterados para incluir o hash MD5.

Sprockets também define o cabeçalho HTTP de controle de cache como max-age = 31536000. Isso sinaliza todos os caches entre o servidor e o navegador do cliente que esse conteúdo (o arquivo exibido) pode ser armazenado em cache por 1 ano. O efeito disso é reduzir o número de solicitações para esse ativo do seu servidor; o ativo tem uma boa chance de estar no cache do navegador local ou em algum cache intermediário.

Este modo utiliza mais memória, apresenta desempenho inferior ao padrão e não é recomendado.

Além disso, a etapa de pré-compilação não é um problema se você usar o Capistrano para suas implantações. Ele cuida disso para você. Você acabou de correr

cap deploy

ou (dependendo da sua configuração)

cap production deploy

e está tudo pronto. Se você ainda não o usa, eu recomendo dar uma olhada.

Sergio Tulentsev
fonte
Então você acha que o idioma do guia oficial concorda comigo? Eu já vi esse guia, não tenho certeza se isso significa o que estou sugerindo acima, o que você acha? Essa é a minha pergunta.
Jrochkind
Sim, você diz basicamente a mesma coisa. Sugiro que você não ative a compilação ao vivo.
Sergio Tulentsev 11/01