{
    "componentChunkName": "component---src-templates-article-page-template-js",
    "path": "/ftw/how-to-improve-performance/",
    "result": {"data":{"markdownRemark":{"frontmatter":{"title":"How to improve performance","slug":"how-to-improve-performance","updated":"2021-02-15T00:00:00.000Z","category":"ftw-styling","ingress":"This guide describes ways to improve the loading and rendering performance of your marketplace.","skills":null},"htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"When we think about page speed there are actually two different\nscenarios that we need to address:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"The speed of initial page load and possible reloads after that"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"The speed of changing the page within Single page application (SPA)"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The first one is usually a slower process. A browser needs to load all\nthe HTML, CSS, JavaScript, and images - and then it needs to understand\nand execute those files, calculate layout, paint components and finally\ncomposite the whole view. The initial page load is the slowest since the\nconsequent page reloads can take benefit from browser caches."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"SPAs can improve from that since they don't necessarily need to download\nanymore JavaScript, HTML, or CSS - already downloaded JavaScript might\nbe enough for rendering consequent pages when a user wants to navigate\nto another page. Most of the time SPAs just fetch data for that page."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"These two UX scenarios might also conflict with each other. If all the\nJavaScript is in one big bundle, page changes within a SPA are fast.\nHowever, downloading and evaluating a big JavaScript file is slowing\ninitial page rendering down. Even though users rarely experience the\nfull initial page load speed when they use an SPA like Flex Template for\nWeb, it is good to keep track of that speed. Especially since that is\nwhat search engine bots are experiencing and therefore it might affect\nyour page rank."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Read more about\n"},{"type":"element","tagName":"a","properties":{"href":"https://developers.google.com/web/fundamentals/performance/why-performance-matters/","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"website performance"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"#check-page-performance"},"children":[{"type":"text","value":"Check page performance"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"#optimize-image-sizes"},"children":[{"type":"text","value":"Optimize image sizes"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"#lazy-load-off-screen-images-and-other-components"},"children":[{"type":"text","value":"Lazy load off-screen images and other components"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"#use-sparse-attributes"},"children":[{"type":"text","value":"Use sparse attributes"}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"check-page-performance","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#check-page-performance","ariaLabel":"check page performance permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Check page performance"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The first step is, of course, to start measuring performance.\n"},{"type":"element","tagName":"a","properties":{"href":"https://developers.google.com/web/tools/lighthouse/","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Lighthouse"}]},{"type":"text","value":" is a\ngood tool to check rendering performance. At least check those pages\nthat are visible to unauthenticated users (e.g. landing page, search\npage, listing page, about page and other content pages)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Lighthouse will give you some tips about how to improve performance and\nother aspects that website developers should think about."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"optimize-image-sizes","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#optimize-image-sizes","ariaLabel":"optimize image sizes permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Optimize image sizes"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If your page is showing images, you should check that the image size is\nnot bigger than what is needed. So, adjusting image dimensions is the\nfirst step, but you should also think about image quality, advanced\nrendering options and possibly serving those images from CDN instead of\nfrom within your web app."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Quick checklist:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Check that the actual dimensions of an image match with DOM element's\ndimensions."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Lighthouse suggests that image compression level should be 85% or\nlower. "},{"type":"element","tagName":"a","properties":{"href":"https://web.dev/uses-optimized-images/","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Read more"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Good rule-of-thumb is that use JPEG for images and photos, where PNG\nis better for graphics, such as logos, graphs and illustrations."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"If you are using JPEG images, think about saving them as progressive\nJPEGs.\n"},{"type":"element","tagName":"a","properties":{"href":"https://cloudinary.com/blog/progressive_jpegs_and_green_martians","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Read more"}]},{"type":"text","value":" +\n"},{"type":"element","tagName":"a","properties":{"href":"https://helpx.adobe.com/photoshop-elements/using/optimizing-images-jpeg-format.html","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Photoshop guide"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"If you are using PNG images, consider running them through PNG\noptimizers to reduce file size. Plenty of options available, one\nexample is "},{"type":"element","tagName":"a","properties":{"href":"https://tinypng.com","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"TinyPNG.com"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Think about serving images and other static assets from some CDN.\n"},{"type":"element","tagName":"a","properties":{"href":"https://www.smashingmagazine.com/2017/04/content-delivery-network-optimize-images/","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Read more."}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"lazy-load-off-screen-images-and-other-components","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#lazy-load-off-screen-images-and-other-components","ariaLabel":"lazy load off screen images and other components permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Lazy load off-screen images and other components"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Another way of dealing with images is to lazy load those images that are\nnot visible inside an initially rendered part of the screen. Lazy\nloading these off-screen images can be done with helper function:\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"lazyLoadWithDimensions"}]},{"type":"text","value":" (from "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"util/contextHelpers/"}]},{"type":"text","value":"). Check\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"SectionLocations"}]},{"type":"text","value":" component for details."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"use-sparse-attributes","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#use-sparse-attributes","ariaLabel":"use sparse attributes permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Use sparse attributes"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Another way to reduce the amount of data that is fetched from API is\nsparse attributes. This is a feature FTW has not yet leveraged fully,\nbut it is created to reduce unnecessary data and speed up rendering. You\ncan read more from\n"},{"type":"element","tagName":"a","properties":{"href":"https://www.sharetribe.com/api-reference/#sparse-attributes","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Marketplace API reference for sparse attributes"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"use-code-splitting","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#use-code-splitting","ariaLabel":"use code splitting permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Use code splitting"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Code splitting is enabled with Loadable Components and by default\nroute-based splits are made through "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"src/routeConfiguration.js"}]},{"type":"text","value":". (In\nFTW-product the file is moved to "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"src/routing/routeConfiguration.js"}]},{"type":"text","value":".)\nIf you want to improve performance, you should prefer subcomponents\ninside page-directories instead of adding more code to shared components\ndirectory. Those components end up to main chunk file that is downloaded\non each page (when full page-load is requested)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You can read more\n"},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/ftw/how-code-splitting-works-in-ftw/"},"children":[{"type":"text","value":"in the code splitting article"}]},{"type":"text","value":"."}]}],"data":{"quirksMode":false}},"headings":[{"value":"Check page performance","depth":2},{"value":"Optimize image sizes","depth":2},{"value":"Lazy load off-screen images and other components","depth":2},{"value":"Use sparse attributes","depth":2},{"value":"Use code splitting","depth":2}]}},"pageContext":{"slug":"how-to-improve-performance","category":"ftw-styling"}},
    "staticQueryHashes": ["3794076007","439097193","717698143"]}