jQuery ou javascript para encontrar o uso de memória da página

98

Existe uma maneira de descobrir quanta memória está sendo usada por uma página da web ou pelo meu aplicativo jquery?

Esta é minha situação:

Estou construindo um webapp com muitos dados usando um front-end jquery e um back-end tranquilo que fornece dados em JSON. A página é carregada uma vez e tudo acontece via ajax.

A IU fornece aos usuários uma maneira de criar várias guias dentro da IU, e cada guia pode conter muitos e muitos dados. Estou pensando em limitar o número de guias que eles podem criar, mas acho que seria bom limitá-las apenas quando o uso de memória ultrapassar um determinado limite.

Com base nas respostas, gostaria de fazer alguns esclarecimentos:

  • Estou procurando uma solução de tempo de execução (não apenas ferramentas de desenvolvedor), para que meu aplicativo possa determinar ações com base no uso de memória no navegador do usuário.
  • Contar os elementos DOM ou o tamanho do documento pode ser uma boa estimativa, mas pode ser bastante impreciso, pois não incluiria associação de eventos, dados (), plug-ins e outras estruturas de dados na memória.
Tauren
fonte
Você deve investigar o tipo de usuário de seu webapp para determinar se eles têm ou não problemas de memória ao usar seu webapp. Ou você está tendo problemas de memória / desempenho com seu webapp?
Prutswonder
@Prutswonder: Não, não estou tendo problemas, mas estou apenas curioso para saber se essa ferramenta existe. Pensei que, em vez de apenas definir um limite fixo nas guias, um método dinâmico pode ser legal.
Tauren
Acabei de adicionar alguns detalhes adicionais à pergunta para ajudar a esclarecer que estou procurando uma solução de tempo de execução, não uma solução de tempo de construção.
Tauren,
2
Só uma pergunta, se algo já foi armazenado em cache, isso ainda conta?
ajax333221

Respostas:

65

Atualização de 2015

Em 2012, isso não era possível, se você quisesse oferecer suporte a todos os principais navegadores em uso. Infelizmente, no momento, esse ainda é um recurso exclusivo do Chrome (uma extensão não padrão do window.performance).

window.performance.memory

Suporte do navegador: Chrome 6+


Resposta de 2012

Existe uma maneira de descobrir quanta memória está sendo usada por uma página da web ou pelo meu aplicativo jquery? Estou procurando uma solução de tempo de execução (não apenas ferramentas de desenvolvedor), para que meu aplicativo possa determinar ações com base no uso de memória no navegador do usuário.

A resposta simples, mas correta, é não . Nem todos os navegadores expõem esses dados para você. E acho que você deveria abandonar a ideia simplesmente porque a complexidade e imprecisão de uma solução "feita à mão" podem apresentar mais problemas do que resolver.

Contar os elementos DOM ou o tamanho do documento pode ser uma boa estimativa, mas pode ser bastante impreciso, pois não incluiria associação de eventos, dados (), plug-ins e outras estruturas de dados na memória.

Se você realmente deseja manter sua ideia, deve separar o conteúdo fixo do dinâmico.

O conteúdo fixo não depende das ações do usuário (memória usada por arquivos de script, plug-ins, etc.)
Todo o resto é considerado dinâmico e deve ser seu foco principal ao determinar seu limite.

Mas não há uma maneira fácil de resumi-los. Você pode implementar um sistema de rastreamento que reúna todas essas informações. Todas as operações devem chamar os métodos de rastreamento apropriados. por exemplo:

jQuery.dataMétodo de embrulhar ou substituir para informar o sistema de rastreamento sobre suas alocações de dados.

Enrole as manipulações html para que a adição ou remoção de conteúdo também seja rastreada ( innerHTML.lengthé a melhor estimativa).

Se você mantiver grandes objetos na memória, eles também devem ser monitorados.

Quanto à associação de eventos, você deve usar a delegação de eventos e, em seguida, também pode ser considerado um fator um tanto fixo.

Outro aspecto que torna difícil estimar seus requisitos de memória corretamente é que navegadores diferentes podem alocar memória de maneira diferente (para objetos Javascript e elementos DOM).

