{"id":2890,"date":"2014-10-15T13:04:55","date_gmt":"2014-10-15T16:04:55","guid":{"rendered":"http:\/\/blog.dialhost.com.br\/?p=2890"},"modified":"2014-10-15T13:04:55","modified_gmt":"2014-10-15T16:04:55","slug":"como-fazer-um-tunning-de-aplicacoes-web","status":"publish","type":"post","link":"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/","title":{"rendered":"Como fazer um tunning de aplica\u00e7\u00f5es web"},"content":{"rendered":"<figure id=\"attachment_2891\" aria-describedby=\"caption-attachment-2891\" style=\"width: 700px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/blog.dialhost.com.br\/wp-content\/uploads\/2014\/10\/slow.jpg\"><img loading=\"lazy\" class=\"size-full wp-image-2891\" src=\"http:\/\/blog.dialhost.com.br\/wp-content\/uploads\/2014\/10\/slow.jpg\" alt=\"Carregando...\" width=\"700\" height=\"260\" \/><\/a><figcaption id=\"caption-attachment-2891\" class=\"wp-caption-text\">Carregando&#8230;<\/figcaption><\/figure>\n<p>A velocidade da aplica\u00e7\u00e3o em executar os processos est\u00e1 intimamente ligada com a experi\u00eancia do usu\u00e1rio final. Na pr\u00e1tica, vejo que os respons\u00e1veis pela cria\u00e7\u00e3o de sistemas (gerentes, projetistas e programadores) n\u00e3o t\u00eam colocado isso como um fator de preocupa\u00e7\u00e3o nos ciclos de desenvolvimento. O resultado \u00e9 o mesmo de sempre, em ambiente de testes, homologa\u00e7\u00e3o e durante algum tempo inicial de produ\u00e7\u00e3o, o sistema acaba enganosamente funciona lindo e maravilhoso, mas depois de algum tempo, as reclama\u00e7\u00f5es relacionadas com a lentid\u00e3o come\u00e7am a aparecer. Diante desse contexto, segue abaixo as principais pr\u00e1ticas que eu venho utilizando como sucesso como se fosse uma \u201creceita de bolo\u201d para resolver esse tipo de situa\u00e7\u00e3o:<\/p>\n<p><strong>Acesso ao banco de dados<\/strong><\/p>\n<p>Reduzir ao m\u00e1ximo o n\u00famero de vezes que a solu\u00e7\u00e3o faz acesso ao banco de dados.<\/p>\n<p><strong>Problema:<\/strong> Muitos programadores t\u00eam a mania de ir desenvolvendo classes, componentes e m\u00f3dulos sem antes e\/ou durante fazer uma an\u00e1lise organizada de como estas partes do sistema est\u00e3o fazendo estes acessos. Com isso, vemos como resultado aplica\u00e7\u00f5es com baixa performance devido aos v\u00e1rios e desnecess\u00e1rios acessos ao banco \u201cround-trips\u201d que se multiplicam a medida do n\u00famero de usu\u00e1rios simultaneamente conectados.<\/p>\n<p><strong>Solu\u00e7\u00e3o:<\/strong> Analisar quantas vezes a aplica\u00e7\u00e3o est\u00e1 acessando o banco, o porqu\u00ea do acesso e assim tentar uma forma de evitar este acesso. Neste momento, muitos profissionais pecam por n\u00e3o conhecerem recursos b\u00e1sicos de banco de dados e de SQL-ANSI, principalmente pelas propaga\u00e7\u00f5es de frameworks ORM. Qualquer meio \u00e9 v\u00e1lido, alguns recursos usados para alcan\u00e7ar isso s\u00e3o o uso de VIEWS, JOIN, SUBQUERYS e o Pattern<a href=\"http:\/\/fernandofranzini.wordpress.com\/2014\/09\/22\/pattern-store-procedure-facade\/\" target=\"_blank\" rel=\"noopener noreferrer\"> Store Procedure Facade<\/a>. Todos os programadores t\u00eam que possuir um lema em mente: \u201cO acesso remoto \u00e9 que mais degrada a performance de uma aplica\u00e7\u00e3o e o acesso ao banco de dados \u00e9 um deles, ent\u00e3o eu tenho que fazer de tudo para evitar ou minimizar ao m\u00e1ximo.\u201c<\/p>\n<p><strong>\u00cdndices adequados<\/strong><\/p>\n<p>Criar os \u00edndices para as todas as tabelas que sofrem consultas na aplica\u00e7\u00e3o.<\/p>\n<p><strong>Problema:<\/strong> Muitos programadores n\u00e3o conhece o m\u00ednimo dos fundamentos de banco de dados, criando bancos sem nenhum \u00edndice de busca para as tabelas que sofrem alto n\u00famero de SELECT + WHERE CAMPO. A quest\u00e3o problem\u00e1tica \u00e9 que quando uma tabela sem \u00edndice sofre um SELECT +WHERE CAMPO, o registro \u00e9 buscado, na maioria das vezes, da pior e mais demorada forma poss\u00edvel, que \u00e9 o \u201csequencialmente\u201d. A pior not\u00edcia \u00e9 que isso \u00e9 um problema cumulativo, ou seja, quanto mais registro existente, mais demorada fica a consulta. J\u00e1 tive experi\u00eancias de diminuir o tempo de um procedimento de fechamento mensal em 50% do tempo, pelo simples ato de criar os \u00edndices nas tabelas usados pelo processo.<\/p>\n<p><strong>Solu\u00e7\u00e3o:<\/strong> Para cada SELECT que o programa faz, em cada tabela, verifique os campos de busca colocados no WHERE e, assim, crie um \u00edndice para cada um deles.<\/p>\n<p><strong>Consultas gigantescas<\/strong><\/p>\n<p>Sistemas que permitem o usu\u00e1rio consultar e trazer do banco de dados um alto n\u00famero de registros.<\/p>\n<p><strong>Problema<\/strong>: Algumas situa\u00e7\u00f5es que costumam ocorrer em sistemas no modelo desktop, ou mais conhecido como \u201cFAT CLIENT\u201d, n\u00e3o se encaixam em aplicativos web. Um destes casos \u00e9 quando sistemas permitem aos usu\u00e1rios filtrar e trazer do banco de dados consultas com um alto n\u00famero de registros complemente desnecess\u00e1rio. Em casos em que o modelo era desktop, isso n\u00e3o acarretava problemas devido \u00e0 pr\u00f3pria natureza da solu\u00e7\u00e3o. Entretanto em sistemas web, onde recursos de execu\u00e7\u00e3o s\u00e3o compartilhados e o numero de acesso simult\u00e2neos \u00e9 ilimitado, o sistema estar\u00e1 gastando um alto e precioso n\u00famero relevante de mem\u00f3ria.<\/p>\n<p>Explicando de forma pr\u00e1tica, eu j\u00e1 peguei sistemas na redondezas onde os programadores estavam replicando a arquitetura que continha uma camada de persist\u00eancia CRUD. O problema era que o framework replicava um m\u00e9todo que sempre retornava todos os registros existente. Isto estava sendo propagado para todo o sistema e seus processos relacionados. Se paramos para analisar, mecanismos de busca s\u00e3o disponibilizados ao usu\u00e1rio para que ele tenha autonomia de buscar registros individuais ou grupos l\u00f3gicos deles. Qual seria o motivo, ou o que poderia fazer um usu\u00e1rio com 500 linhas de resultados de uma consulta? Que ser humano na face da terra gostaria de visualizar 500 registros em uma olhada? Mesmo que a regra de neg\u00f3cio ainda apoiasse o caso, o usu\u00e1rio final, sendo um humano comum, n\u00e3o teria tamanha visibilidade para isso.<\/p>\n<p><strong>Solu\u00e7\u00e3o<\/strong>: Os processos do sistema em quest\u00e3o devem ser analisados e devem ser implementadas valida\u00e7\u00f5es l\u00f3gicas corretas, que n\u00e3o permitam\u00a0 executar consultas que retornem uma alto n\u00famero de registros no banco de dados. Duas pr\u00e1ticas neste t\u00f3pico s\u00e3o bem comuns \u2013 o uso sistem\u00e1tico de pagina\u00e7\u00e3o, e a implementa\u00e7\u00e3o de filtros inteligentes, baseados em regra do pr\u00f3prio neg\u00f3cio, que n\u00e3o deixassem a ocorr\u00eancia de grandes intervalos. Como tudo na vida, existem exce\u00e7\u00f5es e podemos, sim, encontrar situa\u00e7\u00f5es em sistemas que teriam a necessidade de consultar grandes volumes de registros, mas isso j\u00e1 est\u00e1 mais que comprovado que \u00e9 uma porcentagem pequena e restrita do total da automa\u00e7\u00e3o.<\/p>\n<p><strong>Ordena\u00e7\u00e3o de dados<\/strong><\/p>\n<p>Ordenar dados em mem\u00f3ria usando java ao inv\u00e9s de usar ORDER BY.<\/p>\n<p><strong>Problema<\/strong>: Uma funcionalidade muito comum \u00e9 disponibilizar a ordena\u00e7\u00e3o das tabelas apresentadas na aplica\u00e7\u00e3o pelas suas pr\u00f3prias colunas. A quest\u00e3o problem\u00e1tica \u00e9 quando a aplica\u00e7\u00e3o efetua mais um acesso ao banco a cada ordena\u00e7\u00e3o requisitada. Ou seja, o programador usa o recurso de SELECT ORDER BY para fazer a ordena\u00e7\u00e3o.<\/p>\n<p><strong>Solu\u00e7\u00e3o<\/strong>: Transformar as linhas da tabela em objetos Java e, assim, orden\u00e1-los usando recursos do JSE, evitando gasto com tempo, acesso ao banco e recursos de mem\u00f3ria. Esta solu\u00e7\u00e3o pode ser facilmente implementando com a interface <a href=\"http:\/\/lkamal.blogspot.com\/2008\/07\/java-sorting-comparator-vs-comparable.html\" target=\"_blank\" rel=\"noopener noreferrer\">Comparable<\/a>.<\/p>\n<p><strong>Pool de conex\u00f5es<\/strong><\/p>\n<p>Use indiscutivelmente a abordagem de pool como paradigma de acesso ao banco de dados.<\/p>\n<p><strong>Problema<\/strong>: Eu realmente n\u00e3o sei o motivo, mas j\u00e1 peguei alguns aplicativos web por a\u00ed que abrem e fecham objetos de conex\u00e3o com o banco de dados a cada requisi\u00e7\u00e3o. Ou seja, a cada pedido enviado ao container Java, no m\u00ednimo duas chamadas remotas s\u00e3o efetuadas, uma para autenticar o usu\u00e1rio\/senha e outra para efetuar a comando SQL desejado. Esta op\u00e7\u00e3o \u00e9 uma das piores gafes que um desenvolvedor web pode fazer para deixar o sistema com a pior performance poss\u00edvel, sem falar que o sistema pode \u201cbaleiar\u201d o banco quando o n\u00famero de acesso simult\u00e2neos exceder a capacidade de resposta do determinado banco de dados.<\/p>\n<p><strong>Solu\u00e7\u00e3o<\/strong>: Na web existe uma \u00fanica solu\u00e7\u00e3o comprovada que \u00e9 o uso efetivo da abordagem de Pool de conex\u00f5es. No momento da disponibiliza\u00e7\u00e3o \u2013 deploy da aplica\u00e7\u00e3o, o sistema deve abrir um n\u00famero X de conex\u00f5es com o banco de dados que ser\u00e1 posteriormente usado em toda a aplica\u00e7\u00e3o. Esta abordagem mistura o conceito de compartilhamento e concorr\u00eancia, sendo que pedidos em tempos diferentes reutiliza\u00e7\u00e3o a mesma conex\u00e3o e pedidos simult\u00e2neos usar\u00e3o diferentes conex\u00f5es. Este n\u00famero X deve ser levantando e configurado de forma parametrizada, de acordo com o perfil da aplica\u00e7\u00e3o e do modo\/quantidades que os usu\u00e1rios estar\u00e3o gastando conex\u00f5es durante utiliza\u00e7\u00e3o do sistema.<\/p>\n<p><strong>Cache<\/strong><\/p>\n<p>Cachear informa\u00e7\u00f5es que sofrem alto \u00edndice de acesso e baixa ocorr\u00eancia de altera\u00e7\u00e3o.<\/p>\n<p><strong>Problema<\/strong>: Sistemas em geral implementam administra\u00e7\u00e3o de informa\u00e7\u00f5es na qual poder\u00edamos classificar em dois tipos: dados de manuten\u00e7\u00e3o\/par\u00e2metrose de processos:<\/p>\n<ul>\n<li>Manuten\u00e7\u00e3o\/Par\u00e2metros &#8211; informa\u00e7\u00f5es que os sistemas t\u00eam que guardar, usadas como parte do processo, que n\u00e3o possuem um fim nelas mesmas. Este tipo de forma\u00e7\u00e3o frequentemente sofre um baixo \u00edndice de manuten\u00e7\u00e3o e um alto n\u00famero de acessos. Ou seja, no escopo da aplica\u00e7\u00e3o, estes dados raramente s\u00e3o alterados e muitos usados.<\/li>\n<\/ul>\n<ul>\n<li>Processos &#8211; informa\u00e7\u00f5es resultantes de processos com regras de neg\u00f3cio do escopo da aplica\u00e7\u00e3o. Estes podem ou n\u00e3o sofrer altera\u00e7\u00f5es e podem ou n\u00e3o ser altamente acessados. Tudo depende da natureza do neg\u00f3cio da aplica\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>A situa\u00e7\u00e3o complicada seria o sistema fazer um acesso ao banco de dados a cada momento que diferentes usu\u00e1rios (concorrentes ou n\u00e3o) necessitassem usar informa\u00e7\u00f5es de manuten\u00e7\u00e3o \u2013 que na grande maioria dos casos s\u00e3o iguais. Ou seja, ter\u00edamos v\u00e1rios usu\u00e1rios acessando o banco de dados repetidas vezes para pegar as mesmas informa\u00e7\u00f5es, gastando assim tempo e mem\u00f3ria de forma desnecess\u00e1ria.<\/p>\n<p><strong>Solu\u00e7\u00e3o<\/strong>: Analisar cuidadosamente e cachear as determinadas informa\u00e7\u00f5es que se encaixam de alguma maneria no perfil de dados de \u201cManuten\u00e7\u00e3o\/Par\u00e2metros\u201d. Conceitualmente, \u00e9 f\u00e1cil visualizar o mecanismos de cache: o primeiro usu\u00e1rio que necessitar da determinada informa\u00e7\u00e3o efetuar\u00e1 um acesso ao banco e cachear\u00e1 os dados em algum lugar na mem\u00f3ria, fazendo com que os pr\u00f3ximos usu\u00e1rios n\u00e3o precisem gastar tempo e mem\u00f3ria repetindo o ciclo. O cache \u00e9 atualizado quando estes dados forem atualizados de alguma maneira no sistema, bem como o perfil deles j\u00e1 mostrou que seria um caso dif\u00edcil de acontecer.<\/p>\n<p><strong>Segue um resumo das estrat\u00e9gias gerais:<\/strong><\/p>\n<ul>\n<li>Use cache de global para evitar consultas repetitivas dentro da solu\u00e7\u00e3o global para dados que n\u00e3o sofram altera\u00e7\u00e3o de n\u00edvel global;<\/li>\n<li>Use cache de sess\u00e3o para evitar consultas repetitivas dentro da mesma sess\u00e3o para casos no qual dados estes dados n\u00e3o sofram altera\u00e7\u00e3o durante a o tempo de dura\u00e7\u00e3o da sess\u00e3o;<\/li>\n<li>Use cache de <a href=\"http:\/\/fernandofranzini.wordpress.com\/2014\/09\/17\/aprenda-o-escopo-thread-local\/\" target=\"_blank\" rel=\"noopener noreferrer\">thread local<\/a> para evitar consultas repetitivas dentro da mesma requisi\u00e7\u00e3o para casos no qual estes dados os sofram altera\u00e7\u00e3o durantes as requisi\u00e7\u00f5es.<\/li>\n<\/ul>\n<p>A pr\u00e1tica do cache, entretanto, n\u00e3o \u00e9 algo simples ou trivial; demandando tempo e esfor\u00e7o para ser implementado. Eu poderia sugerir implementa\u00e7\u00f5es prontas como o <a href=\"http:\/\/ehcache.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">EhCache<\/a>, ou servi\u00e7os de cache disponibilizados pelos frameworks ORM. Veja que a utiliza\u00e7\u00e3o s\u00f3 vale a pena se os dados realmente possu\u00edrem um alto \u00edndice de acesso. Com esta abordagem, a aplica\u00e7\u00e3o consegue reduzir em m\u00e9dia at\u00e9 60% o acesso ao banco de dados.<\/p>\n<p><strong>Ciclo de vida de objetos<\/strong><\/p>\n<p>Controle efetivo da cria\u00e7\u00e3o de objetos durante a execu\u00e7\u00e3o do programa.<\/p>\n<p><strong>Problema<\/strong>: Algo que precisamos sempre lembrar durante a programa\u00e7\u00e3o \u00e9 que o operador new aloca fisicamente o objeto da mem\u00f3ria, gastando espa\u00e7o no HEAP da aplica\u00e7\u00e3o. A primeira quest\u00e3o problem\u00e1tica \u00e9 que percebo que os programadores usam o new de forma displicente, sem nem ao menos parar para pensar em que contexto da aplica\u00e7\u00e3o est\u00e1 usando. Tudo \u00e9 motivo para fazer um new! Eu j\u00e1 vi casos em que para reiniciar o estado do objeto, o programador dava um new na refer\u00eancia.<\/p>\n<p><strong>Solu\u00e7\u00e3o:<\/strong> O programador tem que sair desse comodismo e come\u00e7ar a analisar todos os seus new! Duas perguntas resolvem o problema: por que estou alocando esse objeto? Quantas vezes esse c\u00f3digo vai ser executado?<\/p>\n<p>Estas duas perguntas v\u00e3o consciencializar o programador daquela situa\u00e7\u00e3o, levando-o no m\u00ednimo a tomar uma das duas decis\u00f5es abaixo:<\/p>\n<ul>\n<li>Reutilizar Objetos: ao inv\u00e9s de ficar sempre fazendo new, ele pode aumentar a visibilidade do escopo daquele objeto e assim reus\u00e1-lo, restartando seu estado;<\/li>\n<\/ul>\n<ul>\n<li>Reduzir o Escopo: reduzir o escopo dos objetos vai deix\u00e1-los dispon\u00edveis mais r\u00e1pido para o coletor de lixo. Se for preciso, use escopos l\u00f3gicos menores com { }.<\/li>\n<\/ul>\n<p>Esta solu\u00e7\u00e3o \u00e9 uma das mais dif\u00edceis a serem implementadas, porque invadem a \u201ccultura\u201d do programador de se autocriticar. Mas quero anim\u00e1-los dizendo que a batalha da economia de mem\u00f3ria e performance se ganha na somat\u00f3ria de detalhes.<\/p>\n<p><strong>Objetos string<\/strong><\/p>\n<p>Controlar o gasto com os objetos Strings.<\/p>\n<p><strong>Problema<\/strong>: Outra coisa que sempre precisamos lembrar \u00e9 que os objetos String chamados de \u201cwrappers\u201d s\u00e3o imut\u00e1veis, ou seja, uma vez instanciados eles nunca mudam. Qualquer opera\u00e7\u00e3o com a String gerar\u00e1 uma terceira String. O problema aqui \u00e9 o uso abusivo, desnecess\u00e1rio e inconsciente das String durante a execu\u00e7\u00e3o do programa.<\/p>\n<p><strong>Solu\u00e7\u00e3o<\/strong>: Segue a mesma ideia do t\u00f3pico 5. O programador deve analisar a quest\u00e3o da necessidade e entender o por qu\u00ea daquele uso. Duas op\u00e7\u00f5es surgem para contornar a situa\u00e7\u00e3o:<\/p>\n<ol>\n<li>Usar final static para as Strings que se encaixam no contexto de est\u00e1ticas (SQLs, mensagens). Ou seja, somente ser\u00e1 gasto um objeto para todas as execu\u00e7\u00f5es do programa;<\/li>\n<li>Usar StringBuffer\/StringBuilder para as String que sofrem altera\u00e7\u00f5es constantes ou para situa\u00e7\u00f5es de manipula\u00e7\u00e3o de arquivos.<\/li>\n<\/ol>\n<p><strong>Configura\u00e7\u00f5es de mem\u00f3ria da JVM<\/strong><\/p>\n<p><strong>Problema<\/strong>: Mesmo depois de todas as precau\u00e7\u00f5es tomadas, a aplica\u00e7\u00e3o ainda pode gastar mais mem\u00f3ria do valor default previamente configurado na JVM.<\/p>\n<p><strong>Solu\u00e7\u00e3o<\/strong>: Neste casos, \u00e9 preciso fazer um estudo, apurando a m\u00e9dia de mem\u00f3ria gasta pela aplica\u00e7\u00e3o, usando alguma ferramenta de profile e, assim, configurar um adequado n\u00famero razo\u00e1vel de mem\u00f3ria.<\/p>\n<p>\u00c9 isso, pessoal! O artigo fica aberto para sugest\u00f5es e novas ideias.<\/p>\n<p>&#8212;&#8211;<\/p>\n<p>Artigo de Fernando Franzini, publicado originalmente no <a href=\"http:\/\/imasters.com.br\/desenvolvimento\/como-fazer-um-tunning-de-aplicacoes-web\/\" target=\"_blank\" rel=\"noopener noreferrer\">iMasters<\/a>.\t\t\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\t\t\t\tEm ambiente de testes, homologa\u00e7\u00e3o e durante algum tempo inicial de produ\u00e7\u00e3o, o sistema acaba enganosamente funciona lindo e maravilhoso, mas depois de algum tempo, as reclama\u00e7\u00f5es relacionadas com a lentid\u00e3o come\u00e7am a aparecer\t\t\t\t<\/p>\n","protected":false},"author":1,"featured_media":2892,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[40,76,99,158],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v15.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Como fazer um tunning de aplica\u00e7\u00f5es web - Blog DialHost<\/title>\n<meta name=\"description\" content=\"Veja as principais pr\u00e1ticas para reduzir a lentid\u00e3o de sistemas e aumentar a velocidade de sua aplica\u00e7\u00e3o\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Como fazer um tunning de aplica\u00e7\u00f5es web - Blog DialHost\" \/>\n<meta property=\"og:description\" content=\"Veja as principais pr\u00e1ticas para reduzir a lentid\u00e3o de sistemas e aumentar a velocidade de sua aplica\u00e7\u00e3o\" \/>\n<meta property=\"og:url\" content=\"\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog DialHost\" \/>\n<meta property=\"article:publisher\" content=\"http:\/\/www.facebook.com\/DialHost\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/DialHost\" \/>\n<meta property=\"article:published_time\" content=\"2014-10-15T16:04:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dialhost.com.br\/blog\/wp-content\/uploads\/2019\/04\/og-image.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@dialhost\" \/>\n<meta name=\"twitter:site\" content=\"@dialhost\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#organization\",\"name\":\"DialHost Internet\",\"url\":\"https:\/\/www.dialhost.com.br\/blog\/\",\"sameAs\":[\"http:\/\/www.facebook.com\/DialHost\",\"https:\/\/www.instagram.com\/dialhost_oficial\/\",\"https:\/\/www.linkedin.com\/company\/dialhost-internet\",\"https:\/\/www.youtube.com\/channel\/UCAiqiX8IiqTSfA8wQhpzgXQ\",\"https:\/\/twitter.com\/dialhost\"],\"logo\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#logo\",\"inLanguage\":\"pt-BR\",\"url\":\"https:\/\/www.dialhost.com.br\/blog\/wp-content\/uploads\/2019\/03\/marca-dialhost.png\",\"width\":81,\"height\":81,\"caption\":\"DialHost Internet\"},\"image\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#logo\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#website\",\"url\":\"https:\/\/www.dialhost.com.br\/blog\/\",\"name\":\"Blog DialHost\",\"description\":\"Os melhores conte\\u00fados sobre Desenvolvimento Web, Marketing e Neg\\u00f3cios\",\"publisher\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/www.dialhost.com.br\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#primaryimage\",\"inLanguage\":\"pt-BR\",\"url\":\"\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#webpage\",\"url\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/\",\"name\":\"Como fazer um tunning de aplica\\u00e7\\u00f5es web - Blog DialHost\",\"isPartOf\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#primaryimage\"},\"datePublished\":\"2014-10-15T16:04:55+00:00\",\"dateModified\":\"2014-10-15T16:04:55+00:00\",\"description\":\"Veja as principais pr\\u00e1ticas para reduzir a lentid\\u00e3o de sistemas e aumentar a velocidade de sua aplica\\u00e7\\u00e3o\",\"breadcrumb\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"\/blog\/\",\"url\":\"\/blog\/\",\"name\":\"In\\u00edcio\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@type\":\"WebPage\",\"@id\":\"\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/\",\"url\":\"\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/\",\"name\":\"Como fazer um tunning de aplica\\u00e7\\u00f5es web\"}}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#webpage\"},\"author\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#\/schema\/person\/a0b10cbe35449dea173a06d4664f9fcc\"},\"headline\":\"Como fazer um tunning de aplica\\u00e7\\u00f5es web\",\"datePublished\":\"2014-10-15T16:04:55+00:00\",\"dateModified\":\"2014-10-15T16:04:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#webpage\"},\"publisher\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/como-fazer-um-tunning-de-aplicacoes-web\/#primaryimage\"},\"keywords\":\"banco de dados,desenvolvimento,feed de parceiros,noticias\",\"articleSection\":\"Dicas e Not\\u00edcias\",\"inLanguage\":\"pt-BR\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#\/schema\/person\/a0b10cbe35449dea173a06d4664f9fcc\",\"name\":\"DialHost Internet\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.dialhost.com.br\/blog\/#personlogo\",\"inLanguage\":\"pt-BR\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/05feec2f99aef1c42b09aeaa637ee66f?s=96&r=g\",\"caption\":\"DialHost Internet\"},\"description\":\"H\\u00e1 mais de 18 anos proporcionando um servi\\u00e7o de hospedagem de sites voltado 100% na Experi\\u00eancia e Sucesso do Cliente, prezando a qualidade, transpar\\u00eancia e seguran\\u00e7a.\",\"sameAs\":[\"https:\/\/www.facebook.com\/DialHost\",\"https:\/\/www.instagram.com\/dialhost_oficial\/\",\"https:\/\/www.linkedin.com\/company\/dialhost-internet\",\"https:\/\/twitter.com\/dialhost\",\"https:\/\/www.youtube.com\/channel\/UCAiqiX8IiqTSfA8wQhpzgXQ\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/posts\/2890"}],"collection":[{"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/comments?post=2890"}],"version-history":[{"count":0,"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/posts\/2890\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/media\/2892"}],"wp:attachment":[{"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/media?parent=2890"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/categories?post=2890"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dialhost.com.br\/blog\/wp-json\/wp\/v2\/tags?post=2890"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}