{"id":5214,"date":"2019-02-12T19:46:41","date_gmt":"2019-02-12T18:46:41","guid":{"rendered":"https:\/\/monodes.com\/predaelli\/?p=5214"},"modified":"2019-02-12T11:47:45","modified_gmt":"2019-02-12T10:47:45","slug":"vue-js-app-performance-optimization-part-1%e2%80%8a-%e2%80%8aintroduction-to-performance-optimization-and-lazy","status":"publish","type":"post","link":"https:\/\/monodes.com\/predaelli\/2019\/02\/12\/vue-js-app-performance-optimization-part-1%e2%80%8a-%e2%80%8aintroduction-to-performance-optimization-and-lazy\/","title":{"rendered":"Vue.js App Performance Optimization: part 1\u200a\u2014\u200aIntroduction to performance optimization and lazy\u2026"},"content":{"rendered":"<p>For the series, I will never stop learning<\/p>\n<blockquote><p>While mobile-first approach becomes a standard and uncertain network conditions are something we should always take into consideration\u2026<\/p><\/blockquote>\n<p><em><a href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-1-introduction-to-performance-optimization-and-lazy-29e4ff101019\">Vue.js App Performance Optimization: part 1\u200a\u2014\u200aIntroduction to performance optimization and lazy\u2026<\/a><\/em><\/p>\n<p><!--more--><!--nextpage--><\/p>\n<blockquote>\n<h1 id=\"e2b2\" class=\"graf graf--h3 graf-after--figure graf--title\">Vue.js App Performance Optimization: part 1\u200a\u2014\u200aIntroduction to performance optimization and lazy&nbsp;loading.<\/h1>\n<div class=\"uiScale uiScale-ui--regular uiScale-caption--regular u-flexCenter u-marginVertical24 u-fontSize15 js-postMetaLockup\">\n<div class=\"u-flex1 u-paddingLeft15 u-overflowHidden\">\n<div class=\"u-paddingBottom3\"><a class=\"ds-link ds-link--styleSubtle ui-captionStrong u-inlineBlock link link--darken link--darker\" dir=\"auto\" href=\"https:\/\/itnext.io\/@frakowski\" data-action=\"show-user-card\" data-action-value=\"2f6fdc60db8b\" data-action-type=\"hover\" data-user-id=\"2f6fdc60db8b\" data-collection-slug=\"itnext\">by Filip Rakowski<\/a><\/div>\n<\/div>\n<\/div>\n<div class=\"uiScale uiScale-ui--regular uiScale-caption--regular u-flexCenter u-marginVertical24 u-fontSize15 js-postMetaLockup\">\n<div class=\"u-flex1 u-paddingLeft15 u-overflowHidden\">\n<div class=\"ui-caption u-noWrapWithEllipsis js-testPostMetaInlineSupplemental\"><time datetime=\"2019-01-29T10:25:34.785Z\">Jan 29<\/time><\/div>\n<\/div>\n<\/div>\n<p id=\"7dd5\" class=\"graf graf--p graf-after--h3\"><strong class=\"markup--strong markup--p-strong\">While mobile-first approach becomes a standard and uncertain network conditions are something we should always take into consideration it\u2019s harder and harder to keep your application loading fast. In this series I\u2019ll dig deep into Vue performance optimization techniques that we are using in <\/strong><a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/DivanteLtd\/vue-storefront\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/DivanteLtd\/vue-storefront\"><strong class=\"markup--strong markup--p-strong\">Vue Storefront<\/strong><\/a><strong class=\"markup--strong markup--p-strong\"> and that you can use in your Vue.js applications to make them loading instantly and perform smooth. My goal is to make this series a full and complete guide on Vue apps performance.<\/strong><\/p>\n<p id=\"f7ef\" class=\"graf graf--p graf-after--p\"><a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-1-introduction-to-performance-optimization-and-lazy-29e4ff101019\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-1-introduction-to-performance-optimization-and-lazy-29e4ff101019\">Part 1\u200a\u2014\u200aIntroduction to performance optimization and lazy loading.<\/a><\/p>\n<p id=\"c5c1\" class=\"graf graf--p graf-after--p\"><a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-2-lazy-loading-routes-and-vendor-bundle-anti-pattern-4a62236e09f9\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-2-lazy-loading-routes-and-vendor-bundle-anti-pattern-4a62236e09f9\">Part 2\u200a\u2014\u200aLazy loading routes and vendor bundle anti-pattern.<\/a><\/p>\n<p id=\"7135\" class=\"graf graf--p graf-after--p\">Part 3\u2014 Lazy loading Vuex stores and single components\u200a\u2014\u200asoon<\/p>\n<p id=\"5b8d\" class=\"graf graf--p graf-after--p\">Part 4\u2014 Lazy loading libs and finding smaller equivalents\u200a\u2014\u200asoon<\/p>\n<p id=\"39f2\" class=\"graf graf--p graf-after--p\">Part 5\u200a\u2014\u200aMaking use of Service Worker cache\u200a\u2014\u200asoon<\/p>\n<p id=\"543e\" class=\"graf graf--p graf-after--p\">Part 6\u2014 Prefetching<\/p>\n<h3 id=\"a339\" class=\"graf graf--h3 graf-after--p\">How Webpack bundling&nbsp;works?<\/h3>\n<p id=\"649c\" class=\"graf graf--p graf-after--h3\">Most of the tips in this series will focus on making our JS bundle smaller. To understand while it\u2019s crucial first we need to understand how Webpack is bundling all of our files.<\/p>\n<p id=\"5469\" class=\"graf graf--p graf-after--p\">While bundling our assets Webpack is creating something called <strong class=\"markup--strong markup--p-strong\">dependency graph<\/strong>. It\u2019s a graph that links all of our files based on imports. Assuming we have a file called <code class=\"\" data-line=\"\">main.js <\/code>specified as an entry point in our webpack config it will be a root of our dependency graph. Now every js module that we will import in this file will become it\u2019s leaf in the graph and every module imported in this leafs will become their leafs.<\/p>\n<p id=\"f7db\" class=\"graf graf--p graf-after--p\">Webpack is using this dependency graph to detect which files it should include in the output bundle. Output bundle is just a single (or multiple as we will see in the later parts) javascript file containing all modules from dependency graph.<\/p>\n<p id=\"4831\" class=\"graf graf--p graf-after--p\">We can illustrate this process like this:<\/p>\n<figure id=\"d8ce\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder\"><a href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-1-introduction-to-performance-optimization-and-lazy-29e4ff101019\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1600\/1%2ASL6RVjoNQaUdii2Qh9XeZg.png?w=910&#038;ssl=1\" alt=\"\"\/><\/a><\/div>\n<\/figure>\n<p id=\"ddc5\" class=\"graf graf--p graf-after--figure\">Now when we know how bundling works it becomes obvious that the more our project will grow the biggest initial JavaScript bundle will be. The bigger it\u2019ll be the longer it\u2019ll take to download and parse it so user will see something meaningful later. The longer user will wait the more probable it is that he\/she will leave our website.<\/p>\n<p id=\"9514\" class=\"graf graf--p graf-after--p\">In short words <strong class=\"markup--strong markup--p-strong\">bigger bundle = less users. <\/strong>At least in most of the cases.<\/p>\n<h3 id=\"0522\" class=\"graf graf--h3 graf-after--p\"><strong class=\"markup--strong markup--h3-strong\">Lazy loading<\/strong><\/h3>\n<p id=\"6ca9\" class=\"graf graf--p graf-after--h3\">So how we can cut off bundle size when we still need to add new features and improve our application? The answer is easy\u200a\u2014<strong class=\"markup--strong markup--p-strong\">\u200alazy loading and code splitting<\/strong>.<\/p>\n<p id=\"c0d5\" class=\"graf graf--p graf-after--p\">As the name suggests lazy loading is loading parts of your application lazily. In other words\u200a\u2014\u200aloading them only when we really need them. Code splitting is just splitting the app into this lazily loaded chunks.<\/p>\n<figure id=\"4528\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*FMC15xLg-8ERtuMjonFLhQ.png\" data-width=\"1036\" data-height=\"302\" data-action=\"zoom\" data-action-value=\"1*FMC15xLg-8ERtuMjonFLhQ.png\" data-scroll=\"native\"><\/div>\n<\/div>\n<\/figure>\n<div class=\"section-inner sectionLayout--insetColumn\">\n<figure id=\"4528\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*FMC15xLg-8ERtuMjonFLhQ.png\" data-width=\"1036\" data-height=\"302\" data-action=\"zoom\" data-action-value=\"1*FMC15xLg-8ERtuMjonFLhQ.png\" data-scroll=\"native\"><a href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-1-introduction-to-performance-optimization-and-lazy-29e4ff101019\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1600\/1%2AFMC15xLg-8ERtuMjonFLhQ.png?w=910&#038;ssl=1\" alt=\"\"\/><\/a><\/div>\n<\/div>\n<\/figure>\n<p id=\"7025\" class=\"graf graf--p graf-after--figure\">In most cases you don\u2019t need all the code from your Javascript bundle right after user visits your website. Even if we will have 3 different routes in our app no matter where user will end up he\/she always needs to download, parse and execute bundle with all of them even though only one is needed. What a waste of time and energy!<\/p>\n<p id=\"fa71\" class=\"graf graf--p graf-after--p\">Lazy loading allows us to split the bundle and serve only the needed parts so user is not wasting time to download and parse code that\u2019ll not be used.<\/p>\n<p id=\"c5bb\" class=\"graf graf--p graf-after--p\">To see how much of the JavaScript code is actually used in our website we can go to the devtools -&gt; cmd+shift+p -&gt; type coverage -&gt; hit \u2018record\u2019. Now we should be able to see how much of the downloaded code was actually used.<\/p>\n<\/div>\n<div class=\"section-inner sectionLayout--outsetColumn\">\n<figure id=\"16a5\" class=\"graf graf--figure graf--layoutOutsetCenter graf-after--p\" data-scroll=\"native\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*ewG1n7SK4621-w2wBSNWYA.png\" data-width=\"2880\" data-height=\"1214\" data-action=\"zoom\" data-action-value=\"1*ewG1n7SK4621-w2wBSNWYA.png\" data-scroll=\"native\"><\/div>\n<\/div>\n<\/figure>\n<\/div>\n<div class=\"section-inner sectionLayout--outsetColumn\">\n<figure id=\"16a5\" class=\"graf graf--figure graf--layoutOutsetCenter graf-after--p\" data-scroll=\"native\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*ewG1n7SK4621-w2wBSNWYA.png\" data-width=\"2880\" data-height=\"1214\" data-action=\"zoom\" data-action-value=\"1*ewG1n7SK4621-w2wBSNWYA.png\" data-scroll=\"native\"><a href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-1-introduction-to-performance-optimization-and-lazy-29e4ff101019\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/2000\/1%2AewG1n7SK4621-w2wBSNWYA.png?w=910&#038;ssl=1\" alt=\"\"\/><\/a><\/div>\n<\/div>\n<\/figure>\n<\/div>\n<div class=\"section-inner sectionLayout--insetColumn\">\n<p id=\"c8dc\" class=\"graf graf--p graf-after--figure\"><strong class=\"markup--strong markup--p-strong\">Everything marked as red is something that is not needed on current route and can be lazily loaded.<\/strong> If you are using source maps you can click on any file in this list and see which of it\u2019s parts were not invoked. As we can see even <em class=\"markup--em markup--p-em\">vuejs.org<\/em> has a huge room for improvement&nbsp;;).<\/p>\n<p id=\"927a\" class=\"graf graf--p graf-after--p\">By lazy loading proper components and libraries we managed to cut off the bundle size of <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/DivanteLtd\/vue-storefront\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/DivanteLtd\/vue-storefront\">Vue Storefront<\/a> by 60%!<\/p>\n<p id=\"9eff\" class=\"graf graf--p graf-after--p\">Ok, we know what lazy loading is it\u2019s and that it\u2019s pretty useful&nbsp;\ud83d\ude09<\/p>\n<p id=\"ac47\" class=\"graf graf--p graf-after--p\">It\u2019s time to see how we can use it in our Vue.js application.<\/p>\n<h3 id=\"2efc\" class=\"graf graf--h3 graf-after--p\"><strong class=\"markup--strong markup--h3-strong\">Dynamic imports<\/strong><\/h3>\n<p id=\"0135\" class=\"graf graf--p graf-after--h3\">We can easily load some parts of our application lazily with <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/webpack.js.org\/guides\/code-splitting\/\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/webpack.js.org\/guides\/code-splitting\/\">webpack dynamic imports<\/a>. Let\u2019s see how they work and how they differ from regular imports.<\/p>\n<p id=\"fa46\" class=\"graf graf--p graf-after--p\">If we will import JS module in a standard way like this:<\/p>\n<pre id=\"5c8a\" class=\"graf graf--pre graf-after--p\">\/\/ main.js\nimport ModuleA from '.\/module_a.js'<\/pre>\n<pre id=\"381f\" class=\"graf graf--pre graf-after--pre\">ModuleA.doStuff()<\/pre>\n<p id=\"8eb2\" class=\"graf graf--p graf-after--pre\">It will be added as a leaf of a main.js in the dependency graph and bundled with it.<\/p>\n<p id=\"bdb7\" class=\"graf graf--p graf-after--p\">But what if we will need <code class=\"\" data-line=\"\">ModuleA<\/code> only under certain circumstances like a response to the user interaction? Bundling this module with our initial bundle is a bad idea since it may not be needed at all. We need a way to tell our application when it should download this chunk of code.<\/p>\n<p id=\"731c\" class=\"graf graf--p graf-after--p\">This is where dynamic imports can help us! Now take a look at this example:<\/p>\n<pre id=\"6896\" class=\"graf graf--pre graf-after--p\">\/\/main.js\nconst getModuleA = () =&gt; import('.\/module_a.js')<\/pre>\n<pre id=\"0fd1\" class=\"graf graf--pre graf-after--pre\">\/\/ invoked as a response to some user interaction\ngetModuleA()\n  .then({ doStuff } =&gt; doStuff())<\/pre>\n<p id=\"dae8\" class=\"graf graf--p graf-after--pre\">Let\u2019s take a quick look at what happened here:<\/p>\n<p id=\"31ee\" class=\"graf graf--p graf-after--p\">Instead of directly importing <code class=\"\" data-line=\"\">module_a.js<\/code> we created a function that returns the<code class=\"\" data-line=\"\">import()<\/code> function&nbsp;. <strong class=\"markup--strong markup--p-strong\">Now webpack will bundle content of dynamically imported module into a separate file and unless the function will be invoked the import will not be called and file won\u2019t be downloaded.<\/strong> Later in the code we downloaded this optional chunk of code as a response to some certain user interaction (like route change or click).<\/p>\n<p id=\"f56f\" class=\"graf graf--p graf-after--p\">By making a dynamic import we are basically cutting off the leaf that will be added to the dependency graph and making the separate one that will be downloaded when we decide it\u2019s needed (<strong class=\"markup--strong markup--p-strong\">which implies that we are also cutting off modules that are imported inside <\/strong><code class=\"\" data-line=\"\">module_a.js<\/code> ).<\/p>\n<p id=\"1204\" class=\"graf graf--p graf-after--p\">Let\u2019s see another example that will better illustrate this mechanism.<\/p>\n<p id=\"673f\" class=\"graf graf--p graf-after--p\">Let\u2019s assume we have 4 files: <code class=\"\" data-line=\"\">main.js<\/code>, <code class=\"\" data-line=\"\">module_a.js<\/code>, <code class=\"\" data-line=\"\">module_b.js<\/code> and <code class=\"\" data-line=\"\">module_c.js.<\/code> To understand how dynamic imports work we need only source code of <code class=\"\" data-line=\"\">main<\/code> and <code class=\"\" data-line=\"\">module_a<\/code>:<\/p>\n<pre id=\"2ec9\" class=\"graf graf--pre graf-after--p\">\/\/main.js\nimport ModuleB from '.\/mobile_b.js'\nconst getModuleA = () =&gt; import('.\/module_a.js')<\/pre>\n<pre id=\"6df5\" class=\"graf graf--pre graf-after--pre\">getModuleA()\n  .then({ doStuff } =&gt; doStuff()\n)<\/pre>\n<pre id=\"b166\" class=\"graf graf--pre graf-after--pre\">\/\/module_a.js\nimport ModuleC from '.\/module_c.js'<\/pre>\n<p id=\"febb\" class=\"graf graf--p graf-after--pre\">By making <code class=\"\" data-line=\"\">module_a<\/code> a dynamically imported module we are cutting part of the dependency graph with <code class=\"\" data-line=\"\">module_a<\/code> and all it\u2019s children. When <code class=\"\" data-line=\"\">module_a<\/code> is dynamically imported it loads together with modules imported inside of it.<\/p>\n<p id=\"931c\" class=\"graf graf--p graf-after--p\">In other words we are just creating a new entry point for the dependency graph.<\/p>\n<figure id=\"187f\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*Sow926JkqGKm-ZQ341iLpA.png\" data-width=\"1276\" data-height=\"808\" data-action=\"zoom\" data-action-value=\"1*Sow926JkqGKm-ZQ341iLpA.png\" data-scroll=\"native\"><\/div>\n<\/div>\n<\/figure>\n<\/div>\n<figure id=\"187f\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*Sow926JkqGKm-ZQ341iLpA.png\" data-width=\"1276\" data-height=\"808\" data-action=\"zoom\" data-action-value=\"1*Sow926JkqGKm-ZQ341iLpA.png\" data-scroll=\"native\"><a href=\"https:\/\/itnext.io\/vue-js-app-performance-optimization-part-1-introduction-to-performance-optimization-and-lazy-29e4ff101019\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1600\/1%2ASow926JkqGKm-ZQ341iLpA.png?w=910&#038;ssl=1\" alt=\"\"\/><\/a><\/div>\n<\/div><figcaption class=\"imageCaption\">This how our dependency graph and bundles will look like with given&nbsp;setup.<\/figcaption><\/figure>\n<h3 id=\"1d95\" class=\"graf graf--h3 graf-after--figure\"><span class=\"markup--quote markup--h3-quote is-other\" data-creator-ids=\"anon\">Lazy loading Vue components<\/span><\/h3>\n<p id=\"4236\" class=\"graf graf--p graf-after--h3\">We know what lazy loading is and why we need it. It\u2019s time to see how we can make use of it in our Vue application.<\/p>\n<p id=\"b5ed\" class=\"graf graf--p graf-after--p\">The good news is that it\u2019s extremely easy and we can lazily load whole SFC along with it\u2019s css and html with the same syntax as previously!<\/p>\n<pre id=\"9b2b\" class=\"graf graf--pre graf-after--p\">const lazyComponent = () =&gt; import('Component.vue')<\/pre>\n<p id=\"7505\" class=\"graf graf--p graf-after--pre\">\u2026that\u2019s all you need! Now the component will be downloaded only when it\u2019s requested. Here are the most common ways to invoke dynamic loading of Vue component:<\/p>\n<ul class=\"postList\">\n<li id=\"6bd1\" class=\"graf graf--li graf-after--p\">function with import is invoked<\/li>\n<\/ul>\n<pre id=\"99dd\" class=\"graf graf--pre graf-after--li\">const lazyComponent = () =&gt; import('Component.vue')<\/pre>\n<pre id=\"d4a6\" class=\"graf graf--pre graf-after--pre\">lazyComponent()<\/pre>\n<ul class=\"postList\">\n<li id=\"1989\" class=\"graf graf--li graf-after--pre\">component is requested to render<\/li>\n<\/ul>\n<pre id=\"fef5\" class=\"graf graf--pre graf-after--li\">&lt;template&gt;\n  &lt;div&gt; \n    &lt;lazy-component \/&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;<\/pre>\n<pre id=\"b90e\" class=\"graf graf--pre graf-after--pre\">&lt;script&gt;\nconst lazyComponent = () =&gt; import('Component.vue')<\/pre>\n<pre id=\"c950\" class=\"graf graf--pre graf-after--pre\">export default {\n  components: { lazyComponent }\n}\n&lt;\/script&gt;<\/pre>\n<p id=\"a007\" class=\"graf graf--p graf-after--pre\">Please note that the invocation of <code class=\"\" data-line=\"\">lazyComponent<\/code> function will happen only when component is requested to render in a template.<br \/>\nFor example this code:<\/p>\n<pre id=\"19ea\" class=\"graf graf--pre graf-after--p\">&lt;lazy-component v-if=\"false\" \/&gt;<\/pre>\n<\/p>\n<p id=\"ffaf\" class=\"graf graf--p graf-after--pre\">will not dynamically import the component since it\u2019s not added to the DOM (but will do it as soon as the value will change to <code class=\"\" data-line=\"\">true<\/code> which is a nice way to conditionally lazily load Vue components)<\/p>\n<h3 id=\"a63a\" class=\"graf graf--h3 graf-after--p\">Summary<\/h3>\n<p id=\"d1d0\" class=\"graf graf--p graf-after--h3 graf--trailing\">Lazy loading is one of the best ways to make your web app more performant and cut off on it\u2019s size. We learned how to use lazy loading with Vue components. In the next part of this series I\u2019ll show you how to split your Vue application code with <code class=\"\" data-line=\"\">vue-router<\/code> and async routes.<\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p class=\"excerpt\">For the series, I will never stop learning While mobile-first approach becomes a standard and uncertain network conditions are something we should always take into consideration\u2026 Vue.js App Performance Optimization: part 1\u200a\u2014\u200aIntroduction to performance optimization and lazy\u2026<\/p>\n<p class=\"more-link-p\"><a class=\"more-link\" href=\"https:\/\/monodes.com\/predaelli\/2019\/02\/12\/vue-js-app-performance-optimization-part-1%e2%80%8a-%e2%80%8aintroduction-to-performance-optimization-and-lazy\/\">Read more &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[72,50],"tags":[],"class_list":["post-5214","post","type-post","status-publish","format-standard","hentry","category-documentations","category-javascript"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6daft-1m6","jetpack-related-posts":[{"id":6562,"url":"https:\/\/monodes.com\/predaelli\/2020\/01\/29\/9-vue-js-libraries-that-will-make-your-life-easier-better-programming-medium\/","url_meta":{"origin":5214,"position":0},"title":"9 Vue.js Libraries That Will Make Your Life Easier &#8211; Better Programming &#8211; Medium","author":"Paolo Redaelli","date":"2020-01-29","format":"link","excerpt":"9 Vue.js Libraries That Will Make Your Life Easier - Better Programming - Medium\u00a0 Vue-Lazyload is a great library for lazy loading of not only images but also components. vue-head library makes manipulating the information in the head tag a piece of cake. BootstrapVue: Bootstrap components built with Vue. Vue-multiselect\u2026","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4345,"url":"https:\/\/monodes.com\/predaelli\/2018\/05\/26\/adding-snap-svg-to-vue-js-and-nuxt-js-projects\/","url_meta":{"origin":5214,"position":1},"title":"Adding Snap.svg to Vue.js and Nuxt.js Projects","author":"Paolo Redaelli","date":"2018-05-26","format":false,"excerpt":"Adding Snap.svg to Vue.js and Nuxt.js Projects | James Scheller Getting Snap.svg Working with Vue.js Out of the gate, there\u2019s some hurdles because Snap mounts itself on the browser\u2019s window object, so if you\u2019re trying to load Snap through WebPack (as opposed to just including it in a project using\u2026","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4422,"url":"https:\/\/monodes.com\/predaelli\/2018\/07\/04\/4422\/","url_meta":{"origin":5214,"position":2},"title":"VueI18n is internationalization plugin for\u2026","author":"Paolo Redaelli","date":"2018-07-04","format":"link","excerpt":"VueI18n is internationalization plugin for Vue.js","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/monodes.com\/predaelli\/wp-content\/uploads\/sites\/4\/2018\/07\/vue-i18n-logo-1.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":9267,"url":"https:\/\/monodes.com\/predaelli\/2022\/04\/08\/webpagetest-website-performance-and-optimization-test\/","url_meta":{"origin":5214,"position":3},"title":"WebPageTest &#8211; Website Performance and Optimization Test","author":"Paolo Redaelli","date":"2022-04-08","format":false,"excerpt":"WebPageTest - Website Performance and Optimization Test Run a free website speed test from around the globe using real browsers at consumer connection speeds with detailed optimization recommendations. Better than pagespeed by Google. Why? becuase it's free-as-in-freedom","rel":"","context":"In &quot;Senza categoria&quot;","block_context":{"text":"Senza categoria","link":"https:\/\/monodes.com\/predaelli\/category\/senza-categoria\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4639,"url":"https:\/\/monodes.com\/predaelli\/2018\/10\/13\/gcc-optimizing-everything\/","url_meta":{"origin":5214,"position":4},"title":"GCC: Optimizing Everything","author":"Paolo Redaelli","date":"2018-10-13","format":"link","excerpt":"Software is useless if computers can't run it. Even the most talented developer is at the mercy of the compiler when it comes to run-time performance - if you don\u2019t have a reliable compiler toolchain you can\u2019t build anything serious. The GNU Compiler Collection (GCC) provides a robust, mature and\u2026","rel":"","context":"In &quot;Senza categoria&quot;","block_context":{"text":"Senza categoria","link":"https:\/\/monodes.com\/predaelli\/category\/senza-categoria\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6263,"url":"https:\/\/monodes.com\/predaelli\/2019\/11\/18\/cell-editable-vue-table\/","url_meta":{"origin":5214,"position":5},"title":"cell-editable vue table","author":"Paolo Redaelli","date":"2019-11-18","format":false,"excerpt":"It seems time has come for me to learn Chinese or to heavily rely on translators: vue table \u7ec4\u4ef6 \u5f3a\u5927\u3001\u7075\u6d3b\uff0c\u652f\u6301 \u5355\u5143\u683c\u5408\u5e76\u3001\u5355\u5143\u683c\u7f16\u8f91\u3001\u591a\u8868\u5934\u56fa\u5b9a\u3001\u591a\u5217\u56fa\u5b9a\u3001\u5217\u62d6\u52a8\u3001\u6392\u5e8f\u3001\u81ea\u5b9a\u4e49\u5217\u3001\u5206\u9875\u3001\u5355\u5143\u683c\u7f16\u8f91\u3001\u5168\u9009\u3001\u884c\u5c55\u5f00\u3001\u6761\u4ef6\u8fc7\u6ee4\u3001footer \u6c47\u603b\u3001\u5bfc\u51faexcel\u3001\u6c47\u603b Vue2.x flexible table components, support for cell edit,multi-head fixed, multi-column fixed, clumn drag, sort, custom column,Cell Editing, Support cell merge (colSpan and rowSpan),Support checkbox selection Source: vue table\u2026","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/5214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/comments?post=5214"}],"version-history":[{"count":0,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/5214\/revisions"}],"wp:attachment":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/media?parent=5214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/categories?post=5214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/tags?post=5214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}