gblazex
fonte
Não innerHTML.lengthleva memória ou RAM ou CPU (ou qualquer outra coisa, não tenho ideia) para processar também?
mrReiha
O suporte do navegador para este recurso NÃO é o IE9 + ou qualquer coisa além do Chrome. Window.performance.memory é apenas para o Chrome. docs.webplatform.org/wiki/apis/timing/properties/memory
Blunderfest
Você está certo, eu pensei que a memória fosse parte do padrão de tempo de navegação e do window.performanceobjeto. As antigas entradas "suportado por" eram aplicáveis ​​a esse padrão. window.performance.memoryé considerada uma extensão não padrão pelo Chrome.
gblazex
Para ativar o monitoramento de memória em tempo real por meio de window.performance.memory, você precisa iniciar o Chrome com o sinalizador --enable-precise-memory-info.
kluverua
Atualização: Opera também suporta isso. Fonte: Mozilla. developer.mozilla.org/en-US/docs/Web/API/…
HoldOffHunger
39

Você pode usar a API Navigation Timing .

O Navigation Timing é uma API JavaScript para medir com precisão o desempenho na web. A API fornece uma maneira simples de obter estatísticas de tempo precisas e detalhadas - nativamente - para navegação de página e eventos de carregamento.

window.performance.memory dá acesso aos dados de uso de memória JavaScript.


Leitura recomendada

Sindre Sorhus
fonte
Ótima sugestão. Obrigado.
MaximOrlovsky
21

Esta questão tem 5 anos, e tanto o javascript quanto os navegadores evoluíram incrivelmente nesta época. Já que isso agora é possível (em pelo menos alguns navegadores), e essa pergunta é o primeiro resultado quando você Google "javascript show memory useage", pensei em oferecer uma solução moderna.

memory-stats.js: https://github.com/paulirish/memory-stats.js/tree/master

Este script (que você pode executar a qualquer momento em qualquer página) exibirá o uso de memória atual da página:

var script=document.createElement('script');
script.src='https://rawgit.com/paulirish/memory-stats.js/master/bookmarklet.js';
document.head.appendChild(script);

Dustin Brownell
fonte
1
Isso parece estar relatando o uso de memória JS e não o uso de memória da página, o gerenciador de tarefas integrado do Chrome diz que o Gmail está usando 250 MB, enquanto memory-stats.js relata 33,7 MB
Brandito
Não há licença listada para a página github de bookmarklet.js, portanto, é presumivelmente protegida por direitos autorais, propriedade intelectual. Isso deixa um certo grau de incerteza em depender desse projeto.
HoldOffHunger
8

Não conheço nenhuma maneira de descobrir quanta memória está sendo usada pelo navegador, mas talvez seja possível usar uma heurística baseada no número de elementos da página. Uinsg jQuery, você poderia fazer $('*').lengthe ele lhe dará a contagem do número de elementos DOM. Honestamente, porém, provavelmente é mais fácil apenas fazer alguns testes de usabilidade e chegar a um número fixo de guias para suportar.

Tvanfosson
fonte
3
@tvanfosson: não é uma má ideia, mas isso não vai me dar informações sobre memória não-DOM, como .data () e em estruturas de dados de memória. Mas pode dar uma boa estimativa do peso geral que eu poderia usar.
Tauren
4

Use a ferramenta Chrome Heap Snapshot

Também existe uma ferramenta Firebug chamada MemoryBug, mas parece que ainda não está muito madura.

Pablo Fernandez
fonte
@Pablo: Obrigado. Certamente estarei usando ferramentas de desenvolvimento, mas esperava encontrar algo que pudesse usar durante o tempo de execução para descobrir o uso de memória no navegador de cada usuário.
Tauren,
3

Se você deseja apenas ver para testes, há uma maneira no Chrome por meio da página do desenvolvedor para rastrear o uso de memória, mas não sabe como fazê-lo diretamente em javascript.

Zachary K
fonte
@Zachary: Obrigado. Certamente estarei usando ferramentas de desenvolvimento, mas esperava encontrar uma solução de análise de tempo de execução.
Tauren,
1
Se você encontrar um, me avise, eu adoraria ter um à mão
Zachary K,
3

Gostaria de sugerir uma solução totalmente diferente das outras respostas, ou seja, observar a velocidade do seu aplicativo e, uma vez que ele caia abaixo dos níveis definidos, mostrar dicas para o usuário fechar abas, ou desabilitar a abertura de novas abas. Uma classe simples que fornece esse tipo de informação é, por exemplo, https://github.com/mrdoob/stats.js . Além disso, pode não ser sábio para um aplicativo tão intenso manter todas as guias na memória em primeiro lugar. Por exemplo, manter apenas o estado do usuário (rolar) e carregar todos os dados a cada vez que todas as guias, exceto as duas últimas, podem ser uma opção mais segura.

