{"id":52136,"date":"2018-02-07T08:00:18","date_gmt":"2018-02-07T07:00:18","guid":{"rendered":"https:\/\/www.humanlevel.com\/sin-categorizar\/optimizacion-de-javascript.html"},"modified":"2018-02-07T09:00:00","modified_gmt":"2018-02-07T08:00:00","slug":"javascript-optimization","status":"publish","type":"post","link":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization","title":{"rendered":"JavaScript optimization"},"content":{"rendered":"<p>With the shift of users from desktop to mobile devices, <strong>client-side optimization of web pages<\/strong> is becoming more important than in the past, matching the importance of server-side optimization. Making a website work fast on devices that are slower and with connections that, depending on the coverage, can be bad or even suffer outages, is not an easy task, but it is necessary, because having <strong>higher speed will mean more satisfied users who will visit us more often <\/strong> and\u00a0<a href=\"https:\/\/webmasters.googleblog.com\/2018\/01\/using-page-speed-in-mobile-search.html?m=1\" target=\"_blank\" rel=\"noopener noreferrer\">better positioning in mobile searches<\/a>.<\/p>\n<p>In this article I will discuss some of the points to pay more attention to when <strong>optimizing JavaScript running on the client<\/strong>. Firstly, we will see how to optimize its <strong>download and compilation<\/strong>, and secondly, how to optimize <strong>its execution<\/strong> so that the page has a good performance. Understanding by performance, the definition given by Google&#8217;s <a href=\"https:\/\/web.dev\/rail\/\" target=\"_blank\" rel=\"noopener noreferrer\">RAIL<\/a> model. These acronyms stand for:<br \/>\n<a name=\"rail\"><\/a><\/p>\n<ul>\n<li>Interface <strong>response\u00a0<\/strong>in less than 100ms.<\/li>\n<li>Full draw <strong>animations\u00a0<\/strong>every 16ms which is 60 FPS or 60 frames per second.<\/li>\n<li><strong>Disabled<\/strong>: when the user does not interact with the page what is executed in the background should not last more than 50ms.<\/li>\n<li><strong>Load<\/strong>: the page must load in 1000ms.<\/li>\n<\/ul>\n<p>These times should be achieved in the worst case (when running the web on an old cell phone), with low processor and memory resources.<\/p>\n<figure id=\"attachment_30452\" aria-describedby=\"caption-attachment-30452\" style=\"width: 890px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-full wp-image-30452\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/carga-movil-vs-escritorio.png\" alt=\"Mobile web load time compared to desktop.\" width=\"900\" height=\"428\" srcset=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/carga-movil-vs-escritorio.png 900w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/carga-movil-vs-escritorio-400x190.png 400w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/carga-movil-vs-escritorio-754x359.png 754w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/carga-movil-vs-escritorio-768x365.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><figcaption id=\"caption-attachment-30452\" class=\"wp-caption-text\">Comparison of site load on mobile and desktop obtained from the public <a href=\"https:\/\/developer.chrome.com\/docs\/crux\/\" target=\"_blank\" rel=\"noopener noreferrer\">Chrome User Experience Report<\/a> database. The histogram shows the number of users who obtained each response time. As can be seen, the maximum peak in mobile is in 2.5s and in desktop in 1.5s.<\/figcaption><\/figure>\n<p>In the following I explain, firstly, the actions necessary to optimize the download and compilation and, secondly, the actions necessary to optimize the execution of the code, being this part more technical, but not less important.<\/p>\n<h2>Actions to optimize the download and compilation of JavaScript code<\/h2>\n<h3>Browser caching<\/h3>\n<p>Here we have two options. The first is to use <strong>the JavaScript Cache API<\/strong>, which we can make use of by installing a service worker. The second is to use <strong>the HTTP protocol cache<\/strong>. If we use the Cache API our application could have the option to run in offline mode. If we use the HTTP protocol cache, roughly speaking, we must configure it using the <strong>Cache-control<\/strong> parameter <strong>with the values public and max-age<\/strong>, with a large cache time, such as one year. Then, if we want to invalidate this cache we will rename the file.<\/p>\n<h3>Compressing with Brotli q11 and Gzip<\/h3>\n<p>By compressing the JavaScript code, we are <strong>reducing the bits that are transmitted over the network<\/strong> and, therefore, the transmission time, but it must be taken into account that we are <strong>increasing processing time on both the server and client side<\/strong>The first one must compress the file and the second one must decompress it. We can save the first time if we have a <strong>cache of compressed files on the server<\/strong>, but the decompression time on the client plus the compressed transmission time may be longer than the transmission time of the decompressed file, making this technique <strong>slow down the download<\/strong>. This will occur only <strong>with very small files and at high transmission speeds<\/strong>. We cannot know the user&#8217;s transmission speed, but we can tell our server not to compress very small files, for example, tell it not to compress files smaller than 280 bytes. In connections with high speeds, above 100Mb\/s, this value should be much higher, but it<strong> is optimized for those who have mobile connections with poor coverage<\/strong>, where the loss of performance is more pronounced, although in fast connections it goes a little slower.<\/p>\n<p>The new <strong>Brotli<\/strong> compression algorithm <strong>improves compression<\/strong> over <a href=\"https:\/\/www.humanlevel.com\/en\/blog\/seo\/gzip-compression-in-depth\" target=\"_blank\" rel=\"noopener noreferrer\">Gzip<\/a> by 17%. If the browser sends, in the HTTP protocol header, the value &#8220;br&#8221; in the accept-encoding parameter, this means that the server can send you the file in Brotli format instead of Gzip.<\/p>\n<h3>Minimize<\/h3>\n<p>It consists of using an automatic tool to remove comments, spaces, tabs and substitute variables to make the <strong>code take up less space<\/strong>. Minimized files should be cached on the server or generated already minimized at the time of upload, because if the server has to minimize them with every request, it will have a negative impact on performance.<\/p>\n<h3>Unify JavaScript code<\/h3>\n<p>This is an optimization technique that is not very important if our website works with HTTPS and HTTP2, since this protocol sends the files as if they were one, but if our website works with HTTP1.1 or we expect to have many customers with older browsers using this protocol, <strong>unification is necessary to optimize the download<\/strong>. <strong>But do not go overboard and unify all the code of the web in a single file<\/strong>, because if you send only the code that the user needs on each page, you can reduce the bytes to be downloaded considerably. For this purpose <strong>We will separate the code base that is necessary for the entire portal from what will be executed on each individual page.<\/strong> In this way we will have two JavaScript files for each page, one with the basic libraries that will be common for all pages and another with the specific code of the page. With a tool like <strong>webpack<\/strong> we can unify and minimize these two groups of files in our development project. Make sure that the tool you use for this purpose generates the so-called &#8220;.<strong>source maps<\/strong>&#8220;. These are .map files that are associated in the header of the final file and in which the relationship between the minimized and unified code and the real source code files is established. This way we can later debug the code without problems.<\/p>\n<p>The option to unify everything in a single larger file has the advantage that you can cache all the JavaScript code of the website in the browser on the first visit and, on the next load, the user will not have to download all the JavaScript code. So I recommend this option only if the byte savings are practically negligible compared to the previous technique and we have a low bounce rate.<\/p>\n<h3>Mark JavaScript as asynchronous<\/h3>\n<p>We must include the JavaScript as follows:<\/p>\n<pre>&lt;script async src=\"\/codigo.js\" \/&gt;<\/pre>\n<p>In this way we are preventing the appearance of the script tag from blocking the DOM construction stage of the page.<\/p>\n<h3>Do not use JavaScript embedded in the page<\/h3>\n<p>Using the script tag to embed code in the page also blocks the construction of the DOM and even more so if the document.write() function is used. In other words, this is prohibited:<\/p>\n<p>&lt;script&gt;documente.write(&#8220;Hello world!&#8221;);&lt;\/script&gt;<\/p>\n<h3>Load JavaScript in the page header with async<\/h3>\n<p>Before the <strong>async<\/strong> tag was available, it was recommended to put all script tags at the end of the page to avoid blocking the construction of the page. This is no longer necessary, in fact it is better if it is at the top inside the tag &lt;head&gt;, so that <strong>the JavaScript starts downloading, parsing and compiling as soon as possible<\/strong>, since these phases are the ones that will take the longest. If this attribute is not used, the JavaScript must be at the end.<\/p>\n<h3>Remove unused JavaScript<\/h3>\n<p>At this point <strong>we are not only reducing the transmission time, but also the time it takes for the browser to parse and compile the code<\/strong>. To do so, the following points must be taken into account:<\/p>\n<ul>\n<li>If it is detected that a <strong>feature is not being used by users<\/strong>, we can remove it and all its associated JavaScript code, so that the web will load faster and users will appreciate it.<\/li>\n<li>It is also possible that we have included by mistake some <strong>library that is not necessary<\/strong> or that we have libraries that offer some functionality that we already have natively in all browsers, without the need to use additional code and in a faster way.<\/li>\n<li>Finally, if we want to optimize to the extreme, no matter how long it takes, we should <strong>remove the code we are not using from the libraries<\/strong>. But I do not recommend it, because we never know when we might need it again.<\/li>\n<\/ul>\n<h3>Defer loading of JavaScript that is not required:<\/h3>\n<p>This should be done with those<strong> functionalities that are not necessary for the initial drawing of the page<\/strong>. These are functionalities for which the user must perform a certain action in order to execute it. That way <strong>we avoid loading and compiling JavaScript code that would delay the initial display<\/strong>. Once the page is fully loaded, we can start loading those functionalities so that they are immediately available when the user starts interacting. Google in the RAIL model recommends that this deferred loading be done in 50ms blocks so that it does not influence the user&#8217;s interaction with the page. If the user interacts with a feature that has not yet been loaded, we must load it at that time.<\/p>\n<h2>Actions to optimize JavaScript code execution<\/h2>\n<h3>Avoid using too much memory<\/h3>\n<p>We can&#8217;t say how much memory will be too much, but we can say that we should always try <strong>not to use more than necessary<\/strong>, because we don&#8217;t know how much memory the device that will run the web will have. <strong>When the browser&#8217;s garbage collector is executed, JavaScript execution is stopped,<\/strong> and this happens every time our code asks the browser to reserve new memory. If this happens frequently, the page will be slow.<\/p>\n<p>In <strong>the &#8220;Memory&#8221; tab of Chrome&#8217;s developer tools<\/strong>, we can see the memory occupied by each JavaScript function:<\/p>\n<figure id=\"attachment_30375\" aria-describedby=\"caption-attachment-30375\" style=\"width: 624px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-full wp-image-30375\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/memoria-reservada.png\" alt=\"Reserved memory per JavaScript function.\" width=\"634\" height=\"243\" srcset=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/memoria-reservada.png 634w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/memoria-reservada-400x153.png 400w\" sizes=\"auto, (max-width: 634px) 100vw, 634px\" \/><figcaption id=\"caption-attachment-30375\" class=\"wp-caption-text\">Reserved memory per function<\/figcaption><\/figure>\n<h3>Prevent memory leaks<\/h3>\n<p>If we have a <strong>memory leak in a loop<\/strong>, the page will reserve more and more memory, occupying all the available memory of the device and making everything slower and slower. This bug usually occurs in carousels and image sliders.<\/p>\n<p>In Chrome we can analyze if our website is leaking memory by recording a timeline in the <strong>performance tab of the developer tools<\/strong>:<\/p>\n<figure id=\"attachment_30373\" aria-describedby=\"caption-attachment-30373\" style=\"width: 984px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-full wp-image-30373\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/memory-leak.png\" alt=\"Memory leak display in the performance tab of Google Chrome.\" width=\"994\" height=\"911\" srcset=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/memory-leak.png 994w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/memory-leak-400x367.png 400w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/memory-leak-754x691.png 754w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/memory-leak-900x825.png 900w\" sizes=\"auto, (max-width: 994px) 100vw, 994px\" \/><figcaption id=\"caption-attachment-30373\" class=\"wp-caption-text\">This is what a memory leak looks like in the &#8220;Performance&#8221; tab of Google Chrome where we can observe a constant growth of DOM and JS Heap nodes.<\/figcaption><\/figure>\n<p>Memory leaks are usually caused by <strong>chunks of the DOM that are removed from the page but have some variable that refers to them<\/strong> and, therefore, the garbage collector cannot remove them and therefore the <a href=\"https:\/\/www.humanlevel.com\/en\/blog\/seo\/indexability-shadow-dom\" target=\"_blank\" rel=\"noopener noreferrer\">not understanding how variable scoping and closures work in JavaScript<\/a>.<\/p>\n<figure id=\"attachment_30376\" aria-describedby=\"caption-attachment-30376\" style=\"width: 558px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-full wp-image-30376\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/nodos-desacoplados.png\" alt=\"Trees decoupled from the DOM.\" width=\"568\" height=\"731\" srcset=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/nodos-desacoplados.png 568w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/nodos-desacoplados-400x515.png 400w\" sizes=\"auto, (max-width: 568px) 100vw, 568px\" \/><figcaption id=\"caption-attachment-30376\" class=\"wp-caption-text\">Detached DOM trees that are occupying memory because they are referenced by variables.<\/figcaption><\/figure>\n<h3>Use web workers when you need to execute code that requires a long execution time.<\/h3>\n<p>All processors nowadays are multithreaded and multicore but JavaScript has traditionally been a single-threaded language and, although it has timers, these are executed in the same thread of execution, in which, in addition, the interaction with the interface is executed, so <strong>while executing JavaScript the interface crashes<\/strong> and if it takes longer than 50ms it will be noticeable. <strong>Web workers and service workers bring multithreaded execution to JavaScript<\/strong>, although they do not allow direct access to the DOM, so we will have to think about how to delay access to it, in order to apply web workers in cases where we have code that takes more than 50ms to execute.<\/p>\n<h3>Using the Fetch API (AJAX)<\/h3>\n<p>The use of the Fetch API or <a href=\"https:\/\/www.humanlevel.com\/en\/digital-marketing-dictionary\/ajax\" target=\"_blank\" rel=\"noopener noreferrer\">AJAX<\/a> is also a good way for the user to perceive a faster loading time, but we should not use it in the initial loading, but in the subsequent navigation and in a way that is indexable. The best way to implement it is to make use of a framework that uses <a href=\"https:\/\/www.humanlevel.com\/en\/blog\/seo\/indexability-shadow-dom\" target=\"_blank\" rel=\"noopener noreferrer\">Universal JavaScript<\/a>.<\/p>\n<h3>Prioritizes access to local variables<\/h3>\n<p>JavaScript first looks to see if the variable exists locally and continues to look for it in higher scopes, the latter being global variables. <strong>JavaScript accesses local variables faster because it does not have to look up the variable<\/strong> in higher environments to find it, so this is a good strategy <strong>store in local variables those variables of a higher scope that we are going to access several times <\/strong>and, in addition, do not create new scopes with closures or with the with and try catch statements, without it being necessary.<\/p>\n<h3>If you access a DOM element several times save it in a local variable<\/h3>\n<p><strong>DOM access is slow<\/strong>. So if we are going to read the content of an element several times, better save it in a local variable, so the JavaScript won&#8217;t have to look for the element in the DOM every time you want to access its content. But pay attention, if you save in a variable a piece of the DOM that you are going to remove from the page and you are not going to use it anymore, try to assign to &#8220;null&#8221; the variable where you have saved it in order not to cause a memory leak.<\/p>\n<h3>Clustering and minimizing DOM and CSSOM reads and writes<\/h3>\n<p><a name=\"rutarepresentacion\"><\/a><br \/>\nWhen the browser draws a page it goes through<strong> the critical rendering path<\/strong> which follows the following steps on first load:<\/p>\n<ol>\n<li>HTML is received.<\/li>\n<li>Start building the <strong>DOM<\/strong>.<\/li>\n<li>While the DOM is being built, external resources (CSS and JS) are requested.<\/li>\n<li>The <strong>CCSOM<\/strong> (mixture of DOM and CSS) is built.<\/li>\n<li>The <strong>representation tree<\/strong> (the parts of the CSSOM to be drawn) is created.<\/li>\n<li>The geometry of each visible part of the tree in a layer is calculated from the representation tree. This stage is called<strong> layout or reflow<\/strong>.<\/li>\n<li>In the <strong>final painting stage<\/strong>, the layers from step 6 are painted, processed and <strong>composited<\/strong> on top of each other to display the page to the user.<\/li>\n<li>If the <strong>JavaScript<\/strong> has finished compiling, it <strong>is executed<\/strong> (actually, this step could occur at any point after step 3, the sooner the better).<\/li>\n<li>If in the previous step the JavaScript code forces to redo part of the DOM or the CSSOM we go back several steps that will be executed until point 7.<\/li>\n<\/ol>\n<figure id=\"attachment_30393\" aria-describedby=\"caption-attachment-30393\" style=\"width: 1140px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-full wp-image-30393\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/render-tree-construction.png\" alt=\"Construction of the rendering tree or rendering tree.\" width=\"1150\" height=\"537\" srcset=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/render-tree-construction.png 1150w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/render-tree-construction-400x187.png 400w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/render-tree-construction-754x352.png 754w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/render-tree-construction-900x420.png 900w\" sizes=\"auto, (max-width: 1150px) 100vw, 1150px\" \/><figcaption id=\"caption-attachment-30393\" class=\"wp-caption-text\">Construction of the representation tree<\/figcaption><\/figure>\n<p>Although browsers queue changes to the rendering tree and decide when to repaint, if we have a loop in which we read the DOM and\/or CSSOM and modify it on the next line, <strong>the browser may be forced to reflow or repaint the page several times.<\/strong>especially if the next reading depends on the previous writing. This is why it is recommended:<\/p>\n<ul>\n<li>Separate all the reads in a separate loop and do all the writes in one go with the cssText property if it is the CSSOM or innerHTML if it is the DOM, so <strong>the browser will only have to launch a repaint<\/strong>.<\/li>\n<li>If reads depend on previous writes, find a way to rewrite the algorithm so that this is not the case.<\/li>\n<li>If you have no choice but to apply a lot of changes to a DOM element, <strong>take it out of the DOM, make the changes and put it back in where it was<\/strong>.<\/li>\n<li>In Google Chrome, we can analyze what happens in<strong> the critical rendering path<\/strong> with the<strong> Lighthouse<\/strong> tool in the &#8220;Audits&#8221; tab <strong>or in the &#8220;Performance&#8221; tab<\/strong> by recording what happens while the page is loading.<\/li>\n<\/ul>\n<figure id=\"attachment_30420\" aria-describedby=\"caption-attachment-30420\" style=\"width: 725px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-full wp-image-30420\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/lighthouse-1.png\" alt=\"Performance analysis of the Lighthouse tool.\" width=\"735\" height=\"1080\" srcset=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/lighthouse-1.png 735w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/lighthouse-1-400x588.png 400w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/lighthouse-1-720x1058.png 720w\" sizes=\"auto, (max-width: 735px) 100vw, 735px\" \/><figcaption id=\"caption-attachment-30420\" class=\"wp-caption-text\">In this Lighthouse performance analysis of the Google home page, we can see which resources block the critical rendering path.<\/figcaption><\/figure>\n<h3>Use the requestAnimationFrame(callback) function in animations and scroll-dependent effects.<\/h3>\n<p>The function requestAnimationFrame(), makes the function that is passed as a parameter <strong>does not cause a repaint, until the next scheduled<\/strong>. This, in addition to avoiding unnecessary repaints, has the effect that the animations stop while the user is in another tab, saving CPU and device battery.<\/p>\n<p>Scroll-dependent effects are the slowest because the following <strong>DOM properties force a reflow<\/strong> (step 7 of the previous point) when accessing them:<\/p>\n<pre>offsetTop, offsetLeft, offsetWidth, offsetHeight\r\nscrollTop, scrollLeft, scrollWidth, scrollHeight\r\nclientTop, clientLeft, clientWidth, clientHeight\r\ngetComputedStyle() (currentStyle en IE)\r\n<\/pre>\n<p>If in addition to accessing one of these properties, then based on them we can paint a <strong><a href=\"https:\/\/www.humanlevel.com\/en\/digital-marketing-dictionary\/banner\">banner<\/a> or menu that follow you when scrolling or a parallax scroll effect<\/strong>will be made the <strong>repainting of several layers each time the scroll is moved<\/strong>This negatively affects the response time of the interface, so that we can have a scroll that jumps instead of sliding smoothly. Therefore, with these effects, you should save in a global variable the last position of the scroll in the onscroll event, and then use the requestAnimationFrame() function only if the previous animation has finished.<\/p>\n<h3>If there are many similar events, group them together<\/h3>\n<p>If you have 300 buttons that when clicked do pretty much the same thing, we can assign one event to the parent element of the 300 buttons instead of assigning 300 events to each of them. When a button is clicked, the event &#8220;bubbles&#8221; up to the parent and from the parent we can know which button the user clicked and modify the behavior accordingly.<\/p>\n<h3>Beware of events that are triggered several times in a row<\/h3>\n<p>Events such as <em>onmousemove<\/em> or <em>onscroll<\/em> are fired several times in a row while the action is being performed. So make sure that the associated code is not executed more times than necessary, as this is a very common error.<\/p>\n<h3>Avoid string execution with code with eval(), Function(), setTimeout() and setInterval()<\/h3>\n<p>Entering code in a literal to be parsed and compiled during the execution of the rest of the code is quite slow, for example: eval(&#8220;c = a + b&#8221;);. You can always redo the programming to avoid having to do this.<\/p>\n<h3>Implements optimizations that you would apply in any other programming language<\/h3>\n<ul>\n<li>Always use the algorithms with the <strong>lowest computational complexity or cyclomatic complexity <\/strong>for the task to be solved.<\/li>\n<li>Use the <strong>optimal data structures<\/strong> to achieve the above point.<\/li>\n<li>Rewrite the algorithm to <strong>obtain the same result with fewer calculations<\/strong>.<\/li>\n<li><strong>Avoid recursive calls<\/strong> by changing the algorithm to an equivalent one that makes use of a stack.<\/li>\n<li>Make a function with a high cost and repeated calls over several code blocks <strong>store the result in memory for the next call<\/strong>.<\/li>\n<li><strong>Put calculations and repeated function calls in variables<\/strong>.<\/li>\n<li>When <b>traversing a loop, store the loop size in a variable first<\/b>, to avoid recalculating it, at its end condition, at each iteration.<\/li>\n<li><strong>Factor and simplify<\/strong> mathematical formulas.<\/li>\n<li><strong>Replace calculations<\/strong> that do not depend on variables <strong>with constants and leave the calculation commented out<\/strong>.<\/li>\n<li>Use search <strong>arrays<\/strong>: they are used to obtain a value based on another value <strong>instead of using a switch block<\/strong>.<\/li>\n<li>Make the <strong>conditions always more likely to be true <\/strong>to take better advantage of the speculative execution of the processor, since this way the jump prediction will fail less.<\/li>\n<li><strong>Simplify Boolean expressions<\/strong> with the rules of Boolean logic or better yet with Karnaugh maps.<\/li>\n<li>Use <strong>bitwise operators<\/strong> when you can use them to replace certain operations, since these operators use fewer processor cycles. Using them requires knowledge of binary arithmetic, e.g.: x being a value of an integer variable, we can put &#8220;y=x&gt;&gt;1;&#8221; instead of &#8220;y=x\/2;&#8221; or &#8220;y=x&amp;0xFF;&#8221; instead of &#8220;y=x%256&#8221;.<\/li>\n<\/ul>\n<p>These are some of my favorites, the first three being the most important and the ones that require the most study and practice. The latter are micro-optimizations that are only worthwhile if you perform them while writing the code or if it&#8217;s something computationally very expensive like a video editor or a video game, although in those cases you&#8217;d be better off using WebAssembly instead of JavaScript.<\/p>\n<h2>Tools to detect problems<\/h2>\n<p>We have already seen several. Of all of them, <strong>Lighthouse<\/strong> is the easiest to interpret, since it simply gives us a series of points to improve, as the <a href=\"https:\/\/pagespeed.web.dev\/?utm_source=psi&amp;utm_medium=redirect&amp;hl=es\" target=\"_blank\" rel=\"noopener noreferrer\">Google PageSpeed Insights<\/a> tool or many others, such as <a href=\"https:\/\/gtmetrix.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">GTmetrix<\/a>, can also give us. In Chrome we can also use, in the &#8220;More tools&#8221; option of the main menu, the <strong>task manager<\/strong>, to see the memory and CPU used by each tab. For even more technical analysis, we have the <strong>Firefox and Google Chrome developer tools<\/strong>, where we have a tab called &#8220;Performance&#8221; that allows us to analyze quite well the times of each phase, memory leaks, etc. Let&#8217;s look at an example:<\/p>\n<figure id=\"attachment_30399\" aria-describedby=\"caption-attachment-30399\" style=\"width: 984px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-full wp-image-30399\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/performance.png\" alt=\"Google Chrome performance analysis.\" width=\"994\" height=\"911\" srcset=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/performance.png 994w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/performance-400x367.png 400w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/performance-754x691.png 754w, https:\/\/www.humanlevel.com\/wp-content\/uploads\/performance-900x825.png 900w\" sizes=\"auto, (max-width: 994px) 100vw, 994px\" \/><figcaption id=\"caption-attachment-30399\" class=\"wp-caption-text\">In the Google Chrome performance analysis, in the tools menu it allows us to simulate a slower CPU and network, and in it we see, among other things, the frames per second (<a href=\"#rail\">remember that it must be less than 16ms<\/a>) and the phases of <a href=\"#rutarepresentacion\">the critical representation path<\/a> with colors: in blue the file loading time, in yellow the script execution time, in purple the rendering tree construction time (including reflows or layout construction) and in green the painting time. In addition, the time it took to paint each frame and how it turned out.<\/figcaption><\/figure>\n<p>All the information above <strong>can be recorded while the page loads, we execute an action or we scroll<\/strong>. Then we can zoom in on a part of the graphic to see it in detail and, if, as in this case, what takes the longest is the execution of JavaScript, we can display the<strong> Main section and click on the scripts that take the long<\/strong> est time. In the Bottom-Up tab, the tool will show us in detail how the JavaScript is affecting each phase of the critical representation path and in the Summary tab it <strong>will indicate with a warning if it has detected a performance problem in the JavaScript<\/strong>. Clicking on the file will take you to the line that produces the delay.<\/p>\n<figure id=\"attachment_30454\" aria-describedby=\"caption-attachment-30454\" style=\"width: 316px\" class=\"wp-caption aligncenter\"><a class=\"dt-pswp-item\" href=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/summary-devtools.png\" data-dt-img-description=\"Aviso de la pesta\u00f1a resumen de las herramientas de rendimiento\" data-large_image_width=\"326\" data-large_image_height=\"424\"><img loading=\"lazy\" class=\"size-medium wp-image-30454\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/summary-devtools.png\" alt=\"Overview of the devtools tool with performance problem warning.\" width=\"231\" height=\"300\" \/><\/a><figcaption id=\"caption-attachment-30454\" class=\"wp-caption-text\">Performance tools summary tab warning<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>Finally, for even finer analysis, it is advisable to use the <strong>JavaScript Navigation Timing API<\/strong> that allows us to measure in detail how long each part of our code takes from the programming itself.<\/p>\n<h2>Final recommendations<\/h2>\n<p>As you can see, JavaScript optimization is not an easy task and involves a laborious analysis and optimization process that <strong>can easily exceed the development budget we had initially planned<\/strong>. Therefore, there are many of the most famous websites, plugins and themes for the most common content management systems that have many of the problems I have listed.<\/p>\n<p>If your website presents these problems, try to <strong>solve the ones that have the greatest impact on performance first<\/strong> and <strong>always make sure that the optimizations do not affect the maintainability and quality of the code<\/strong>. That is why I do not recommend the use of more extreme optimization techniques, such as removing function calls by replacing them with the code they call, unrolling loops, or using the same variable for everything, so that it loads from cache or from the processor registers, as these are techniques that mess up the code and, in JavaScript runtime compilation, some of them are already applied. So remember:<\/p>\n<blockquote><p>Performance is not a requirement that should ever take precedence over the ease of detecting bugs and adding functionality.<\/p><\/blockquote>\n\n<section class=\"rounded-xlg cta-image\">\n<div>\n<p class=\"gb-text cta-abovetitle\">Tu marca, visible y encontrable<\/p>\n\n\n\n<p class=\"gb-text cta-title\">Est\u00e1s a un paso de dominar tu categor\u00eda online<\/p>\n\n\n\n<a class=\"gb-text btn\" href=\"#anchor-formulario\">Start now<\/a>\n<\/div>\n\n\n\n<img loading=\"lazy\" class=\"gb-media-f45eabef\" alt=\"\" title=\"HL20-SEO\" src=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/HL20-SEO-1-e1770805082974.png\" width=\"500\" height=\"400\"\/>\n<\/section>\n\n","protected":false},"excerpt":{"rendered":"<p>Discover in this guide, the main points to take into account when optimizing the JavaScript client code of a&#8230;<\/p>\n","protected":false},"author":14,"featured_media":47812,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[349],"tags":[534,379],"class_list":["post-52136","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-seo","tag-technical-seo","tag-wpo"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>JavaScript optimization | Human Level<\/title>\n<meta name=\"description\" content=\"Discover with this guide the main points to take into account when optimizing the JavaScript client code of a website.\" \/>\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.humanlevel.com\/en\/blog\/seo\/javascript-optimization\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JavaScript optimization | Human Level\" \/>\n<meta property=\"og:description\" content=\"Discover with this guide the main points to take into account when optimizing the JavaScript client code of a website.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization\" \/>\n<meta property=\"og:site_name\" content=\"Human Level\" \/>\n<meta property=\"article:published_time\" content=\"2018-02-07T07:00:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-02-07T08:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.humanlevel.com\/wp-content\/uploads\/optimizacion-javascript-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"400\" \/>\n\t<meta property=\"og:image:height\" content=\"400\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Ram\u00f3n Saquete\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@daiatron\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ram\u00f3n Saquete\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization\"},\"author\":{\"name\":\"Ram\u00f3n Saquete\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#\\\/schema\\\/person\\\/11ad888926867985985a0210476bae94\"},\"headline\":\"JavaScript optimization\",\"datePublished\":\"2018-02-07T07:00:18+00:00\",\"dateModified\":\"2018-02-07T08:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization\"},\"wordCount\":3898,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/optimizacion-javascript-1.png\",\"keywords\":[\"Technical SEO\",\"WPO\"],\"articleSection\":[\"SEO\\\/GEO\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization\",\"url\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization\",\"name\":\"JavaScript optimization | Human Level\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/optimizacion-javascript-1.png\",\"datePublished\":\"2018-02-07T07:00:18+00:00\",\"dateModified\":\"2018-02-07T08:00:00+00:00\",\"description\":\"Discover with this guide the main points to take into account when optimizing the JavaScript client code of a website.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization#primaryimage\",\"url\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/optimizacion-javascript-1.png\",\"contentUrl\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/optimizacion-javascript-1.png\",\"width\":400,\"height\":400},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\\\/javascript-optimization#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Inicio\",\"item\":\"https:\\\/\\\/www.humanlevel.com\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"SEO\\\/GEO\",\"item\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/blog\\\/seo\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"JavaScript optimization\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#website\",\"url\":\"https:\\\/\\\/www.humanlevel.com\\\/en\",\"name\":\"Human Level\",\"description\":\"Web positioning and online marketing consultant Human Level\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.humanlevel.com\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#organization\",\"name\":\"Human Level\",\"url\":\"https:\\\/\\\/www.humanlevel.com\\\/en\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/logohl25x3.png\",\"contentUrl\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/logohl25x3.png\",\"width\":600,\"height\":93,\"caption\":\"Human Level\"},\"image\":{\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/company\\\/human-level-communications\",\"https:\\\/\\\/www.youtube.com\\\/user\\\/humanlevelcommunica\",\"https:\\\/\\\/bsky.app\\\/profile\\\/humanlevel.bsky.social\",\"https:\\\/\\\/instagram.com\\\/humanlevel\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/en#\\\/schema\\\/person\\\/11ad888926867985985a0210476bae94\",\"name\":\"Ram\u00f3n Saquete\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/1x1-ramon-saquete-26-96x96.jpg\",\"url\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/1x1-ramon-saquete-26-96x96.jpg\",\"contentUrl\":\"https:\\\/\\\/www.humanlevel.com\\\/wp-content\\\/uploads\\\/1x1-ramon-saquete-26-96x96.jpg\",\"caption\":\"Ram\u00f3n Saquete\"},\"description\":\"Web Developer and Technical SEO Consultant at Human Level. He holds degrees in Computer Engineering and Technical Engineering in Computer Systems. He also earned a Higher Vocational Degree in Computer Applications Development and later obtained the Certificate of Pedagogical Aptitude (CAP). He is an expert in WPO and indexability.\",\"sameAs\":[\"https:\\\/\\\/es.linkedin.com\\\/in\\\/ramonsaquete\",\"https:\\\/\\\/x.com\\\/daiatron\"],\"url\":\"https:\\\/\\\/www.humanlevel.com\\\/en\\\/author\\\/ramon\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"JavaScript optimization | Human Level","description":"Discover with this guide the main points to take into account when optimizing the JavaScript client code of a website.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization","og_locale":"en_US","og_type":"article","og_title":"JavaScript optimization | Human Level","og_description":"Discover with this guide the main points to take into account when optimizing the JavaScript client code of a website.","og_url":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization","og_site_name":"Human Level","article_published_time":"2018-02-07T07:00:18+00:00","article_modified_time":"2018-02-07T08:00:00+00:00","og_image":[{"width":400,"height":400,"url":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/optimizacion-javascript-1.png","type":"image\/png"}],"author":"Ram\u00f3n Saquete","twitter_card":"summary_large_image","twitter_creator":"@daiatron","twitter_misc":{"Written by":"Ram\u00f3n Saquete","Est. reading time":"20 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization#article","isPartOf":{"@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization"},"author":{"name":"Ram\u00f3n Saquete","@id":"https:\/\/www.humanlevel.com\/en#\/schema\/person\/11ad888926867985985a0210476bae94"},"headline":"JavaScript optimization","datePublished":"2018-02-07T07:00:18+00:00","dateModified":"2018-02-07T08:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization"},"wordCount":3898,"commentCount":0,"publisher":{"@id":"https:\/\/www.humanlevel.com\/en#organization"},"image":{"@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization#primaryimage"},"thumbnailUrl":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/optimizacion-javascript-1.png","keywords":["Technical SEO","WPO"],"articleSection":["SEO\/GEO"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization","url":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization","name":"JavaScript optimization | Human Level","isPartOf":{"@id":"https:\/\/www.humanlevel.com\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization#primaryimage"},"image":{"@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization#primaryimage"},"thumbnailUrl":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/optimizacion-javascript-1.png","datePublished":"2018-02-07T07:00:18+00:00","dateModified":"2018-02-07T08:00:00+00:00","description":"Discover with this guide the main points to take into account when optimizing the JavaScript client code of a website.","breadcrumb":{"@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization#primaryimage","url":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/optimizacion-javascript-1.png","contentUrl":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/optimizacion-javascript-1.png","width":400,"height":400},{"@type":"BreadcrumbList","@id":"https:\/\/www.humanlevel.com\/en\/blog\/seo\/javascript-optimization#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Inicio","item":"https:\/\/www.humanlevel.com\/en"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/www.humanlevel.com\/en\/blog"},{"@type":"ListItem","position":3,"name":"SEO\/GEO","item":"https:\/\/www.humanlevel.com\/en\/blog\/seo"},{"@type":"ListItem","position":4,"name":"JavaScript optimization"}]},{"@type":"WebSite","@id":"https:\/\/www.humanlevel.com\/en#website","url":"https:\/\/www.humanlevel.com\/en","name":"Human Level","description":"Web positioning and online marketing consultant Human Level","publisher":{"@id":"https:\/\/www.humanlevel.com\/en#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.humanlevel.com\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.humanlevel.com\/en#organization","name":"Human Level","url":"https:\/\/www.humanlevel.com\/en","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.humanlevel.com\/en#\/schema\/logo\/image\/","url":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/logohl25x3.png","contentUrl":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/logohl25x3.png","width":600,"height":93,"caption":"Human Level"},"image":{"@id":"https:\/\/www.humanlevel.com\/en#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/human-level-communications","https:\/\/www.youtube.com\/user\/humanlevelcommunica","https:\/\/bsky.app\/profile\/humanlevel.bsky.social","https:\/\/instagram.com\/humanlevel"]},{"@type":"Person","@id":"https:\/\/www.humanlevel.com\/en#\/schema\/person\/11ad888926867985985a0210476bae94","name":"Ram\u00f3n Saquete","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/1x1-ramon-saquete-26-96x96.jpg","url":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/1x1-ramon-saquete-26-96x96.jpg","contentUrl":"https:\/\/www.humanlevel.com\/wp-content\/uploads\/1x1-ramon-saquete-26-96x96.jpg","caption":"Ram\u00f3n Saquete"},"description":"Web Developer and Technical SEO Consultant at Human Level. He holds degrees in Computer Engineering and Technical Engineering in Computer Systems. He also earned a Higher Vocational Degree in Computer Applications Development and later obtained the Certificate of Pedagogical Aptitude (CAP). He is an expert in WPO and indexability.","sameAs":["https:\/\/es.linkedin.com\/in\/ramonsaquete","https:\/\/x.com\/daiatron"],"url":"https:\/\/www.humanlevel.com\/en\/author\/ramon"}]}},"_links":{"self":[{"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/posts\/52136","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/comments?post=52136"}],"version-history":[{"count":4,"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/posts\/52136\/revisions"}],"predecessor-version":[{"id":52638,"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/posts\/52136\/revisions\/52638"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/media\/47812"}],"wp:attachment":[{"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/media?parent=52136"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/categories?post=52136"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.humanlevel.com\/en\/wp-json\/wp\/v2\/tags?post=52136"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}