Por último, os desenvolvedores de webkit têm discutido a adição de informações de memória ao javascript, mas eles apresentaram uma série de argumentos sobre o que e o que não deve ser exposto. De qualquer forma, não é improvável que esse tipo de informação esteja disponível em alguns anos (embora essa informação não seja muito útil agora).

David Mulder
fonte
1

Momento de pergunta perfeito comigo começando em um projeto semelhante!

Não há uma maneira precisa de monitorar o uso de memória JS no aplicativo, pois isso exigiria privilégios de nível mais alto. Conforme mencionado nos comentários, verificar o número de todos os elementos etc. seria uma perda de tempo, pois ignora eventos vinculados etc.

Isso seria um problema de arquitetura se o manifesto de vazamentos de memória ou elementos não utilizados persistissem. Certificar-se de que o conteúdo das guias fechadas seja excluído completamente sem manipuladores de eventos remanescentes, etc. presumindo que está feito, você pode apenas simular o uso intenso em um navegador e extrapolar os resultados do monitoramento de memória (digite about: memory na barra de endereço)

Protip: se você abrir a mesma página no IE, FF, Safari ... e Chrome; e, em seguida, navegue até about: memory no Chrome, ele relatará o uso de memória em todos os outros navegadores. Arrumado!

ov
fonte
0

O que você pode querer fazer é que o servidor controle sua largura de banda para aquela sessão (quantos bytes de dados foram enviados a eles). Quando eles ultrapassam o limite, em vez de enviar dados via ajax, o servidor deve enviar um código de erro que o javascript usará para informar ao usuário que utilizou muitos dados.

Cam
fonte
@incrediman: essa é uma ideia legal também, mas eu não acho que funcionaria sem incluir muitos recursos de rastreamento - apenas uma contagem de bytes não funcionaria. O problema é que os dados em uma guia são uma lista que o usuário filtrará e classificará de muitas maneiras diferentes. Cada vez que eles fazem alterações, novos dados serão recuperados do servidor e substituirão os elementos dom atuais. Além disso, o que dizer que eles não cliquem em "recarregar" e comecem com uma página nova? Eu teria que rastrear 304s e tal também, mas pretendo servir apenas html estático, todos os dados vêm de um serviço REST.
Tauren,
Essa abordagem não leva em consideração os elementos criados ou destruídos com createElement () ou remove (), o que afetaria o uso da memória do cliente. Mas é curiosamente diferente de outras respostas (medindo do lado do servidor, e não do lado do cliente, suas medições não mudam a memória, como outras respostas fariam).
HoldOffHunger
0

Você pode obter o document.documentElement.innerHTML e verificar seu comprimento. Daria a você o número de bytes usados ​​por sua página da web.

Isso pode não funcionar em todos os navegadores. Portanto, você pode incluir todos os elementos do seu corpo em uma div gigante e chamar innerhtml nessa div. Algo como<body><div id="giantDiv">...</div></body>

Midhat
fonte
4
innerHTMLÉ improvável que o comprimento da string gerada seja corrigido de forma útil com a memória que o navegador usa (por exemplo, em seu modelo de objeto interno) para renderizar esse HTML.
TJ Crowder
e por que isto? Meu raciocínio é que, se algum texto for carregado no navegador, ele deverá ser armazenado na memória. Portanto, dá alguma medida da memória usada pelo navegador para renderizar a página.
Midhat
4
Pense nisso desta maneira. Se você disser "Eu gostaria de lhe dar 10 milhões de dólares", são 8 palavras. Por outro lado, se você disser "Eu gostaria de espirrar no seu guardanapo", isso daria 7. O primeiro 8/7 é mais valioso do que o segundo?
intuído em
1
Isso é semelhante à sugestão de @tvanfosson de obter a contagem de elementos DOM. O seu é provavelmente um pouco mais preciso porque diferentes elementos dom podem conter diferentes quantidades de texto. Mas ainda não obtém nenhuma informação sobre data (), manipuladores de cliques, estruturas de dados e objetos na memória e assim por diante. Meu aplicativo usa muitos desses recursos.
Tauren,
1
Pode haver variáveis ​​JS no escopo que apontam para nós DOM separados, que não farão parte do elemento do documento. Além disso, você pode escrever código apenas para carregar uma string muito longa em uma variável, consumindo gigabytes de memória, sem afetar o texto na página.
Josh Ribakoff