diff --git a/404.html b/404.html index e4664c4..142683c 100644 --- a/404.html +++ b/404.html @@ -9,13 +9,13 @@ - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/assets/images/floating_point_representation-efc73a8c1b722a82b772c2cd7ee7ba99.webp b/assets/images/floating_point_representation-efc73a8c1b722a82b772c2cd7ee7ba99.webp new file mode 100644 index 0000000..a74faa8 Binary files /dev/null and b/assets/images/floating_point_representation-efc73a8c1b722a82b772c2cd7ee7ba99.webp differ diff --git a/assets/js/00b62936.719c05c2.js b/assets/js/00b62936.719c05c2.js new file mode 100644 index 0000000..d23283e --- /dev/null +++ b/assets/js/00b62936.719c05c2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[6284],{2620:a=>{a.exports=JSON.parse('{"label":"golang","permalink":"/blog/tags/golang","allTagsPath":"/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/assets/js/23b2474b.b0be182d.js b/assets/js/23b2474b.b0be182d.js new file mode 100644 index 0000000..a0cbb21 --- /dev/null +++ b/assets/js/23b2474b.b0be182d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[1364],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),u=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=u(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),p=u(n),d=r,f=p["".concat(l,".").concat(d)]||p[d]||m[d]||a;return n?o.createElement(f,i(i({ref:t},s),{},{components:n})):o.createElement(f,i({ref:t},s))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:r,i[1]=c;for(var u=2;u{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>c,toc:()=>u});var o=n(7462),r=(n(7294),n(3905));const a={slug:"accuracy-of-decimal-computations",authors:["patrickb"],tags:["golang","currency","decimal accuracy"]},i="Accuracy of decimal computations",c={permalink:"/blog/accuracy-of-decimal-computations",editUrl:"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2023-03-06-accuracy-of-decimal-computations/index.mdx",source:"@site/blog/2023-03-06-accuracy-of-decimal-computations/index.mdx",title:"Accuracy of decimal computations",description:"Intro",date:"2023-03-06T00:00:00.000Z",formattedDate:"March 6, 2023",tags:[{label:"golang",permalink:"/blog/tags/golang"},{label:"currency",permalink:"/blog/tags/currency"},{label:"decimal accuracy",permalink:"/blog/tags/decimal-accuracy"}],hasTruncateMarker:!1,authors:[{name:"Patrick Buchner",title:"MSc",url:"https://github.com/smartinov",imageURL:"https://github.com/uebriges.png",key:"patrickb"}],frontMatter:{slug:"accuracy-of-decimal-computations",authors:["patrickb"],tags:["golang","currency","decimal accuracy"]},nextItem:{title:"Why bundle size is important?",permalink:"/blog/why-bundle-size-is-important"}},l={authorsImageUrls:[void 0]},u=[{value:"Intro",id:"intro",level:2},{value:"Finite accuracy of representation",id:"finite-accuracy-of-representation",level:2},{value:"Money computations",id:"money-computations",level:2},{value:"Solution",id:"solution",level:2},{value:"Conclusio",id:"conclusio",level:2}],s={toc:u},p="wrapper";function m(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,o.Z)({},s,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"intro"},"Intro"),(0,r.kt)("p",null,"Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors."),(0,r.kt)("h2",{id:"finite-accuracy-of-representation"},"Finite accuracy of representation"),(0,r.kt)("p",null,"Floating points are represented like this"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"Floating point representation",src:n(880).Z,width:"810",height:"226"})),(0,r.kt)("p",null,"Not every number can be represented with a finite number of decimal places"),(0,r.kt)("p",null,"0.01 \u2014> 0.0000011001100110011\u2026"),(0,r.kt)("p",null,"Taking 17 places of the above results in 0.010000000000000001"),(0,r.kt)("p",null,"Consider the following code snipet that shows the missing accuracy"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},"func main() {\n\n var n float64 = 0\n\n for i := 0; i < 1000; i++ {\n n += .01\n }\n\n fmt.Println(n)\n\n}\n")),(0,r.kt)("p",null,"Result: 9.999999999999831"),(0,r.kt)("h2",{id:"money-computations"},"Money computations"),(0,r.kt)("p",null,"They can't be done with floating-point as it would inevitably lead to rounding errors."),(0,r.kt)("p",null,"Even the following packages are problematic:"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/shopspring/decimal"},"github.com/shopspring/decimal")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/Rhymond/go-money"},"github.com/Rhymond/go-money")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},"a := decimal.NewFromInt(2)\nb := decimal.NewFromFloat(300.99)\nc := a.Mul(b)\nd := c.Div(decimal.NewFromInt(3))\n")),(0,r.kt)("h2",{id:"solution"},"Solution"),(0,r.kt)("p",null,"Use Int by representing money in cents:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"10.99 -> 1099 (cents)"),(0,r.kt)("li",{parentName:"ul"},"10.9900 -> 109900 (4 digit tax)")),(0,r.kt)("h2",{id:"conclusio"},"Conclusio"),(0,r.kt)("p",null,"Division is a problem!"),(0,r.kt)("p",null,"1/3 - > 0.33333333\u2026\nCorrect way: 0.33, 0.33, 0.34"),(0,r.kt)("p",null,"When doing money calculations one should avoid division as it inevitably leads to loss of accuracy.\nWhen dividing make sure to round to cent and deal with diffs."),(0,r.kt)("p",null,"Division by 10^k is ok till we are inside of the range of the data type."))}m.isMDXComponent=!0},880:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/floating_point_representation-efc73a8c1b722a82b772c2cd7ee7ba99.webp"}}]); \ No newline at end of file diff --git a/assets/js/26ea2a44.571352e6.js b/assets/js/26ea2a44.571352e6.js deleted file mode 100644 index e4cce7d..0000000 --- a/assets/js/26ea2a44.571352e6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[1435],{3905:(A,e,t)=>{t.d(e,{Zo:()=>g,kt:()=>d});var l=t(7294);function n(A,e,t){return e in A?Object.defineProperty(A,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):A[e]=t,A}function a(A,e){var t=Object.keys(A);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(A);e&&(l=l.filter((function(e){return Object.getOwnPropertyDescriptor(A,e).enumerable}))),t.push.apply(t,l)}return t}function o(A){for(var e=1;e=0||(n[t]=A[t]);return n}(A,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(A);for(l=0;l=0||Object.prototype.propertyIsEnumerable.call(A,t)&&(n[t]=A[t])}return n}var r=l.createContext({}),s=function(A){var e=l.useContext(r),t=e;return A&&(t="function"==typeof A?A(e):o(o({},e),A)),t},g=function(A){var e=s(A.components);return l.createElement(r.Provider,{value:e},A.children)},u="mdxType",p={inlineCode:"code",wrapper:function(A){var e=A.children;return l.createElement(l.Fragment,{},e)}},c=l.forwardRef((function(A,e){var t=A.components,n=A.mdxType,a=A.originalType,r=A.parentName,g=i(A,["components","mdxType","originalType","parentName"]),u=s(t),c=n,d=u["".concat(r,".").concat(c)]||u[c]||p[c]||a;return t?l.createElement(d,o(o({ref:e},g),{},{components:t})):l.createElement(d,o({ref:e},g))}));function d(A,e){var t=arguments,n=e&&e.mdxType;if("string"==typeof A||n){var a=t.length,o=new Array(a);o[0]=c;var i={};for(var r in e)hasOwnProperty.call(e,r)&&(i[r]=e[r]);i.originalType=A,i[u]="string"==typeof A?A:n,o[1]=i;for(var s=2;s{t.r(e),t.d(e,{assets:()=>r,contentTitle:()=>o,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var l=t(7462),n=(t(7294),t(3905));const a={slug:"why-bundle-size-is-important",authors:["nicola"],tags:["javascript","bundle","bundle size"]},o="Why bundle size is important?",i={permalink:"/blog/why-bundle-size-is-important",editUrl:"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-03-17-why-bundle-size-is-important/index.mdx",source:"@site/blog/2022-03-17-why-bundle-size-is-important/index.mdx",title:"Why bundle size is important?",description:"Intro",date:"2022-03-17T00:00:00.000Z",formattedDate:"March 17, 2022",tags:[{label:"javascript",permalink:"/blog/tags/javascript"},{label:"bundle",permalink:"/blog/tags/bundle"},{label:"bundle size",permalink:"/blog/tags/bundle-size"}],hasTruncateMarker:!1,authors:[{name:"Nicola Turcato",title:"Memelord brother",url:"https://github.com/nicolaturcato",imageURL:"https://github.com/nicolaturcato.png",key:"nicola"}],frontMatter:{slug:"why-bundle-size-is-important",authors:["nicola"],tags:["javascript","bundle","bundle size"]},nextItem:{title:"Prometheus Is Out Of Memory. Again.",permalink:"/blog/prometheus-cardinality-issues"}},r={authorsImageUrls:[void 0]},s=[{value:"Intro",id:"intro",level:2},{value:"Nobody likes waiting\u2026",id:"nobody-likes-waiting",level:2},{value:"What is a "bundle"?",id:"what-is-a-bundle",level:2},{value:"Performance implications",id:"performance-implications",level:2},{value:"What is the recommended bundle size?",id:"what-is-the-recommended-bundle-size",level:2},{value:"What do we do then?",id:"what-do-we-do-then",level:2},{value:"How to start decreasing the bundle size?",id:"how-to-start-decreasing-the-bundle-size",level:2},{value:"Breaking up the bundle...",id:"breaking-up-the-bundle",level:2},{value:"Which strategies can we adopt?",id:"which-strategies-can-we-adopt",level:2},{value:"Useful tools to help you reducing bundle size",id:"useful-tools-to-help-you-reducing-bundle-size",level:2},{value:"Conclusion",id:"conclusion",level:2}],g={toc:s},u="wrapper";function p(A){let{components:e,...a}=A;return(0,n.kt)(u,(0,l.Z)({},g,a,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h2",{id:"intro"},"Intro"),(0,n.kt)("p",null,"JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website."),(0,n.kt)("p",null,"Frontend performance optimization is critical because\xa0it accounts for around 80-90% of user response time (10-20% backend).\nSo when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets."),(0,n.kt)("h2",{id:"nobody-likes-waiting"},"Nobody likes waiting\u2026"),(0,n.kt)("p",null,"A\xa0study found\xa0that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site."),(0,n.kt)("p",null,"Sending large JavaScript payloads impacts the speed of your site significantly."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Mazzarri",src:t(7017).Z,width:"410",height:"276"})),(0,n.kt)("h2",{id:"what-is-a-bundle"},'What is a "bundle"?'),(0,n.kt)("p",null,"Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application."),(0,n.kt)("p",null,"JS bundling is\xa0an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Bundle Everywhere",src:t(6865).Z,width:"448",height:"245"})),(0,n.kt)("h2",{id:"performance-implications"},"Performance implications"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Time to transmit over the network"),": considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"JS parse and compile time"),": more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"JS execution time"),": optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Memory consumption"),": everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!")),(0,n.kt)("h2",{id:"what-is-the-recommended-bundle-size"},"What is the recommended bundle size?"),(0,n.kt)("p",null,"AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Mr Chao",src:t(1262).Z,width:"406",height:"250"})),(0,n.kt)("h2",{id:"what-do-we-do-then"},"What do we do then?"),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Meh",src:t(4812).Z,width:"539",height:"399"})),(0,n.kt)("h2",{id:"how-to-start-decreasing-the-bundle-size"},"How to start decreasing the bundle size?"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Measure"),": first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI)\xa0is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Analyze"),": Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Stonks",src:t(3400).Z,width:"309",height:"229"})),(0,n.kt)("h2",{id:"breaking-up-the-bundle"},"Breaking up the bundle..."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Monitor network requests"),": These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Reduce the total dom nodes"),": the less the page needs to render, the less time it takes."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Moving work off the main thread"),": By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Caching"),": Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Breaking Bad",src:t(1278).Z,width:"299",height:"230"})),(0,n.kt)("h2",{id:"which-strategies-can-we-adopt"},"Which strategies can we adopt?"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Minification and Dead Code Elimination"),": These processes are often summed up as\xa0minifying\xa0or\xa0uglifying."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Tree shaking"),": Tree shaking is dead code elimination on a project or library. Always try to use deps which support \u201ctree shaking\u201d, Bundlephobia could be your friend in this case."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Code Splitting and Lazy Loading"),": Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Replace/rewrite large dependencies"),": Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example)."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Feature module import"),": Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Strategy",src:t(2235).Z,width:"307",height:"204"})),(0,n.kt)("h2",{id:"useful-tools-to-help-you-reducing-bundle-size"},"Useful tools to help you reducing bundle size"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Lighthouse"),": automated tool for improving the performance, quality, and correctness of your web apps"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Bundlephobia"),": Bundlephobia\xa0helps you find the performance impact of npm packages"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Webpack Bundle Analyzer"),": analyzes your bundle"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"VS Code"),": Import Cost plugin -> Display import/require package size in the editor")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Tools",src:t(4941).Z,width:"345",height:"255"})),(0,n.kt)("h2",{id:"conclusion"},"Conclusion"),(0,n.kt)("p",null,"Performance cannot be stripped down to a single metric such as bundle size. It would be great!\nUnfortunately there is no single place to measure all of them.I think metrics like the\xa0Core Web Vitals and a general look at bundle size should be considered as a starting point.\nYou will cry... A lot... But don\u2019t give up!"),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"The End",src:t(6899).Z,width:"358",height:"260"})))}p.isMDXComponent=!0},1278:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},6865:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/bundle_everywhere-12122e37ab5ca6bcdd61061c4dc32fd4.webp"},7017:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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FzF4MYb5dPUHhs5cr4W48fbG0YBO8KzHr+LA17KHdZxYMTAAUpcIp1VnAxgo31955bEsLblDFuBy5dlIEDsrWBpK464x+XXAKVkwXRr/6wHYa71OvfyxCA1GDVeOMppgCM+SdSSV+Z4ZOovufzwbrFiK3sBdeld88AOcgwYxb7qpz7mhGS+zB64o5jXBTZSyA0MDXdYQvBoDLJ20qMaLfoJFEqWGz2rC81rxT/bY7gBgPtFqMlpyIMYi4u3Yf1172FNN4/W/xvmZprZO3IbwFq9PQMoJbQXQrwxVYYZwvWGXERPk2Uhlz9gRWmzNaVqkp7mubKLzLAUJ6lcuebTvMqkcxJJymwmZtTUr5Gxvd/HWyOx2AAfyO55mL93wAKh7ARoMajGsPnAMsEfBuYIWIdlP2J4tFsRWmhppa6AQ0cfFbM4a8+RPS2EsWikEK0LhB4GwUWRPGqjgRduFXpKdIIclPO1V8FWUIErCbCAPvTG621JcUfAF9zBHAyEDUplreZZ7sJWMytQpAAkQo1oYHokzkMAkASVnsb09gWQHFj9DRXBQN7QHdbarq61G9+bdIH7RjBlmBo2PkcAwx6UQB2Gs+3fjaO2CxPFOSFo3qLw54OIXVcwaQOoFyZksQpx38MAMv8LX68Pl6brrz7OlB1oNcsJNDiE7+FeHZ/8/I0oZAAAARVhJRlYAAABNTQAqAAAACAABh2kABAAAAAEAAAAaAAAAAAADkoYABwAAABIAAABEoAIABAAAAAEAAAGaoAMABAAAAAEAAAEUAAAAAEFTQ0lJAAAAU2NyZWVuc2hvdFhNUCDAAQAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yNzY8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NDEwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6VXNlckNvbW1lbnQ+U2NyZWVuc2hvdDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cg=="},4812:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/meh-3b42aead7d2246467fd0101518403734.webp"},1262:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},3400:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},2235:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},6899:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,UklGRhIiAABXRUJQVlA4WAoAAAAsAAAAZQEAAwEASUNDUBQCAAAAAAIUYXBwbAQAAABtbnRyUkdCIFhZWiAH5gADABEACAAyADdhY3NwQVBQTAAAAABBUFBMAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGycI4tw2obgutNn6fT9ab4VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApkZXNjAAAA/AAAAGVjcHJ0AAABZAAAACN3dHB0AAABiAAAABRyWFlaAAABnAAAABRnWFlaAAABsAAAABRiWFlaAAABxAAAABRyVFJDAAAB2AAAABBjaGFkAAAB6AAAACxiVFJDAAAB2AAAABBnVFJDAAAB2AAAABBkZXNjAAAAAAAAAAtST0cgUEcyNDhRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIEluYy4sIDIwMjIAAFhZWiAAAAAAAADzUgABAAAAARa+WFlaIAAAAAAAAG+kAAA49gAAA5FYWVogAAAAAAAAYpQAALeGAAAY2lhZWiAAAAAAAAAkngAAD4QAALbCcGFyYQAAAAAAAAAAAAH2BHNmMzIAAAAAAAEMPwAABd3///MoAAAHkQAA/ZH///uj///9owAAA9sAAMB5VlA4ILIdAAAQpwCdASpmAQQBPpE6mEeloyKhK9Wd0LASCU3ECXcmYiUAQ0Ku96r9jfTW5H70PiUgJ7j0l5u/+r7AfF96jnmqpqvH9XvuxvVfYX/htzH/heEf7fm9goeVz4n6RvJq/DdESoAK+SRKjKksi/yRCc0V+eA/vVYRk6XuqAYGExwXDTFcqJv/MgIUmP8LmBxSWOCb8doXkFhYA9b5e3+gCb/2vra0ZIY9ceXGm0hFQ0fkVUA/OmHD3TinU7fwH65HT8sfrYfFQK/8/dAmmikKkWFS9ml67dsfvwcKciJHLzsrFYWc2AXki39z8vt6XU5pg2KXhOkeuU6U8OTkFWlY/MgLuPFfSOKU/TcD68/sNRILrWuqizlOQlhdci5546ZlL0148ngdk9ApZ/HEdH9v0Z4XqsGZuUCmlU+cgFVGXDV2gG7Eg7eOVMJqx5C89nQG9jF2jn8d6++6Yzdfe2xzcKBmVfcAQ+07G4Puy7wWvZkYHypFZgFPuEfTu+Wd5HpBme9AHbr5PuRqTsjmfklP828GWCgx2+162ynH8donGtdbeUAy+I61URZSlX9YdqRVVNibQSdExb6p+SS9JEHgs+1eHXs0d1x2cFJtqk6A0a5sXSzJCb0e7CXnkvxwE7MjS/prTYCKtCJgVgiHK1XM1Rly/WKpKjyB1moWIncBo3PgvMj5loTqA+rDzeRYx2yo5ey4dvDWf8vUIaaJDcjHxKNDwBqE73PExe8Bz6O4j1EKif6dUbi2Dze/JlJ8p24NnHQDS/rS656w/6w/fX7ecFBPBHiCGjC9AKbeCOP+ZieFTvO5qUic4iqHAyFwNf72PXxxB4sJpPye2F2QjMmqk+zdWhi6tJl36Vr0+1ysOs1tEahvbkFhj8FRX2WF6QTqL+jjfrVSmYFphaDGnhwSucwjtkHO2jfnOy9bAipVGBnT+ity6Y0S8nJglRmwgewPZYvvQMK52HEsgCacl+hteS4dVmJZNZz380ARHfBC8v/XouDpiPchdfgF/KGGm54XXAMbGxf0GvvSpoJimr4HYb8s09pmn9niUw3/iQTBf/atELZnkTNuIPul4Lq6Ag3tJpEprt75mgMkgC3Cn4mnQM05hSIAIiY/Vgme8r6JfBG4Dt+/QyA6lkdbJWHINiY0I2woCiNNPSIfi7Uz1UfOFlXm8Bd7+ZtFrrDo7y/cJoS5cSJbHOQCNHdptbP8/8UXRbonxm1QiqpZc+GeceESl2trZhdYDh25XOXMpQH1PEX88LQFI5uDinbcyoYa6QfhRKI4VKCB78KNLypA4NPyjGeDStTHdITU0jSI6fE9e19zIpUaAX/CnqncOsk6lEug1BC7UGcOYelhyzHAY7U1B68L1zKTaTHCL+/t8RQiJ4+X4hngL5nhmBnmUksKz1oXlzPyPRG8WNRzxz/rFp4o0Q8Tc/t36lq0WZaSs339/wj0SEU05GGmMk9UW3Dz2PgdC62GEmUXpPObjBSOmYRhWq+ALfKNSLzDNu4UM7s3qerSvJAw62aZvYhVAyE6zNArWZO90keO24rm6thp82U9BbFcaZlzlyGGJYdjcivXaeAmMULngB5D/sBgxMTnM67x4On7Aez1kfu7QqVwjbr0VnnbfldYE5waJ7r+DbK6d5yAz37gXz3LtiwdA2BgwT6zlBk5aGRplQrxhDPX0m84lhDFWkxo06W7/Foc2U9Dn6/A+Z+a8LfRkwGgUpWwoNgthN0hG0ETdrzR+v+I3U7jIMI0ZBTkQk6IZD2MFPKboKuos8/k/SEbSIfVsh7GECDCjNcwAKzgHlaEET322Qthf+D+PXBz3lbsq1gjMxPm3+M8OALqfeniSrzTNk76+TWkyZH+pz8jMzP8JJ9mdEc/pfTgMdadI+BnJaZ0Wcm3NvcYk0X1OGAqkytuEp2YNuAc5p5r4b5Sm73vmeQDWUIryR2F6FSsmxVKMK2FE0EbOY3fndvaAI92HyytVSf85p7MWkssIu1raKNlvbuOrYmDof/w/LofWOjh/ligLN30E+IyucGI8m/3YSoSE6rV9PRhv4WdoC2V/6qf0/qZ40lm80A7llP0LSwsjVr4OXnUhqaIVaElgVkvLkFB1U3gNvZXFnq8WLbZyr5oHv+H2962ITRsaWuUkr7+z8BukPBtUbvITNGuLXiYc17taO3T5E3nZs9SXBzyy7FT3Raaqp9+/4n+wXm5jxi2oFrI2rTXJ64XIuXy19Cy2gApoBUkGY8Gg+cDpnO2Z0ygmkM/4kIvHud9O+0EABdXfOZaU35+H5a0jyfXd4UevXus3tMnT/3CHDbg1iRcehkqK/q/ndbAdlEUOeIMZg+9Aofz3LVkhV/jgv91LDXJ//KSdvi3KbdRqsO24VzPnTT/DHy/DC/Cnq6uzO4XRp1SLyz0KTYRdoOR4XlkxlLXC9NAddBLWAVgJ+hrXI/edoYcwoq/PayPy7z94A103vwV43UVeBIjYs7uX4ObevXR/Q5mun4atkjPVW2wNQK8LQ5q+xiysMFObrobSL/+yUG1fj9Fca4+wVte9bnc3tc0qVdNHHbgMweVVK62Txu7DsoZttFmwwPaPCNgdarOhWH9bn3ls5XJwE/u43cc7wSIO/4xwFMpFOehYzGAdr6Gn3Z89Yu1hQGy2D/l2fpprBz3ENmhXl+etamx7zNfp6ngGBlKdiGkprYZQk7RYLppiMTybIlOMSOnS2Zzax+TzDJH8ml1+9gLTjNRTwgNW1oAGIVeOd7WLtUrV/J4LvGnm3i7UjqzA2aYAjETYuvxDV0tRTCn6cHEXenI2gehTgL7lO05AIRyLKNNHO0HnVcfDEmZlDhfXYhVfMQjCK09/OJ4NZI9bpJCG42ZxPmbMywhtmzsF9L3P1zRQwwgxs9Q+0FQDMCz0hF+tZhKQ9iGiKLiImCSWd18RwzsCh5N7Q/aR+e17moK5qRkJW6A3pwgnWD1/d0dBPXepM+PMfSGah0kh9rbtxgHP1iQPQNRrayo6WnfX3aBgJy02EUaDPZzZSqb0naWuGoqv8dnbx1EQjs2ErE40SAKMSgVeKpngYfbvQsccJumkiyuSKEiAd4Zq6fDC9GKKw4O7/NKonQy1gk/yGXxtsJiokiwL46HFvr7DnBZBMv2I9Op6f3BMP6R5Ys3ewzkTqoQRgj4BHB1RCMdV28MEyMSdJNq8y4SkPg/47TSw+Pn5137xukYSV8iZQQ1UThnsyMpkORg/r875F6VUwakob43sTdMRFwbBAQYBUJazlqWrq2ht6/PNF0KeHFeje1eUCfzkpxP/vpD32G9/APX6GecfUjNbMjpJzbogCRe1W+x32Ly///xLrQcguT58JFZETEoA0kz14N4NHBmM2XWoky1w6c6iLWLfNjDOi7SefMoGStthC8WcZ6eg1hJAVBrqk3xk5P+5jkLouaMbFwIsF1rOOnmYnHZlwyoIieQoLyhdCqsDNB3i+FOSmjDNwvH5EfhEJYLnRE4Z1key1+xJcXsDSjMQmQjAAokM55LI6SawZT4CnkxQAbluhb2oseU+Hwlxre9SOw2FtSDXqQJN6Q/27W3MAYXMEugW82AA+bVSfBkPSUV+XM/cb75/EsAkFDAxxAgFObx30Nes8lqwjzacEIqyh2gZkS7UKpUtmXZboaqwZpkarhX3bO+5E3JY3AlmskLRhP1igHnrW674PQ8g+xVeR9PrF1guLxfQz9U2kNUgVfKFWMAy3Gjgltx/jziqIPbCJtkzXGKzB1mZ2NN3gTrJ3GMy3qkFc8Dt+p00q5GjPh4X6vvtUAy7W+tHt2KYyjkUBonU+zClG55AJplREZ7sPi15wA2kWo+Fo/OnEfN6dypwJK6Ol+wwTFs9a8h8FQWWSX1rRv+sCR1IKTdkiRHloeWs2m+vt7zqdeueZlwJcIzHaWLr69Dp3l4WCV6j4WVtv+9qpgG31zaWOLtOsu1095Kzd1rBb4Eh/jY/BWZoMInyrDLMrfpzHrrtr4KH0DbVEH728kCxe6CNPb5JPRZ2/TlpbVBx4NVW7yIpx//5LD+FGNZoPrVXxxFbVzeVCWDLBZg0ft9PFxiQU3w3+c2TnU87WlXjYXNfzWD3j6+FltExmZ35zoYKQoAjrDVdAZAdFOW5X7rKx43y/XfkNQz58D3Xah1M3TA5T36VyqqQmri/YAZGc4hsZfrfkUdavOpl7Ne9iWOqxYYMXFdIcr17l85AWp8Czzz6rnUPkjTtvNOwk5ysO5vEVVm5Cnqu57m1B4KfCyXMi6Tfq+0nkWa7IIQJtevSKG219Ymtxg2O2rjfadT4oRf5M+AxC9Y7GOGd+RBru0kz+qimu+cI7v2VtSEaI0sH+DriwaU7ZRWzSCL8L9Us1NJI9BDCwH0qE4G8mgwlr6iYCd3q1+P7InHH77hJ41voQfE+P05il6MnKpFZsmZxsRiwSTZLoCO7lXnbK0MH2xp5WTD5ZUqbGKcUp4DcxfDBgBjt7xUhVN2dLCSP0FFo4tqHN5cW0pmDaYgrXeZJIiTDUFkGAO0epjw403O7a0d4aFtcj3tnZsUNoCaZcofaYPhuvfw763kV5xY+ahnT4PTzZk6s5IGCMFBbdeAkQcirDsLTzRwUD2G0OIZH7Fb+pWG36lTAoIYN9BvwrMAaEcbrCilMJg4p2JhT+BWquQYdxwtsaWwehw7xYVcoNECBxjng3h3qsIqi3d5T8ezUev1Xvh2DR+0zBiXVLEb5aPQZLovquFfC0Pm3OVrIsDzGzmZjRoRLH6f97JTT+tg3lmCbxf9n8rkd5HQI44nGYjpvFd3R4RTSqMRp0Lem4gr63bmJO5zQi565PgTjUTyceOycb+Sud7wMwyMFRouKyssYuAYxNpXbc4PRD0rJ50eN7msdIc/Oxx9DXPq4FAX1Ou8xP1D+qTLI8dZ+bKBEWwj/8y30idruD/inswlhIUvTVodODSjn2UnkOCstKVnu4MAG09uIWTK+y624Wffjvs7g1zD2YGu/S/plMMNgDkVe882Ys5V1ceQOl4maHI+DPzQVxfZwAHEwDHS6eckM9rYfOPAIL8AlLRAnS2RkodTjHMrd2GTMP2U+wFx4nTA+BgXQA0Zn0cLm1S4S4op905tc8vd9qnpoG3uEGSahYWt3cVWHovHJg2EWRX+alxFDOiOnzj8DJVrUTJC7EG9p9cucJMD3qZQPbtV2V9p+p/khGDUW56OZjcWdUz+ImqoSfC5IX10ZdcJagZ7w6S2StmxZfvuLJB4XrzJqf0rs/aeA5TM9N10UZx943xLe3ak/Sf1tEeCMnQQaZpAQblUwVtNRMJfoD1BfsuslARVYIO+QzLhX5X64mon/PtqC3JesupDfWybC4Gu70/f6Tv6w8JBPnf79bN5z6e85nirdwjSzNYkjZkMXDzwVdepX0QtTluBnMbazljV4l/xEYNINQttEcg3q8XvFqWETPBsAyrXP4+9Hd844MGOOsmj71SQb8jmv2lG0dhJHgouyJjfA6V83vNw6MmhXqv90ZFVrc8eQ1uLz+48Q0tI/cJf69670eHYKSjfTBYxA8upkViBo3FiamS8En7MbqPKv8+IFUyrB8LQN8CTd9OQkslzBW+FsjOmGBv5x9AnlVET7NbXn9r0RHzqCwx2ld9sQIjD13p/ezfTcfaRSbRFyemcLTohq2E8qPSPMEGeGwDpoDbMAdLdHL6L5eXKF7ziaTGE+jlW83ZfK5T6X/dgh31Xar/aPMIIX3To/0UWfvk53xFlRWA3F6hvxQg6ylJvNewiWUonhkwyaX+FhQPyBWNV0G4NPLPm17I4GFVlOm1rCz4byeETNOKhmzyt+RDKzVESvxdXEu9SQOYrRiOAS1EI4aNVRoxJMZaxZfQEw8hBFuhb5obKftj1KHbBcm8dsejl9/LOwue7mTCyJP1cnOnIBpwUi4p6PzsFZw0hP+4hYQprco6qmes8L07qYqMcTrooLE++aSVnb5oGQUIqQmfDSrkGdkMxp4mNvc322DupA8gWFrt1PxPeu4tHHF1ZaTThxy9sBVPbBmMWMkOE89wKByL0UJqOVGmUu6BO542lIsrazrAlcagb3+iMIFmI0kX8wFkKtTG5vSV1Aeh6Cy+WWwyp/rbkSsszvLQbw3cZHrYoxjm2+xfNmPtHQ30AlLtD1CVzI8k8CmPEwduuggBVVFccEfd8C2Ra78KODsXLuko42efCbbKFFrLNHhO6pf2mFlA9LG5sn9022nQEa9StGfu8MnHZAjSOrxmi+GJXWidbHf4h29GEYylMwOoA7RcbY/QQgibvzBVxQ3E69L9nCWrenNg6p3dxFXw8bs97a5eNnPgtSB2GBkJLBRdiLAs0UmDwBE0aaMA5o066hI0/zH7S2LSz8k0xuaYwO2Z7yNQzMPdJCT5FqZXO4nDldmDD+9Fp733q5nvw8KM/lYT1h86V6qKjA90AbfwAJgyx/b7vXB7mgLM3xfbZP93RAZKLgbs+id6DbVANPx231RzNfA7VmsJPaUGdqL0T19jHwtFCHPIXL171t5PFQYP0fPdgmRBnHDf/MZMbYOS7Fk6R+AywQysyk1wstd24V+jYC3ef4cews2xTnwcvf6hTOgNw0fxoJBO13I4ntLUqr37HcFzTosP2HaXr6LWzpkv2NMkBdFMY8ePBSVgNinXX79QQmg8h2snT3JvN7ywJLSrTFI0ayZVpRpalgwOk23Jh7yDr7kcKn/lx4N67k9PJzqRWALbLTBlQRYYuQhsCDPm6s5XhYghPfrMd94yBgM7IYnbtExgRA3Szyw6eDTL40TUU6uXqxU68Oz2U/01oH0cAJVYutcSBWeZUDH1LabmK/k2xyvZLHNnturozTIB+5iqeuOtiaMYh9+Thy/vH5MXBlWyOEv4RhKofB6YIt4CPMJszzvzxxgFK3F50djsHMx/qSJOxWhj6bSxTNwswCgnty3xcqVKivBcVFt4jNZtUEXpQR/IgRrE3JdwCeSadDonwGwZe2ia6hbrSF5iT73nfGH/7elVpFX7Uoby7rUAc3Z4AHMV35/ZHR4L0Cqn2PpZ9glMWXOq325IDp8oeDJkDblSifrYWKIAyq5cyh03ZmXMWHcV1+zRyMlxcM70tRJ9uiN2hrtiOqrTe1tPAJENsxK6dfuYTvR1+PSTKVPfKOWryyFb2cf67fUD9KhAr9SuxVQI6g9/07puZQT/t0BvkGKJdyQML7Sfa2/w5ORa+DLDS6FbmXkxn6D+pUxwlHIOZ7Hp8cAqcW7Y9Czw42m0nsEaNEg014iwX7G3vQQFv63LnTTKcij2Cp9L4EHgk07cf5YdlJeOWKZwGovbFSNjJ9cbP0q4XFQKxJ+9XuKT0pC9pPgRpbYA425V6HOZmejlGOLP/Fuc5LmxlNLNwkp7iQDDRWhFL5ZRB7vljsFnPM7Jctb6fid/kIiko8MgZq0UqR16FwWpf1AKRFzLa2rdAzjcK0VW54xt++mHGWAnyDQpWZdh4i//Ywi7ebuUhcJzcV39iJFSSUZ3UsVx/2yIacKSJtn+F05gxOLbBCPwG/uXNMFMUlwinpqbZ9QKP8ZhHnEVvbK+asgPPQDg+TW8wVx4rJoD9Yiv+OzM6W8UMKKZAPz92fgteUmbQ5mqp28N0m+rDpFee9yzeA2Etoik7lBJbNOb+OrU/B+UcAWq2tLa065Ztnc35U4C+G56Om5Q69YF//vgRVNgA5ZMgDT4ekNELTNoYwiOt3l7utT0x9STwuAxPY/8LuO+6rdRjy3SWzGsLCuVA9LvPfh/bWw1VpIhOUPGGkPu5IMq5yeyY+Z41/lfCT934N1nulkRnSrTZkkwS25b5BbJltEdRU0RYg2rwDdOVM4sKBeBQxb0v9KCtOJ/A0BaTB81n8w4tj2h0K8/OMsgNWHBYalToIvVebwtd6BWj3jeAgBJkIj2pe3Uzqv2qD3ACcT/jyjDJqvaAll6UAGWlHZdKMcv9oUR/mtcAUsqMIu9zEWmabQxe+iJqP155GJCwgf/lXF7GB3BwT6z3jhuNggpL83yg7nvsF2360H+kO3zWaq9zE20NcTC46fTvqMdYHJrkzT0YiyzQpiWpKRY+0S048ouh1s5jgnzh0BPrla0zMK+FHbIU7Dxd0R1TXrwpe5mKxDUnB4FEjA0lg9uqkVDzv5rK8/MsM7J9pSaqVMLGLv+kuHuxzhXgnTljt0kKa58/olSitCfP1CCsCFItE8yD38UMQ+iIzWe9NgrzBk7vnMK7IXL8H45P1faOcl2v1Wy1KM7Jv+ca3lYDT2TxDBxY+Fcnu7alxlO2ukm8n1tlRKHMhm+NWiX7q+pQamEmfi0/A5tSG/bo24Ws0XgElFc0tsWLcPy5eahFmO2fUvk6pWyNmWUb6KqcdqfjvvxR1QzwXO6i5Jc5Wdod22vXv9qr4PXY+wk/fAzGprvhJHFooEAAecGLPgoN2fLpFGZMB8qixSShtf9/SpJTxHYX1mNB0JbKwstF+1H6qMRqsav4g/rnSBV17x6s/YolqbO5HJeoa2ejkgDdsIvu613bpw9WC1K3xMtKRd8by+0cUkSRx8nzBO5Ui6wFZ8eRU0WM3qs21tGtbHFxFCTCuCH/IjtTtCL0jh3zUvZE9fsgo/xymaFrMcCyDyYrIt38bLNcdocAI8UJUfRSgImTTH3YuZd35H8dAO2RsRuJ6g771h8Gkw3dLEpZgeMrqAyyEkuWjrdpVhYJ3HpnPiHn+1dgkiIGPnc0FYtvxA6jN+LPUiuwiV69IbXWYo7P7K1OrtjmLHweytCxhDIfbXe0Bx7LAjZD+Q8Vz478zABAdzkk9kd0RoBlOIa/qYxtFos24FhPIa7fjcq0Uc+CfBE2fLUn0vZLqz3oPWyruYU4lKLBT+ei7srbAZra3VKSTwTdSBwiBanF7SvRWzkSHG/1hmHbMzOnIsG9wBmXMjE165tLfXaPiYxPAck0Sq/nadsws8qp+wFDV+5p07O/CcvhK7JTy5iTll/Er+xbFQNTaAuxQ8eexHWwxrNFievvxJvmFdEol49s/MgVm/D1gNMphSP2JqwlN246KFdEF5UP0yknrJtOAc/2Cq+MKreh5LILfjUHJNDGB+WR1U4A98YM3k0issrYTnRt0KcHLjWumjbc0r0tr2FJKJ2o9uIrQWvfJ6aLojJEWSzuh+vvV+s88mbDkdy4bSPYs8M9xpNxZ78g2B4hG2VoUAT3OvIs7Ima9y+62xqfVoLRxItbrzniKbOd+WL9TaKmuU/3E2L4Ad+n+swWOpp1o07Rzx+U36WPMBQWynmwhtLTT6WFMs5wPMlnnvMT/pDE4+fLC8rbmgySQX2itqKty4DyM9P6nEPpUyxjGN8uLNu3gGs2eK7bAhBYlCq7h29SocAR0HkxHNwahxkmsBmjoAFcHuSDEtCFxEkKQLFHNS8WR1Xz2UZZlDWw/7jSGARIuIM0o0JyCs1CNkpnnhdoTs+VbKfrkQLXJ1vBwRivAy84jW+oAgeOac98u/jl3BkjlkHiEtjjgiEfpU2LQroHpbieo2wvKUxY5UvmL14PUsl/RY1IYeg+0jMkh1LyiEF1sNwbSCsb+Xk/ADwgswBy8Jerja09441xR2ObXf9kM1QvxB6BMB2gT2arX16Pi93UcrKOL0MUNyz0k5VckzNQBO6kGXxM6koaCNpkc2Rx5m388xHQxN1WL/CLlzCkG3T+1MnXAdQD9hHbk67kWy1cueKuoili68tGJ15mPD3BGNyAQu/deSh+XU2aTEX14Yox2q7+opM41bQhOjPS+q3cZXWQjuD5F9r1rXdfVHI0P0w6SHswUulZ3Hwp3mtpxoIw2NcuZRDWTqR4ujBGMIlS6HZHx12UTHq8eUzkjEubP3EmTLSREOKAVjwAfrwXmmlTzbOKxhW63VP6ex+258Pq2bPAaE+lN1A0i0nZORrsBv61Nn/liSCg815zqJlzPKkM5YDtr93ZtTjG5OgsYslCAAAADmr4khU4MCdtz46OoMhTcCSjD0bNH7MNakjoJy/pIKZOe6eFjFo7yNF2OXv4UxRamnlnv67yxTCRX6ih6BWoTtiHwI66NeUjzYHdHCoQQKGTDPwrANqyuWgfclc/1hrArVWGm4VRJzPMcTABhZHECznZ7JiILyMKVoVh6T0M+rB4AABFWElGVgAAAE1NACoAAAAIAAGHaQAEAAAAAQAAABoAAAAAAAOShgAHAAAAEgAAAESgAgAEAAAAAQAAAWagAwAEAAAAAQAAAQQAAAAAQVNDSUkAAABTY3JlZW5zaG90WE1QIMABAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI2MDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4zNTg8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpVc2VyQ29tbWVudD5TY3JlZW5zaG90PC9leGlmOlVzZXJDb21tZW50PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4K"},4941:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/tools-91886b41cefeef7cc35b5cd21c43d2ba.webp"}}]); \ No newline at end of file diff --git a/assets/js/26ea2a44.e95e0c70.js b/assets/js/26ea2a44.e95e0c70.js new file mode 100644 index 0000000..63deced --- /dev/null +++ b/assets/js/26ea2a44.e95e0c70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[1435],{3905:(A,e,t)=>{t.d(e,{Zo:()=>g,kt:()=>d});var l=t(7294);function n(A,e,t){return e in A?Object.defineProperty(A,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):A[e]=t,A}function a(A,e){var t=Object.keys(A);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(A);e&&(l=l.filter((function(e){return Object.getOwnPropertyDescriptor(A,e).enumerable}))),t.push.apply(t,l)}return t}function o(A){for(var e=1;e=0||(n[t]=A[t]);return n}(A,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(A);for(l=0;l=0||Object.prototype.propertyIsEnumerable.call(A,t)&&(n[t]=A[t])}return n}var r=l.createContext({}),s=function(A){var e=l.useContext(r),t=e;return A&&(t="function"==typeof A?A(e):o(o({},e),A)),t},g=function(A){var e=s(A.components);return l.createElement(r.Provider,{value:e},A.children)},u="mdxType",c={inlineCode:"code",wrapper:function(A){var e=A.children;return l.createElement(l.Fragment,{},e)}},p=l.forwardRef((function(A,e){var t=A.components,n=A.mdxType,a=A.originalType,r=A.parentName,g=i(A,["components","mdxType","originalType","parentName"]),u=s(t),p=n,d=u["".concat(r,".").concat(p)]||u[p]||c[p]||a;return t?l.createElement(d,o(o({ref:e},g),{},{components:t})):l.createElement(d,o({ref:e},g))}));function d(A,e){var t=arguments,n=e&&e.mdxType;if("string"==typeof A||n){var a=t.length,o=new Array(a);o[0]=p;var i={};for(var r in e)hasOwnProperty.call(e,r)&&(i[r]=e[r]);i.originalType=A,i[u]="string"==typeof A?A:n,o[1]=i;for(var s=2;s{t.r(e),t.d(e,{assets:()=>r,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var l=t(7462),n=(t(7294),t(3905));const a={slug:"why-bundle-size-is-important",authors:["nicola"],tags:["javascript","bundle","bundle size"]},o="Why bundle size is important?",i={permalink:"/blog/why-bundle-size-is-important",editUrl:"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-03-17-why-bundle-size-is-important/index.mdx",source:"@site/blog/2022-03-17-why-bundle-size-is-important/index.mdx",title:"Why bundle size is important?",description:"Intro",date:"2022-03-17T00:00:00.000Z",formattedDate:"March 17, 2022",tags:[{label:"javascript",permalink:"/blog/tags/javascript"},{label:"bundle",permalink:"/blog/tags/bundle"},{label:"bundle size",permalink:"/blog/tags/bundle-size"}],hasTruncateMarker:!1,authors:[{name:"Nicola Turcato",title:"Memelord brother",url:"https://github.com/nicolaturcato",imageURL:"https://github.com/nicolaturcato.png",key:"nicola"}],frontMatter:{slug:"why-bundle-size-is-important",authors:["nicola"],tags:["javascript","bundle","bundle size"]},prevItem:{title:"Accuracy of decimal computations",permalink:"/blog/accuracy-of-decimal-computations"},nextItem:{title:"Prometheus Is Out Of Memory. Again.",permalink:"/blog/prometheus-cardinality-issues"}},r={authorsImageUrls:[void 0]},s=[{value:"Intro",id:"intro",level:2},{value:"Nobody likes waiting\u2026",id:"nobody-likes-waiting",level:2},{value:"What is a "bundle"?",id:"what-is-a-bundle",level:2},{value:"Performance implications",id:"performance-implications",level:2},{value:"What is the recommended bundle size?",id:"what-is-the-recommended-bundle-size",level:2},{value:"What do we do then?",id:"what-do-we-do-then",level:2},{value:"How to start decreasing the bundle size?",id:"how-to-start-decreasing-the-bundle-size",level:2},{value:"Breaking up the bundle...",id:"breaking-up-the-bundle",level:2},{value:"Which strategies can we adopt?",id:"which-strategies-can-we-adopt",level:2},{value:"Useful tools to help you reducing bundle size",id:"useful-tools-to-help-you-reducing-bundle-size",level:2},{value:"Conclusion",id:"conclusion",level:2}],g={toc:s},u="wrapper";function c(A){let{components:e,...a}=A;return(0,n.kt)(u,(0,l.Z)({},g,a,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h2",{id:"intro"},"Intro"),(0,n.kt)("p",null,"JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website."),(0,n.kt)("p",null,"Frontend performance optimization is critical because\xa0it accounts for around 80-90% of user response time (10-20% backend).\nSo when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets."),(0,n.kt)("h2",{id:"nobody-likes-waiting"},"Nobody likes waiting\u2026"),(0,n.kt)("p",null,"A\xa0study found\xa0that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site."),(0,n.kt)("p",null,"Sending large JavaScript payloads impacts the speed of your site significantly."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Mazzarri",src:t(7017).Z,width:"410",height:"276"})),(0,n.kt)("h2",{id:"what-is-a-bundle"},'What is a "bundle"?'),(0,n.kt)("p",null,"Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application."),(0,n.kt)("p",null,"JS bundling is\xa0an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Bundle Everywhere",src:t(6865).Z,width:"448",height:"245"})),(0,n.kt)("h2",{id:"performance-implications"},"Performance implications"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Time to transmit over the network"),": considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"JS parse and compile time"),": more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"JS execution time"),": optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Memory consumption"),": everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!")),(0,n.kt)("h2",{id:"what-is-the-recommended-bundle-size"},"What is the recommended bundle size?"),(0,n.kt)("p",null,"AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Mr Chao",src:t(1262).Z,width:"406",height:"250"})),(0,n.kt)("h2",{id:"what-do-we-do-then"},"What do we do then?"),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Meh",src:t(4812).Z,width:"539",height:"399"})),(0,n.kt)("h2",{id:"how-to-start-decreasing-the-bundle-size"},"How to start decreasing the bundle size?"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Measure"),": first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI)\xa0is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Analyze"),": Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Stonks",src:t(3400).Z,width:"309",height:"229"})),(0,n.kt)("h2",{id:"breaking-up-the-bundle"},"Breaking up the bundle..."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Monitor network requests"),": These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Reduce the total dom nodes"),": the less the page needs to render, the less time it takes."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Moving work off the main thread"),": By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Caching"),": Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Breaking Bad",src:t(1278).Z,width:"299",height:"230"})),(0,n.kt)("h2",{id:"which-strategies-can-we-adopt"},"Which strategies can we adopt?"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Minification and Dead Code Elimination"),": These processes are often summed up as\xa0minifying\xa0or\xa0uglifying."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Tree shaking"),": Tree shaking is dead code elimination on a project or library. Always try to use deps which support \u201ctree shaking\u201d, Bundlephobia could be your friend in this case."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Code Splitting and Lazy Loading"),": Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Replace/rewrite large dependencies"),": Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example)."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Feature module import"),": Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Strategy",src:t(2235).Z,width:"307",height:"204"})),(0,n.kt)("h2",{id:"useful-tools-to-help-you-reducing-bundle-size"},"Useful tools to help you reducing bundle size"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Lighthouse"),": automated tool for improving the performance, quality, and correctness of your web apps"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Bundlephobia"),": Bundlephobia\xa0helps you find the performance impact of npm packages"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Webpack Bundle Analyzer"),": analyzes your bundle"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"VS Code"),": Import Cost plugin -> Display import/require package size in the editor")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Tools",src:t(4941).Z,width:"345",height:"255"})),(0,n.kt)("h2",{id:"conclusion"},"Conclusion"),(0,n.kt)("p",null,"Performance cannot be stripped down to a single metric such as bundle size. It would be great!\nUnfortunately there is no single place to measure all of them.I think metrics like the\xa0Core Web Vitals and a general look at bundle size should be considered as a starting point.\nYou will cry... A lot... But don\u2019t give up!"),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"The End",src:t(6899).Z,width:"358",height:"260"})))}c.isMDXComponent=!0},1278:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,UklGRu4UAABXRUJQVlA4WAoAAAAsAAAAKgEA5QAASUNDUBQCAAAAAAIUYXBwbAQAAABtbnRyUkdCIFhZWiAH5gADABEACAAyADdhY3NwQVBQTAAAAABBUFBMAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGycI4tw2obgutNn6fT9ab4VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApkZXNjAAAA/AAAAGVjcHJ0AAABZAAAACN3dHB0AAABiAAAABRyWFlaAAABnAAAABRnWFlaAAABsAAAABRiWFlaAAABxAAAABRyVFJDAAAB2AAAABBjaGFkAAAB6AAAACxiVFJDAAAB2AAAABBnVFJDAAAB2AAAABBkZXNjAAAAAAAAAAtST0cgUEcyNDhRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIEluYy4sIDIwMjIAAFhZWiAAAAAAAADzUgABAAAAARa+WFlaIAAAAAAAAG+kAAA49gAAA5FYWVogAAAAAAAAYpQAALeGAAAY2lhZWiAAAAAAAAAkngAAD4QAALbCcGFyYQAAAAAAAAAAAAH2BHNmMzIAAAAAAAEMPwAABd3///MoAAAHkQAA/ZH///uj///9owAAA9sAAMB5VlA4II4QAADQXQCdASorAeYAPpFCnUolpymhppRq0TASCWVuvmuw79keW/jednnzCQ/RvwepvytelDzpunodFr6yV/HdabprfdChx8p/BX73/AelXhL8edQj8n/nX+z/LHjIgB/l/9k8AbVN8I+wFwx1AbxeNKP1x7C5RlQHbXX/SmLxg06O4ESVNMvFPll/jDjWw+ePOaso3Z/rv8wUwX0sS+8NcGQzbTICuUaT8rpjVX2cE6IpxLvORxOqA5Bs60gIcifRZ2w5Up/m/HMWQSgHbVtQkLDuwzQDd+Kq3sXiGZ/FT4MaxEwkPTjCkA37LFr2YEOcQVFx/BYRdF3czzTHjeGvKxLtcelUKQO/itvqoSDR1tdptNfplWnz48M+8xwWyRylqjhlq/aAaf1duB1WO3m9Rnq0EFTRBibOPSVUSP6OGrag1xnRWudnaKKfcdQstHaRdhrYlTZR7nUPBA6emSdHqF4YCG6gYnxuDupJ2BPZl/sa4t95yaCZ2iDiFXtxFDdDFaE8vlxFQInyEV7Sso5xdzNNSvGSsYMZxMe7ILpmCFSf+kBWA1IyYHzOaL1CARNtwflzHOr+JZDu1O7h/LRCzZAQpExUafNAXl5SGgU9zCy6Qi9FDvHK+DBjigbsc8K6f+kda3jFwaV1opsOzjWuOiQJYAWgayDHwWwqWEwxJZWxdMEPwupQju958GVr1qggM4mCWQIhn2QcDHDC3EBNEH87E8qfSBi7br4rbtczIHA7bJyr4ByqI3niOPou0pNW7Ev3JC4+en5UQ/AWYZWELa3LrprKZew7QPhMvwVVD4UhIwiH7eOF/zQxdS6UY5IGgPq2ENVSPHJxWxse8mDBlyglZE9Hw022n/SmLC4vKFjVfvOrKnkoSrSmjcxycepD5j6III9LNGyiAswysIWSXGRffD7kDrtNlAvoh0twuXZVHfBoCGPSGzbXFmziUS/eUm9lcj/usNSJHPcTK7mbZJsnK3843xGtHpDZxv5soY8b4B215MSzloAA/v3UMfWi1FR+yKPIyFHA4u+pqnCrIquNx3IuqtjAD5zBgNXBY63ZrxEZOmthL23ZogncuQ1aDAff2716s/baz3My4Z5tSqemGx93vipcNRmY9EAB5/UBzWonspFvm2rw7Mrz8onU9ggBI7UHI+OQbR4790sDcXCoJV0//3c4p50+aHhfM0lm8rCBIFR04J6d9xKrudb5q4+y53kPA1uds3jqDSkpBBaNQ1Et7N4F1ndBBoj6N3M5tcKqaSs0z0CLLHknEqgTohA9RSYGmvzcuo7JNVjUFzfR3ChUkbxRmtG3wB4cOjDeVJZ/QouLRly41g0COis5voBBZ9ecJ8qBSF8/zsu4urY1/40ggoLoCBLx5zneqOrAsVEz9PxGPrzZtj3b4BR0DQtMD2NX/DyRaezxOnJ4L8P59L3hNfXz87Gyv9jClZSFoSZ3jVqFz6mfVJO1f276jju4hyesrHSYXdwDEVzrvfsh30YkebkEynaB/W+X68OLT3s/76gODEvVDGupn+ACUmrB1qJ90TXJh8vr5RcYPCZjmiSFECy65++GLCyBvlkmnPNGfFmEcRiB4DtOq7Uz83tXFKF+SulchLz4QzY/m6K4xlV/697103TcBzR5j28nW82VN6LuyaKDYBIN+lejFUvD6DNPNTtQO4v+lLvulaCranlodvzoVqN85u+K0yAgBGo1X1rgYQ8Mant2UCMDCs+EzTmiorGO8s/JpR07QGudgcmnpsrzwFdX4C0ZJPQu4Zy1WGUNlIddShumGxdE96njZS25EUPA7I+TDBVO47uV+qYbcqBWQz5AucWvfMI6hOVizCp0nn8v7ft6hCaQwh59J9mNSOcZ3Z6nrLH3kSQ0JdOnsjDIRUTEh1KfcdOuagL3TrjoUTakOCzxAXIMT13q9Q0TZ4qNXYlCaVGFe2X4og7ZJ0ejgZWEOut6XfFTmp4MXsOL01gsFORtxUddDqI/1Uw7ic7kuOG8G2tK0/F/TvKo5P595jZYXFXnswhHht44rVhVBdzrup58GWUWVxN2gRNbX3v4WzfRak+gt5EQHyPJKKHwgECt4xwfUEIzc5Lw5VGAl1mCDJJd6WDNlXpm+wFZ+xmmBuKfMamh3hFEgylOS5dmBtrtP05pL0Kc6N52vAXo+ZYnF3Pm5SPLqc8e+Kd2INxc0b9zrepdlCCOV598yeZOB4UHEAngMXKklioIBpdi8EdOphElnoVG6DUWnU0xzC5wu2/UHVw6bWt+vZPtY/ZDi34uq3T8vPExfmTt0m5Dc5R1Wdq1rbjZWo4g79iQvx64BIafu43nrulz9Gl78khsFdGy0aAP4XR8eJFHNvTIOvI4N/8Xyoe6kVarpLlnDC1pJSOWPk8HWRiK4m7wW5uS+6d1MOzsRTCjrXJrGvGsJ8UDE66ldjEASuaurRVKk4Um7nuOZp63GKERvFq0yTUijW2HC3zeX1nXXVIKF+DNuMPYiuj5gPnzW6iat/c1YZhJ4+7WYE0pKUQdpKpZe/z1tjvNlqonMr2BihCe5vGu9+P/E03au3S7gaik7coH0JQSloY2wv9oszKysaW5AgERKpD4prsrl/5l2dd7AMCyS1m4Mo17waPqtb03Rqjcoen0i0a/nhzyGFa2eaEDEVSHqbOzbZVFRYRFeGAdCvEVRFvuUqUEvQVYfw83LI3rks1pqkaYFgY8lHg2Vcpe693D2vIYt/gXxoZBh1EFDxeyJ/yhLCfWO5J6F0xxLm27VZPQDPpBbiIR/mcWzjGAC4nTQ4ymcilb/siMz6NRazz3tHuCJxktvdLBgfPGJjd3LRFy/gc262zXk0B64KNuE7wq44C2PXdqrceIq3m+u3VCD2EYJ44Wf61FfwNOrfkDkdmmgvRinnvlXvjLI+PAL3GJB5fhJaUaud+ijqq9bRyv8PgYff1UupN5FFjLzB2pqh0z5RyeC8Nz3UUvpY1xJr1GnvD1PYocvzeOljhjo+A0oplWrpGSnf+5zKgYY8hGmt1eJHqdgSXh2vidqdO8ZEEeBvT0FX7jr6JMroyI4aar2X2wWk0oQ4oHE4uAPShC69u4Lq7K+d/h69eEXob7Zv89DEVNISHb0rAI3bO8zMWQgJdhr0DJQVcXYalie0aWIEqGHMgZAq6BGpjUJzk4oSSB3A9Hb4Ckd90u51CVjtb5m920knNodVSpBmJt9d98HRjduTv/gCibNWOdEJptBdmMca4usEf2SbSnefhMSnXscI/85hKdw9uU6z5/YLboLZfPkndObMKrppPIegKB0Fa/fsgXVrdppTB+NsUN0ZYoeT4E22Z0/T5N+p6SAP0Sw9zV5vVHBVyCznaQhMQcYVScbiGa4gyPx+cZ6gBLcbxS2kmt6QNJZC+F05T/NqGd/JapdhVARpTLD8jrvJK3i+18E9VW0ROcXTg2TR/fF1lKVyqzT1xK011piRnyNkZu8Ik8Dwlmi9iCX4e4OkXhu7cYWzAwxyJcj/BJoE0hVq6Vn46Jtjdf0t40HuZVJK0lVBrLMKzyQqkMvrIuf7c0a1aW6jmMs7fTFYeb50hY+YLJxtwP+1Fabh0/siNDqqYy1NI9NYim77DItRhH9v29nTruX4bB/nfnUed4is//efWaWYrTvZ9QvH//e4B5X5n4irLeS8D5fH729bqhuF0w+M/sh04QNfBNohtiE1uWl+Vf/8BaeL+7VCO4D6K0XEbO9K+0x9/Udh49sHR20964G0Wsg2OI5FQ+tpZaUJLF60RpAIbVMk0Xz+WcpU5L+G0q5ONuro3aNc40DnAU1IiS5f8r2I94aql0PQx/VjGP70JgQLocs1O12pIiITbSgA6WkYnCSH/OlEngrgOOGcQxnC71IAZj0BC7iJg+gMxQerK75QWSbDNU0FLzNZKHUVR+Z7+mXlbHDYf5HE3mnk1qfaJueSQEE7DGdgIl+0KQmGSAGd2gv4meXJl4nmTUMKVnmOzdqXNFJKeU8RkQaYRJRvQ5cXBR6inLPaNxOV77qvqTavkU5MjqkvRkAqlwt4iSSdX2xq7fRswgFcB3W8vuey8KISQSWSibx5B6YKyp5RI2qta5pls7xcmfecwHn4psnQmWER49PdW0WxB0rDRJwD8Qs87HLj3IEJnvZNlQ+1PIwKC2VYqBwrYzfgBies31Zs6PKDqLmreEAoVzjDsEwle8jEsXc8m1yEYAy//K7YzelD/5SfC3D/H56iMGRquiVtierxvzEvPUlcC1kOoQS6+qjX3PblNbnXi2zwUKoIu/L9znOdKXJAm0yJ00d3UyXPBImYtSGKwrNII406/umb0KoWDmG5ODoUAr/CkcizwyYf83gzcYUgzuWrhRuBY93Z7t6iDdnAvpC/xgigttxO3BIcTN9W8/s70oWYjWWzgeA6hUVptA7jokfcpFQeHXkJR8CYPjV+Co46nwnzsqODjH8tw2DdDxUGAgSqeX1CEp1yTg0uH4TuCOSW4zhWRdZyB7mTuUTh4F+JfLXj54MF/v4fjZg//80gD8oEu0REk7HsThE/S7mue1cuP54b84vx1csk+5yfEcDngMHqrO7ddclsdwpJ3nFupX3j+kTq4SNiterjOeFZLEGJAh+uqdmJkeDvJZYLLEkoZ4lAuMqZzEJgGGAiEHW9XOdoOLJ66oL7pkj9KSUU4qq4vhhuYuuJVgEnNXmwW/s9r1BqNSmt86vX/m2JaCHo7+AjoAtS+5nFGHc7Atift+PBl38z3pE30SAhxjqBW48jYb5rACVwpOKAElxIRjf1EhZF3oCFHxOzmaFp6Lo5B/+I1AOOoFrA6qAThfOmdxBYfTcNPfCgHAYt/eV708nR9J2JCucQqis52buSvcfgiIjPduJusdznnuuSMAASTJHTr7/bqkS5WicvEifcKV4hqy5Y0XguVLBWnxZGs0UCj1Z4mylwHA6MdpTK3DUGvUTog9FlgccHU94QZI/GnHSJl5+PNow2IOY4qNiPkWlimh7fPAVkpVio7j1t3b5brdieRPrFu63uTWC6fgIdVupQabPLFO18+fSp0sRlfNUnW/cPXXiNqpLWJdnUY/MvxaPdhDkeF/rYQv06teV5PLfe+mvNz89DbhzHuNHKr1XpEtf3A24e62TiO/Gue4AVSoLoFq1sqDVR7Rp5tQUXJxl0WpAcynjD0xHJqygM98yfdCcTIj0GjqKnqAEdDwO0PH7lamPzxIh6UgP5KwXy/eWqL6IQ8mjH3+naKas9Ygctj+D+EsAtpm6jyJYaB/q210PZq/I7eBrEGKsu4NbxifpZBRvM3qaOf6sU1gIJQ3uPSBi/imyh8H+FR7YJAIerUmCmG2gkixQ58pD35x4D2eEkX0ST6s9K0BdBhy6aBYTyfzVL/sqwPmPl98JKRFDILRL0MTL5Fs8e4yWwKD6GCeimsjBn8UtXDiDG/yJ7UX334fw3A5aBBdJgvEhNkPgW751zz/UQV8pGMnECYjUbaX1am/9wAS9ZW9/ug6gwAj0KIqDTGioCAbBO2EKDdZC9ij2ekoHO7Aoc0ijUmdjCs4u8JAC30uO9MhQd3Rnilz5l3Wm0wijXEKrLoFY+en5A8evExFVM5zF3zPJN6yutmlXL1BJBhelXYIz64i2g7cvoiXrAAtPEVcDpqAZzAAAAAAAEVYSUZWAAAATU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA5KGAAcAAAASAAAARKACAAQAAAABAAABK6ADAAQAAAABAAAA5gAAAABBU0NJSQAAAFNjcmVlbnNob3RYTVAgwAEAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDYuMC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MjMwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI5OTwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlVzZXJDb21tZW50PlNjcmVlbnNob3Q8L2V4aWY6VXNlckNvbW1lbnQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo="},6865:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/bundle_everywhere-12122e37ab5ca6bcdd61061c4dc32fd4.webp"},7017:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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FzF4MYb5dPUHhs5cr4W48fbG0YBO8KzHr+LA17KHdZxYMTAAUpcIp1VnAxgo31955bEsLblDFuBy5dlIEDsrWBpK464x+XXAKVkwXRr/6wHYa71OvfyxCA1GDVeOMppgCM+SdSSV+Z4ZOovufzwbrFiK3sBdeld88AOcgwYxb7qpz7mhGS+zB64o5jXBTZSyA0MDXdYQvBoDLJ20qMaLfoJFEqWGz2rC81rxT/bY7gBgPtFqMlpyIMYi4u3Yf1172FNN4/W/xvmZprZO3IbwFq9PQMoJbQXQrwxVYYZwvWGXERPk2Uhlz9gRWmzNaVqkp7mubKLzLAUJ6lcuebTvMqkcxJJymwmZtTUr5Gxvd/HWyOx2AAfyO55mL93wAKh7ARoMajGsPnAMsEfBuYIWIdlP2J4tFsRWmhppa6AQ0cfFbM4a8+RPS2EsWikEK0LhB4GwUWRPGqjgRduFXpKdIIclPO1V8FWUIErCbCAPvTG621JcUfAF9zBHAyEDUplreZZ7sJWMytQpAAkQo1oYHokzkMAkASVnsb09gWQHFj9DRXBQN7QHdbarq61G9+bdIH7RjBlmBo2PkcAwx6UQB2Gs+3fjaO2CxPFOSFo3qLw54OIXVcwaQOoFyZksQpx38MAMv8LX68Pl6brrz7OlB1oNcsJNDiE7+FeHZ/8/I0oZAAAARVhJRlYAAABNTQAqAAAACAABh2kABAAAAAEAAAAaAAAAAAADkoYABwAAABIAAABEoAIABAAAAAEAAAGaoAMABAAAAAEAAAEUAAAAAEFTQ0lJAAAAU2NyZWVuc2hvdFhNUCDAAQAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yNzY8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NDEwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6VXNlckNvbW1lbnQ+U2NyZWVuc2hvdDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cg=="},4812:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/meh-3b42aead7d2246467fd0101518403734.webp"},1262:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},3400:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},2235:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},6899:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},4941:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/tools-91886b41cefeef7cc35b5cd21c43d2ba.webp"}}]); \ No newline at end of file diff --git a/assets/js/487ae42e.a0943f9c.js b/assets/js/487ae42e.a0943f9c.js new file mode 100644 index 0000000..d730d76 --- /dev/null +++ b/assets/js/487ae42e.a0943f9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[9851],{6920:a=>{a.exports=JSON.parse('{"label":"decimal accuracy","permalink":"/blog/tags/decimal-accuracy","allTagsPath":"/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/assets/js/6b9bd0c6.76e75916.js b/assets/js/6b9bd0c6.76e75916.js new file mode 100644 index 0000000..b285b49 --- /dev/null +++ b/assets/js/6b9bd0c6.76e75916.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[7609],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),u=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=u(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),p=u(n),d=r,f=p["".concat(l,".").concat(d)]||p[d]||m[d]||a;return n?o.createElement(f,i(i({ref:t},s),{},{components:n})):o.createElement(f,i({ref:t},s))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:r,i[1]=c;for(var u=2;u{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>c,toc:()=>u});var o=n(7462),r=(n(7294),n(3905));const a={slug:"accuracy-of-decimal-computations",authors:["patrickb"],tags:["golang","currency","decimal accuracy"]},i="Accuracy of decimal computations",c={permalink:"/blog/accuracy-of-decimal-computations",editUrl:"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2023-03-06-accuracy-of-decimal-computations/index.mdx",source:"@site/blog/2023-03-06-accuracy-of-decimal-computations/index.mdx",title:"Accuracy of decimal computations",description:"Intro",date:"2023-03-06T00:00:00.000Z",formattedDate:"March 6, 2023",tags:[{label:"golang",permalink:"/blog/tags/golang"},{label:"currency",permalink:"/blog/tags/currency"},{label:"decimal accuracy",permalink:"/blog/tags/decimal-accuracy"}],hasTruncateMarker:!1,authors:[{name:"Patrick Buchner",title:"MSc",url:"https://github.com/smartinov",imageURL:"https://github.com/uebriges.png",key:"patrickb"}],frontMatter:{slug:"accuracy-of-decimal-computations",authors:["patrickb"],tags:["golang","currency","decimal accuracy"]},nextItem:{title:"Why bundle size is important?",permalink:"/blog/why-bundle-size-is-important"}},l={authorsImageUrls:[void 0]},u=[{value:"Intro",id:"intro",level:2},{value:"Finite accuracy of representation",id:"finite-accuracy-of-representation",level:2},{value:"Money computations",id:"money-computations",level:2},{value:"Solution",id:"solution",level:2},{value:"Conclusio",id:"conclusio",level:2}],s={toc:u},p="wrapper";function m(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,o.Z)({},s,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"intro"},"Intro"),(0,r.kt)("p",null,"Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors."),(0,r.kt)("h2",{id:"finite-accuracy-of-representation"},"Finite accuracy of representation"),(0,r.kt)("p",null,"Floating points are represented like this"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"Floating point representation",src:n(880).Z,width:"810",height:"226"})),(0,r.kt)("p",null,"Not every number can be represented with a finite number of decimal places"),(0,r.kt)("p",null,"0.01 \u2014> 0.0000011001100110011\u2026"),(0,r.kt)("p",null,"Taking 17 places of the above results in 0.010000000000000001"),(0,r.kt)("p",null,"Consider the following code snipet that shows the missing accuracy"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},"func main() {\n\n var n float64 = 0\n\n for i := 0; i < 1000; i++ {\n n += .01\n }\n\n fmt.Println(n)\n\n}\n")),(0,r.kt)("p",null,"Result: 9.999999999999831"),(0,r.kt)("h2",{id:"money-computations"},"Money computations"),(0,r.kt)("p",null,"They can't be done with floating-point as it would inevitably lead to rounding errors."),(0,r.kt)("p",null,"Even the following packages are problematic:"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/shopspring/decimal"},"github.com/shopspring/decimal")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/Rhymond/go-money"},"github.com/Rhymond/go-money")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},"a := decimal.NewFromInt(2)\nb := decimal.NewFromFloat(300.99)\nc := a.Mul(b)\nd := c.Div(decimal.NewFromInt(3))\n")),(0,r.kt)("h2",{id:"solution"},"Solution"),(0,r.kt)("p",null,"Use Int by representing money in cents:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"10.99 -> 1099 (cents)"),(0,r.kt)("li",{parentName:"ul"},"10.9900 -> 109900 (4 digit tax)")),(0,r.kt)("h2",{id:"conclusio"},"Conclusio"),(0,r.kt)("p",null,"Division is a problem!"),(0,r.kt)("p",null,"1/3 - > 0.33333333\u2026\nCorrect way: 0.33, 0.33, 0.34"),(0,r.kt)("p",null,"When doing money calculations one should avoid division as it inevitably leads to loss of accuracy.\nWhen dividing make sure to round to cent and deal with diffs."),(0,r.kt)("p",null,"Division by 10^k is ok till we are inside of the range of the data type."))}m.isMDXComponent=!0},880:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/floating_point_representation-efc73a8c1b722a82b772c2cd7ee7ba99.webp"}}]); \ No newline at end of file diff --git a/assets/js/814f3328.7b160b12.js b/assets/js/814f3328.7b160b12.js deleted file mode 100644 index 20cb355..0000000 --- a/assets/js/814f3328.7b160b12.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[2535],{5641:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"Why bundle size is important?","permalink":"/blog/why-bundle-size-is-important"},{"title":"Prometheus Is Out Of Memory. Again.","permalink":"/blog/prometheus-cardinality-issues"},{"title":"The never ending search a search engine 2022-01 edition","permalink":"/blog/searching-for-search-engines"},{"title":"Impact of 3rd party scripts on performance","permalink":"/blog/impact-of-3rd-party-scripts-on-performance"},{"title":"debugging Go map races in k8s","permalink":"/blog/debugging-go-map-races-in-k8s"}]}')}}]); \ No newline at end of file diff --git a/assets/js/814f3328.f556ba25.js b/assets/js/814f3328.f556ba25.js new file mode 100644 index 0000000..41303ce --- /dev/null +++ b/assets/js/814f3328.f556ba25.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[2535],{5641:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"Accuracy of decimal computations","permalink":"/blog/accuracy-of-decimal-computations"},{"title":"Why bundle size is important?","permalink":"/blog/why-bundle-size-is-important"},{"title":"Prometheus Is Out Of Memory. Again.","permalink":"/blog/prometheus-cardinality-issues"},{"title":"The never ending search a search engine 2022-01 edition","permalink":"/blog/searching-for-search-engines"},{"title":"Impact of 3rd party scripts on performance","permalink":"/blog/impact-of-3rd-party-scripts-on-performance"}]}')}}]); \ No newline at end of file diff --git a/assets/js/87b8e9c4.24bc7ea5.js b/assets/js/87b8e9c4.24bc7ea5.js deleted file mode 100644 index 1412ddf..0000000 --- a/assets/js/87b8e9c4.24bc7ea5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[2423],{3905:(A,e,t)=>{t.d(e,{Zo:()=>g,kt:()=>d});var l=t(7294);function n(A,e,t){return e in A?Object.defineProperty(A,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):A[e]=t,A}function a(A,e){var t=Object.keys(A);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(A);e&&(l=l.filter((function(e){return Object.getOwnPropertyDescriptor(A,e).enumerable}))),t.push.apply(t,l)}return t}function o(A){for(var e=1;e=0||(n[t]=A[t]);return n}(A,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(A);for(l=0;l=0||Object.prototype.propertyIsEnumerable.call(A,t)&&(n[t]=A[t])}return n}var r=l.createContext({}),s=function(A){var e=l.useContext(r),t=e;return A&&(t="function"==typeof A?A(e):o(o({},e),A)),t},g=function(A){var e=s(A.components);return l.createElement(r.Provider,{value:e},A.children)},u="mdxType",p={inlineCode:"code",wrapper:function(A){var e=A.children;return l.createElement(l.Fragment,{},e)}},c=l.forwardRef((function(A,e){var t=A.components,n=A.mdxType,a=A.originalType,r=A.parentName,g=i(A,["components","mdxType","originalType","parentName"]),u=s(t),c=n,d=u["".concat(r,".").concat(c)]||u[c]||p[c]||a;return t?l.createElement(d,o(o({ref:e},g),{},{components:t})):l.createElement(d,o({ref:e},g))}));function d(A,e){var t=arguments,n=e&&e.mdxType;if("string"==typeof A||n){var a=t.length,o=new Array(a);o[0]=c;var i={};for(var r in e)hasOwnProperty.call(e,r)&&(i[r]=e[r]);i.originalType=A,i[u]="string"==typeof A?A:n,o[1]=i;for(var s=2;s{t.r(e),t.d(e,{assets:()=>r,contentTitle:()=>o,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var l=t(7462),n=(t(7294),t(3905));const a={slug:"why-bundle-size-is-important",authors:["nicola"],tags:["javascript","bundle","bundle size"]},o="Why bundle size is important?",i={permalink:"/blog/why-bundle-size-is-important",editUrl:"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-03-17-why-bundle-size-is-important/index.mdx",source:"@site/blog/2022-03-17-why-bundle-size-is-important/index.mdx",title:"Why bundle size is important?",description:"Intro",date:"2022-03-17T00:00:00.000Z",formattedDate:"March 17, 2022",tags:[{label:"javascript",permalink:"/blog/tags/javascript"},{label:"bundle",permalink:"/blog/tags/bundle"},{label:"bundle size",permalink:"/blog/tags/bundle-size"}],hasTruncateMarker:!1,authors:[{name:"Nicola Turcato",title:"Memelord brother",url:"https://github.com/nicolaturcato",imageURL:"https://github.com/nicolaturcato.png",key:"nicola"}],frontMatter:{slug:"why-bundle-size-is-important",authors:["nicola"],tags:["javascript","bundle","bundle size"]},nextItem:{title:"Prometheus Is Out Of Memory. Again.",permalink:"/blog/prometheus-cardinality-issues"}},r={authorsImageUrls:[void 0]},s=[{value:"Intro",id:"intro",level:2},{value:"Nobody likes waiting\u2026",id:"nobody-likes-waiting",level:2},{value:"What is a "bundle"?",id:"what-is-a-bundle",level:2},{value:"Performance implications",id:"performance-implications",level:2},{value:"What is the recommended bundle size?",id:"what-is-the-recommended-bundle-size",level:2},{value:"What do we do then?",id:"what-do-we-do-then",level:2},{value:"How to start decreasing the bundle size?",id:"how-to-start-decreasing-the-bundle-size",level:2},{value:"Breaking up the bundle...",id:"breaking-up-the-bundle",level:2},{value:"Which strategies can we adopt?",id:"which-strategies-can-we-adopt",level:2},{value:"Useful tools to help you reducing bundle size",id:"useful-tools-to-help-you-reducing-bundle-size",level:2},{value:"Conclusion",id:"conclusion",level:2}],g={toc:s},u="wrapper";function p(A){let{components:e,...a}=A;return(0,n.kt)(u,(0,l.Z)({},g,a,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h2",{id:"intro"},"Intro"),(0,n.kt)("p",null,"JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website."),(0,n.kt)("p",null,"Frontend performance optimization is critical because\xa0it accounts for around 80-90% of user response time (10-20% backend).\nSo when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets."),(0,n.kt)("h2",{id:"nobody-likes-waiting"},"Nobody likes waiting\u2026"),(0,n.kt)("p",null,"A\xa0study found\xa0that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site."),(0,n.kt)("p",null,"Sending large JavaScript payloads impacts the speed of your site significantly."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Mazzarri",src:t(7017).Z,width:"410",height:"276"})),(0,n.kt)("h2",{id:"what-is-a-bundle"},'What is a "bundle"?'),(0,n.kt)("p",null,"Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application."),(0,n.kt)("p",null,"JS bundling is\xa0an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Bundle Everywhere",src:t(6865).Z,width:"448",height:"245"})),(0,n.kt)("h2",{id:"performance-implications"},"Performance implications"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Time to transmit over the network"),": considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"JS parse and compile time"),": more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"JS execution time"),": optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Memory consumption"),": everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!")),(0,n.kt)("h2",{id:"what-is-the-recommended-bundle-size"},"What is the recommended bundle size?"),(0,n.kt)("p",null,"AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Mr Chao",src:t(1262).Z,width:"406",height:"250"})),(0,n.kt)("h2",{id:"what-do-we-do-then"},"What do we do then?"),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Meh",src:t(4812).Z,width:"539",height:"399"})),(0,n.kt)("h2",{id:"how-to-start-decreasing-the-bundle-size"},"How to start decreasing the bundle size?"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Measure"),": first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI)\xa0is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Analyze"),": Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Stonks",src:t(3400).Z,width:"309",height:"229"})),(0,n.kt)("h2",{id:"breaking-up-the-bundle"},"Breaking up the bundle..."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Monitor network requests"),": These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Reduce the total dom nodes"),": the less the page needs to render, the less time it takes."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Moving work off the main thread"),": By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Caching"),": Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Breaking Bad",src:t(1278).Z,width:"299",height:"230"})),(0,n.kt)("h2",{id:"which-strategies-can-we-adopt"},"Which strategies can we adopt?"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Minification and Dead Code Elimination"),": These processes are often summed up as\xa0minifying\xa0or\xa0uglifying."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Tree shaking"),": Tree shaking is dead code elimination on a project or library. Always try to use deps which support \u201ctree shaking\u201d, Bundlephobia could be your friend in this case."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Code Splitting and Lazy Loading"),": Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Replace/rewrite large dependencies"),": Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example)."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Feature module import"),": Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Strategy",src:t(2235).Z,width:"307",height:"204"})),(0,n.kt)("h2",{id:"useful-tools-to-help-you-reducing-bundle-size"},"Useful tools to help you reducing bundle size"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Lighthouse"),": automated tool for improving the performance, quality, and correctness of your web apps"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Bundlephobia"),": Bundlephobia\xa0helps you find the performance impact of npm packages"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Webpack Bundle Analyzer"),": analyzes your bundle"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"VS Code"),": Import Cost plugin -> Display import/require package size in the editor")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Tools",src:t(4941).Z,width:"345",height:"255"})),(0,n.kt)("h2",{id:"conclusion"},"Conclusion"),(0,n.kt)("p",null,"Performance cannot be stripped down to a single metric such as bundle size. It would be great!\nUnfortunately there is no single place to measure all of them.I think metrics like the\xa0Core Web Vitals and a general look at bundle size should be considered as a starting point.\nYou will cry... A lot... But don\u2019t give up!"),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"The End",src:t(6899).Z,width:"358",height:"260"})))}p.isMDXComponent=!0},1278:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},6865:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/bundle_everywhere-12122e37ab5ca6bcdd61061c4dc32fd4.webp"},7017:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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FzF4MYb5dPUHhs5cr4W48fbG0YBO8KzHr+LA17KHdZxYMTAAUpcIp1VnAxgo31955bEsLblDFuBy5dlIEDsrWBpK464x+XXAKVkwXRr/6wHYa71OvfyxCA1GDVeOMppgCM+SdSSV+Z4ZOovufzwbrFiK3sBdeld88AOcgwYxb7qpz7mhGS+zB64o5jXBTZSyA0MDXdYQvBoDLJ20qMaLfoJFEqWGz2rC81rxT/bY7gBgPtFqMlpyIMYi4u3Yf1172FNN4/W/xvmZprZO3IbwFq9PQMoJbQXQrwxVYYZwvWGXERPk2Uhlz9gRWmzNaVqkp7mubKLzLAUJ6lcuebTvMqkcxJJymwmZtTUr5Gxvd/HWyOx2AAfyO55mL93wAKh7ARoMajGsPnAMsEfBuYIWIdlP2J4tFsRWmhppa6AQ0cfFbM4a8+RPS2EsWikEK0LhB4GwUWRPGqjgRduFXpKdIIclPO1V8FWUIErCbCAPvTG621JcUfAF9zBHAyEDUplreZZ7sJWMytQpAAkQo1oYHokzkMAkASVnsb09gWQHFj9DRXBQN7QHdbarq61G9+bdIH7RjBlmBo2PkcAwx6UQB2Gs+3fjaO2CxPFOSFo3qLw54OIXVcwaQOoFyZksQpx38MAMv8LX68Pl6brrz7OlB1oNcsJNDiE7+FeHZ/8/I0oZAAAARVhJRlYAAABNTQAqAAAACAABh2kABAAAAAEAAAAaAAAAAAADkoYABwAAABIAAABEoAIABAAAAAEAAAGaoAMABAAAAAEAAAEUAAAAAEFTQ0lJAAAAU2NyZWVuc2hvdFhNUCDAAQAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yNzY8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NDEwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6VXNlckNvbW1lbnQ+U2NyZWVuc2hvdDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cg=="},4812:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/meh-3b42aead7d2246467fd0101518403734.webp"},1262:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},3400:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},2235:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},6899:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},4941:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/tools-91886b41cefeef7cc35b5cd21c43d2ba.webp"}}]); \ No newline at end of file diff --git a/assets/js/87b8e9c4.408c1281.js b/assets/js/87b8e9c4.408c1281.js new file mode 100644 index 0000000..bd4cd5e --- /dev/null +++ b/assets/js/87b8e9c4.408c1281.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[2423],{3905:(A,e,t)=>{t.d(e,{Zo:()=>g,kt:()=>d});var l=t(7294);function n(A,e,t){return e in A?Object.defineProperty(A,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):A[e]=t,A}function a(A,e){var t=Object.keys(A);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(A);e&&(l=l.filter((function(e){return Object.getOwnPropertyDescriptor(A,e).enumerable}))),t.push.apply(t,l)}return t}function o(A){for(var e=1;e=0||(n[t]=A[t]);return n}(A,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(A);for(l=0;l=0||Object.prototype.propertyIsEnumerable.call(A,t)&&(n[t]=A[t])}return n}var r=l.createContext({}),s=function(A){var e=l.useContext(r),t=e;return A&&(t="function"==typeof A?A(e):o(o({},e),A)),t},g=function(A){var e=s(A.components);return l.createElement(r.Provider,{value:e},A.children)},u="mdxType",c={inlineCode:"code",wrapper:function(A){var e=A.children;return l.createElement(l.Fragment,{},e)}},p=l.forwardRef((function(A,e){var t=A.components,n=A.mdxType,a=A.originalType,r=A.parentName,g=i(A,["components","mdxType","originalType","parentName"]),u=s(t),p=n,d=u["".concat(r,".").concat(p)]||u[p]||c[p]||a;return t?l.createElement(d,o(o({ref:e},g),{},{components:t})):l.createElement(d,o({ref:e},g))}));function d(A,e){var t=arguments,n=e&&e.mdxType;if("string"==typeof A||n){var a=t.length,o=new Array(a);o[0]=p;var i={};for(var r in e)hasOwnProperty.call(e,r)&&(i[r]=e[r]);i.originalType=A,i[u]="string"==typeof A?A:n,o[1]=i;for(var s=2;s{t.r(e),t.d(e,{assets:()=>r,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var l=t(7462),n=(t(7294),t(3905));const a={slug:"why-bundle-size-is-important",authors:["nicola"],tags:["javascript","bundle","bundle size"]},o="Why bundle size is important?",i={permalink:"/blog/why-bundle-size-is-important",editUrl:"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-03-17-why-bundle-size-is-important/index.mdx",source:"@site/blog/2022-03-17-why-bundle-size-is-important/index.mdx",title:"Why bundle size is important?",description:"Intro",date:"2022-03-17T00:00:00.000Z",formattedDate:"March 17, 2022",tags:[{label:"javascript",permalink:"/blog/tags/javascript"},{label:"bundle",permalink:"/blog/tags/bundle"},{label:"bundle size",permalink:"/blog/tags/bundle-size"}],hasTruncateMarker:!1,authors:[{name:"Nicola Turcato",title:"Memelord brother",url:"https://github.com/nicolaturcato",imageURL:"https://github.com/nicolaturcato.png",key:"nicola"}],frontMatter:{slug:"why-bundle-size-is-important",authors:["nicola"],tags:["javascript","bundle","bundle size"]},prevItem:{title:"Accuracy of decimal computations",permalink:"/blog/accuracy-of-decimal-computations"},nextItem:{title:"Prometheus Is Out Of Memory. Again.",permalink:"/blog/prometheus-cardinality-issues"}},r={authorsImageUrls:[void 0]},s=[{value:"Intro",id:"intro",level:2},{value:"Nobody likes waiting\u2026",id:"nobody-likes-waiting",level:2},{value:"What is a "bundle"?",id:"what-is-a-bundle",level:2},{value:"Performance implications",id:"performance-implications",level:2},{value:"What is the recommended bundle size?",id:"what-is-the-recommended-bundle-size",level:2},{value:"What do we do then?",id:"what-do-we-do-then",level:2},{value:"How to start decreasing the bundle size?",id:"how-to-start-decreasing-the-bundle-size",level:2},{value:"Breaking up the bundle...",id:"breaking-up-the-bundle",level:2},{value:"Which strategies can we adopt?",id:"which-strategies-can-we-adopt",level:2},{value:"Useful tools to help you reducing bundle size",id:"useful-tools-to-help-you-reducing-bundle-size",level:2},{value:"Conclusion",id:"conclusion",level:2}],g={toc:s},u="wrapper";function c(A){let{components:e,...a}=A;return(0,n.kt)(u,(0,l.Z)({},g,a,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h2",{id:"intro"},"Intro"),(0,n.kt)("p",null,"JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website."),(0,n.kt)("p",null,"Frontend performance optimization is critical because\xa0it accounts for around 80-90% of user response time (10-20% backend).\nSo when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets."),(0,n.kt)("h2",{id:"nobody-likes-waiting"},"Nobody likes waiting\u2026"),(0,n.kt)("p",null,"A\xa0study found\xa0that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site."),(0,n.kt)("p",null,"Sending large JavaScript payloads impacts the speed of your site significantly."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Mazzarri",src:t(7017).Z,width:"410",height:"276"})),(0,n.kt)("h2",{id:"what-is-a-bundle"},'What is a "bundle"?'),(0,n.kt)("p",null,"Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application."),(0,n.kt)("p",null,"JS bundling is\xa0an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Bundle Everywhere",src:t(6865).Z,width:"448",height:"245"})),(0,n.kt)("h2",{id:"performance-implications"},"Performance implications"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Time to transmit over the network"),": considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"JS parse and compile time"),": more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"JS execution time"),": optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Memory consumption"),": everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!")),(0,n.kt)("h2",{id:"what-is-the-recommended-bundle-size"},"What is the recommended bundle size?"),(0,n.kt)("p",null,"AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Mr Chao",src:t(1262).Z,width:"406",height:"250"})),(0,n.kt)("h2",{id:"what-do-we-do-then"},"What do we do then?"),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Meh",src:t(4812).Z,width:"539",height:"399"})),(0,n.kt)("h2",{id:"how-to-start-decreasing-the-bundle-size"},"How to start decreasing the bundle size?"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Measure"),": first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI)\xa0is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Analyze"),": Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Stonks",src:t(3400).Z,width:"309",height:"229"})),(0,n.kt)("h2",{id:"breaking-up-the-bundle"},"Breaking up the bundle..."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Monitor network requests"),": These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Reduce the total dom nodes"),": the less the page needs to render, the less time it takes."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Moving work off the main thread"),": By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Caching"),": Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Breaking Bad",src:t(1278).Z,width:"299",height:"230"})),(0,n.kt)("h2",{id:"which-strategies-can-we-adopt"},"Which strategies can we adopt?"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Minification and Dead Code Elimination"),": These processes are often summed up as\xa0minifying\xa0or\xa0uglifying."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Tree shaking"),": Tree shaking is dead code elimination on a project or library. Always try to use deps which support \u201ctree shaking\u201d, Bundlephobia could be your friend in this case."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Code Splitting and Lazy Loading"),": Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Replace/rewrite large dependencies"),": Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example)."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Feature module import"),": Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Strategy",src:t(2235).Z,width:"307",height:"204"})),(0,n.kt)("h2",{id:"useful-tools-to-help-you-reducing-bundle-size"},"Useful tools to help you reducing bundle size"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Lighthouse"),": automated tool for improving the performance, quality, and correctness of your web apps"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Bundlephobia"),": Bundlephobia\xa0helps you find the performance impact of npm packages"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Webpack Bundle Analyzer"),": analyzes your bundle"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"VS Code"),": Import Cost plugin -> Display import/require package size in the editor")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Tools",src:t(4941).Z,width:"345",height:"255"})),(0,n.kt)("h2",{id:"conclusion"},"Conclusion"),(0,n.kt)("p",null,"Performance cannot be stripped down to a single metric such as bundle size. It would be great!\nUnfortunately there is no single place to measure all of them.I think metrics like the\xa0Core Web Vitals and a general look at bundle size should be considered as a starting point.\nYou will cry... A lot... But don\u2019t give up!"),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"The End",src:t(6899).Z,width:"358",height:"260"})))}c.isMDXComponent=!0},1278:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},6865:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/bundle_everywhere-12122e37ab5ca6bcdd61061c4dc32fd4.webp"},7017:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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FzF4MYb5dPUHhs5cr4W48fbG0YBO8KzHr+LA17KHdZxYMTAAUpcIp1VnAxgo31955bEsLblDFuBy5dlIEDsrWBpK464x+XXAKVkwXRr/6wHYa71OvfyxCA1GDVeOMppgCM+SdSSV+Z4ZOovufzwbrFiK3sBdeld88AOcgwYxb7qpz7mhGS+zB64o5jXBTZSyA0MDXdYQvBoDLJ20qMaLfoJFEqWGz2rC81rxT/bY7gBgPtFqMlpyIMYi4u3Yf1172FNN4/W/xvmZprZO3IbwFq9PQMoJbQXQrwxVYYZwvWGXERPk2Uhlz9gRWmzNaVqkp7mubKLzLAUJ6lcuebTvMqkcxJJymwmZtTUr5Gxvd/HWyOx2AAfyO55mL93wAKh7ARoMajGsPnAMsEfBuYIWIdlP2J4tFsRWmhppa6AQ0cfFbM4a8+RPS2EsWikEK0LhB4GwUWRPGqjgRduFXpKdIIclPO1V8FWUIErCbCAPvTG621JcUfAF9zBHAyEDUplreZZ7sJWMytQpAAkQo1oYHokzkMAkASVnsb09gWQHFj9DRXBQN7QHdbarq61G9+bdIH7RjBlmBo2PkcAwx6UQB2Gs+3fjaO2CxPFOSFo3qLw54OIXVcwaQOoFyZksQpx38MAMv8LX68Pl6brrz7OlB1oNcsJNDiE7+FeHZ/8/I0oZAAAARVhJRlYAAABNTQAqAAAACAABh2kABAAAAAEAAAAaAAAAAAADkoYABwAAABIAAABEoAIABAAAAAEAAAGaoAMABAAAAAEAAAEUAAAAAEFTQ0lJAAAAU2NyZWVuc2hvdFhNUCDAAQAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yNzY8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NDEwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6VXNlckNvbW1lbnQ+U2NyZWVuc2hvdDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cg=="},4812:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/meh-3b42aead7d2246467fd0101518403734.webp"},1262:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},3400:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},2235:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},6899:(A,e,t)=>{t.d(e,{Z:()=>l});const l="data:image/webp;base64,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"},4941:(A,e,t)=>{t.d(e,{Z:()=>l});const l=t.p+"assets/images/tools-91886b41cefeef7cc35b5cd21c43d2ba.webp"}}]); \ No newline at end of file diff --git a/assets/js/90c7e6e2.80970463.js b/assets/js/90c7e6e2.80970463.js new file mode 100644 index 0000000..d120b95 --- /dev/null +++ b/assets/js/90c7e6e2.80970463.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[1284],{9473:o=>{o.exports=JSON.parse('{"permalink":"/blog/tags/decimal-accuracy","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/a20900f1.d8e2e996.js b/assets/js/a20900f1.d8e2e996.js new file mode 100644 index 0000000..aa80d0c --- /dev/null +++ b/assets/js/a20900f1.d8e2e996.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[6618],{2067:e=>{e.exports=JSON.parse('{"label":"currency","permalink":"/blog/tags/currency","allTagsPath":"/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/assets/js/a7023ddc.9e2b53c7.js b/assets/js/a7023ddc.9e2b53c7.js new file mode 100644 index 0000000..c7e3e3b --- /dev/null +++ b/assets/js/a7023ddc.9e2b53c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[1713],{3457:l=>{l.exports=JSON.parse('[{"label":"golang","permalink":"/blog/tags/golang","count":1},{"label":"currency","permalink":"/blog/tags/currency","count":1},{"label":"decimal accuracy","permalink":"/blog/tags/decimal-accuracy","count":1},{"label":"javascript","permalink":"/blog/tags/javascript","count":1},{"label":"bundle","permalink":"/blog/tags/bundle","count":1},{"label":"bundle size","permalink":"/blog/tags/bundle-size","count":1},{"label":"prometheus","permalink":"/blog/tags/prometheus","count":1},{"label":"cardinality","permalink":"/blog/tags/cardinality","count":1},{"label":"devops","permalink":"/blog/tags/devops","count":1},{"label":"ops","permalink":"/blog/tags/ops","count":1},{"label":"k8s","permalink":"/blog/tags/k-8-s","count":1},{"label":"oom","permalink":"/blog/tags/oom","count":1},{"label":"memory","permalink":"/blog/tags/memory","count":1},{"label":"search","permalink":"/blog/tags/search","count":1},{"label":"search-engine","permalink":"/blog/tags/search-engine","count":1},{"label":"backend","permalink":"/blog/tags/backend","count":2},{"label":"go","permalink":"/blog/tags/go","count":2},{"label":"frontend","permalink":"/blog/tags/frontend","count":1},{"label":"performance","permalink":"/blog/tags/performance","count":1},{"label":"debugging","permalink":"/blog/tags/debugging","count":1},{"label":"foomo","permalink":"/blog/tags/foomo","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/a7023ddc.a066be17.js b/assets/js/a7023ddc.a066be17.js deleted file mode 100644 index 0ef2154..0000000 --- a/assets/js/a7023ddc.a066be17.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[1713],{3457:l=>{l.exports=JSON.parse('[{"label":"javascript","permalink":"/blog/tags/javascript","count":1},{"label":"bundle","permalink":"/blog/tags/bundle","count":1},{"label":"bundle size","permalink":"/blog/tags/bundle-size","count":1},{"label":"prometheus","permalink":"/blog/tags/prometheus","count":1},{"label":"cardinality","permalink":"/blog/tags/cardinality","count":1},{"label":"devops","permalink":"/blog/tags/devops","count":1},{"label":"ops","permalink":"/blog/tags/ops","count":1},{"label":"k8s","permalink":"/blog/tags/k-8-s","count":1},{"label":"oom","permalink":"/blog/tags/oom","count":1},{"label":"memory","permalink":"/blog/tags/memory","count":1},{"label":"search","permalink":"/blog/tags/search","count":1},{"label":"search-engine","permalink":"/blog/tags/search-engine","count":1},{"label":"backend","permalink":"/blog/tags/backend","count":2},{"label":"go","permalink":"/blog/tags/go","count":2},{"label":"frontend","permalink":"/blog/tags/frontend","count":1},{"label":"performance","permalink":"/blog/tags/performance","count":1},{"label":"debugging","permalink":"/blog/tags/debugging","count":1},{"label":"foomo","permalink":"/blog/tags/foomo","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/b2b675dd.6a893e1a.js b/assets/js/b2b675dd.14f7daa6.js similarity index 73% rename from assets/js/b2b675dd.6a893e1a.js rename to assets/js/b2b675dd.14f7daa6.js index fc22bb0..57eff17 100644 --- a/assets/js/b2b675dd.6a893e1a.js +++ b/assets/js/b2b675dd.14f7daa6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[533],{8017:o=>{o.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":6,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[533],{8017:o=>{o.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":7,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/b2f554cd.a67ccd00.js b/assets/js/b2f554cd.a67ccd00.js deleted file mode 100644 index f19b030..0000000 --- a/assets/js/b2f554cd.a67ccd00.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[1477],{10:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"why-bundle-size-is-important","metadata":{"permalink":"/blog/why-bundle-size-is-important","editUrl":"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-03-17-why-bundle-size-is-important/index.mdx","source":"@site/blog/2022-03-17-why-bundle-size-is-important/index.mdx","title":"Why bundle size is important?","description":"Intro","date":"2022-03-17T00:00:00.000Z","formattedDate":"March 17, 2022","tags":[{"label":"javascript","permalink":"/blog/tags/javascript"},{"label":"bundle","permalink":"/blog/tags/bundle"},{"label":"bundle size","permalink":"/blog/tags/bundle-size"}],"hasTruncateMarker":false,"authors":[{"name":"Nicola Turcato","title":"Memelord brother","url":"https://github.com/nicolaturcato","imageURL":"https://github.com/nicolaturcato.png","key":"nicola"}],"frontMatter":{"slug":"why-bundle-size-is-important","authors":["nicola"],"tags":["javascript","bundle","bundle size"]},"nextItem":{"title":"Prometheus Is Out Of Memory. Again.","permalink":"/blog/prometheus-cardinality-issues"}},"content":"## Intro\\n\\nJavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.\\n\\nFrontend performance optimization is critical because\xa0it accounts for around 80-90% of user response time (10-20% backend).\\nSo when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets.\\n\\n## Nobody likes waiting\u2026\\n\\nA\xa0study found\xa0that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site.\\n\\nSending large JavaScript payloads impacts the speed of your site significantly.\\n\\n![Mazzarri](mazzarri.webp)\\n\\n## What is a \\"bundle\\"?\\n\\nYour frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application.\\n\\nJS bundling is\xa0an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests.\\n\\n![Bundle Everywhere](bundle_everywhere.webp)\\n\\n## Performance implications\\n\\n- **Time to transmit over the network**: considering slow connections with some mobile devices, it\'s possible that your page will not be interactive until it loads.-> More bytes = longer download times\\n- **JS parse and compile time**: more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can\'t respond to user input\\n- **JS execution time**: optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It\'s possible that your page won\'t be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it\'s really needed, that also delays your Time to Interactive\\n- **Memory consumption**: everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!\\n\\n## What is the recommended bundle size?\\n\\nAS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly.\\n\\n![Mr Chao](mr_chao.webp)\\n\\n## What do we do then?\\n\\n![Meh](meh.webp)\\n\\n## How to start decreasing the bundle size?\\n\\n- **Measure**: first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI)\xa0is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app.\\n- **Analyze**: Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.\\n\\n![Stonks](stonks.webp)\\n\\n## Breaking up the bundle...\\n\\n- **Monitor network requests**: These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount.\\n- **Reduce the total dom nodes**: the less the page needs to render, the less time it takes.\\n- **Moving work off the main thread**: By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page\\n- **Caching**: Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast\\n\\n![Breaking Bad](breaking_bad.webp)\\n\\n## Which strategies can we adopt?\\n\\n- **Minification and Dead Code Elimination**: These processes are often summed up as\xa0minifying\xa0or\xa0uglifying.\\n- **Tree shaking**: Tree shaking is dead code elimination on a project or library. Always try to use deps which support \u201ctree shaking\u201d, Bundlephobia could be your friend in this case.\\n- **Code Splitting and Lazy Loading**: Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on.\\n- **Replace/rewrite large dependencies**: Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example).\\n- **Feature module import**: Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).\\n\\n![Strategy](strategy.webp)\\n\\n## Useful tools to help you reducing bundle size\\n\\n- **Lighthouse**: automated tool for improving the performance, quality, and correctness of your web apps\\n- **Bundlephobia**: Bundlephobia\xa0helps you find the performance impact of npm packages\\n- **Webpack Bundle Analyzer**: analyzes your bundle\\n- **VS Code**: Import Cost plugin -> Display import/require package size in the editor\\n\\n![Tools](tools.webp)\\n\\n## Conclusion\\n\\nPerformance cannot be stripped down to a single metric such as bundle size. It would be great!\\nUnfortunately there is no single place to measure all of them.I think metrics like the\xa0Core Web Vitals and a general look at bundle size should be considered as a starting point.\\nYou will cry... A lot... But don\u2019t give up!\\n\\n![The End](the_end.webp)"},{"id":"prometheus-cardinality-issues","metadata":{"permalink":"/blog/prometheus-cardinality-issues","editUrl":"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-01-25-prometheus-cardinality-issues/index.mdx","source":"@site/blog/2022-01-25-prometheus-cardinality-issues/index.mdx","title":"Prometheus Is Out Of Memory. Again.","description":"The Annoyance","date":"2022-01-25T00:00:00.000Z","formattedDate":"January 25, 2022","tags":[{"label":"prometheus","permalink":"/blog/tags/prometheus"},{"label":"cardinality","permalink":"/blog/tags/cardinality"},{"label":"devops","permalink":"/blog/tags/devops"},{"label":"ops","permalink":"/blog/tags/ops"},{"label":"k8s","permalink":"/blog/tags/k-8-s"},{"label":"oom","permalink":"/blog/tags/oom"},{"label":"memory","permalink":"/blog/tags/memory"}],"hasTruncateMarker":false,"authors":[{"name":"Stefan Martinov","title":"Memelord","url":"https://github.com/smartinov","imageURL":"https://github.com/smartinov.png","key":"smartinov"}],"frontMatter":{"slug":"prometheus-cardinality-issues","authors":["smartinov"],"tags":["prometheus","cardinality","devops","ops","k8s","oom","memory"]},"prevItem":{"title":"Why bundle size is important?","permalink":"/blog/why-bundle-size-is-important"},"nextItem":{"title":"The never ending search a search engine 2022-01 edition","permalink":"/blog/searching-for-search-engines"}},"content":"## The Annoyance\\n\\nSo, we\'ve all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM!\\nPrometheus returns us a 503, a trusty way of saying I\'m not ready, and I\'m probably going to die soon.\\nAnd since we\'re running in kubernetes I\'m going to die soon, again and again.\\nAnd you\'re getting reports from your colleagues that prometheus is not responding.\\nAnd you can\'t ignore them anymore.\\n\\n![Bummer.](bummer.webp)\\n\\n\\n## The Problem\\n\\nAll right, lets check what\'s happening to the little guy.\\n\\n```bash\\nkubectl get pods -n monitoring\\n\\nprometheus-prometheus-kube-prometheus-prometheus-0 1/2 Running 4 5m\\n```\\n\\nIt seems like it\'s stuck in the running state, where the container is not yet ready.\\nLet\'s describe the deployment, to check out what\'s happening.\\n\\n```yaml\\n State: Running \u2502\\n Started: Wed, 12 Jan 2022 15:12:49 +0100 \u2502\\n Last State: Terminated \u2502\\n Reason: OOMKilled \u2502\\n Exit Code: 137 \u2502\\n Started: Tue, 11 Jan 2022 17:14:41 +0100 \u2502\\n Finished: Wed, 12 Jan 2022 15:12:47 +0100 \u2502\\n```\\n\\nSo we see that the prometheus is in a running state waiting for the readiness probe to trigger, probably working on recovering from Write Ahead Log (WAL).\\nThis could be an issue where prometheus is recovering from an error, or a restart and does not have enough memory to write everything in the WAL.\\nWe could be running into an issue where we set the request/limits memory lower than the prometheus requires, and the kube scheduler keeps killing prometheus for wanting more memory.\\n\\nFor this case, we could give it more memory to work to see if it recovers. We should also analyze why the prometheus WAL is getting clogged up.\\n\\nIn essence, we want to check what has changed so that we suddenly have a high memory spike in our sweet, sweet environment.\\n\\n## The Source\\n\\n![Cardinality](cardinality.webp)\\n\\nA lot of prometheus issues revolve around cardinality.\\nMemory spikes that break your deployment? Cardinality.\\nPrometheus dragging its feet like it\'s Monday after the log4j (the second one ofc) zero day security breach? Cardinality.\\nNot getting that raise since you worked hard the past 16 years without wavering? You bet your ass it\'s cardinality.\\nSo, as you can see much of life\'s problems can be accredited to cardinality.\\n\\nIn short cardinality of your metrics is the combination of all label values per metric.\\nFor example, if our metric ```http_request_total``` had a label response code, and let\'s say we support 8 status codes, our cardinality starts off at 8.\\nFor good measure we want to record the HTTP verb for the request. We support ``GET POST PUT HEAD`` which would put the cardinality to 4\\\\*8=**32**.\\nNow, if someone adds a URL to the metric label (**!!VERY BAD IDEA!!**, but bare with me now) and we have 2 active pages, we\'d have a cardinality of 2\\\\*4\\\\*8=**64**.\\nBut, imagine someone starts scraping your website for potential vulnerabilities. Imagine all the URLs that will appear, most likely only once.\\n\\n```text\\nmywebsite.com/admin.php\\nmywebsite.com/wp/admin.php\\nmywebsite.com/?utm_source=GUID\\n...\\n```\\n\\nThis would blow up our cardinality to kingdom come. Like you will be out of memory faster than \\"[a new super awesome Javascript gamechanger framework](https://www.reddit.com/r/ProgrammerHumor/comments/a483yz/those_javascript_devs/)\\" is born.\\nOr to quote user [naveen17797](https://www.reddit.com/user/naveen17797/) _Scientists predict the number of js frameworks may exceed human population by 2020,at that point of time random string generators will be used to name those frameworks._\\n\\nThe point to this story is, be very mindful of how you use labels and cardinality in prometheus, since that will indeed have great impact on your prometheus performance.\\n\\n## The Solution\\n\\nSince this has never happened to me (never-ever) I found the following solution to be handy.\\nSince we can\'t get prometheus up and running to utilize PromQL to detect the potential issues, we have to find another way to detect high cardinality.\\nTherefore, we might want to get our hands dirty with some ```kubectl exec -it -n monitoring pods/prometheus-prometheus-kube-prometheus-prometheus-0 -- sh```, and run the prometheus ``tsdb`` analysis too.\\n```bash\\n/prometheus $ promtool tsdb analyze .\\n```\\n\\nWhich produced the result.\\n\\n```text\\n> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG\\n> Duration: 1h59m59.997s\\n> Series: 564171\\n> Label names: 285\\n> Postings (unique label pairs): 21139\\n> Postings entries (total label pairs): 6423664\\n>\\n> ...\\n>\\n> Highest cardinality metric names:\\n> 11340 haproxy_server_http_responses_total\\n> ...\\n```\\n\\nWe see the potential issue here, where the ``haproxy_server_http_responses_total`` metric is having a super-high cardinality which is growing.\\nWe need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.\\n\\n... or burn it, up to you.\\n\\n![Flame Thrower](flame-thrower.webp)\\n\\n## The Further Reading\\n\\n1. [WAL Definition](https://github.com/prometheus/prometheus/blob/main/tsdb/docs/format/wal.md)\\n2. [WAL & Checkpoints](https://ganeshvernekar.com/blog/prometheus-tsdb-wal-and-checkpoint/)\\n3. [Using TSDB](https://www.robustperception.io/using-tsdb-analyze-to-investigate-churn-and-cardinality)\\n4. [Biggest Metrics](https://www.robustperception.io/which-are-my-biggest-metrics)\\n5. [Cardinality](https://www.robustperception.io/cardinality-is-key)"},{"id":"searching-for-search-engines","metadata":{"permalink":"/blog/searching-for-search-engines","editUrl":"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-01-20-searching-for-search-engines.mdx","source":"@site/blog/2022-01-20-searching-for-search-engines.mdx","title":"The never ending search a search engine 2022-01 edition","description":"While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.","date":"2022-01-20T00:00:00.000Z","formattedDate":"January 20, 2022","tags":[{"label":"search","permalink":"/blog/tags/search"},{"label":"search-engine","permalink":"/blog/tags/search-engine"},{"label":"backend","permalink":"/blog/tags/backend"},{"label":"go","permalink":"/blog/tags/go"}],"hasTruncateMarker":false,"authors":[{"name":"Jan Halfar","title":"foomo maintainer","url":"https://github.com/janhalfar","imageURL":"https://github.com/janhalfar.png","key":"jan"}],"frontMatter":{"slug":"searching-for-search-engines","authors":["jan"],"tags":["search","search-engine","backend","go"]},"prevItem":{"title":"Prometheus Is Out Of Memory. Again.","permalink":"/blog/prometheus-cardinality-issues"},"nextItem":{"title":"Impact of 3rd party scripts on performance","permalink":"/blog/impact-of-3rd-party-scripts-on-performance"}},"content":"While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.\\n\\nSince I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.\\n\\n## Algolia\\n\\nI was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)\\n\\nTo see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men \\n\\nApart from that the UI/UX of their backend tools is fantastic.\\n\\n## Elastic\\n\\nWhen it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.\\n\\n\\n## typesense.org\\n\\nI do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: ___\\"The Open Source Algolia Alternative\\" / \\"The Easier To Use ElasticSearch Alternative\\"___ \\n\\nWhen looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.\\n\\n## MeiliSearch\\n\\nThis Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.\\n\\n## Go eco system\\n\\nObviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature. \\n\\n\\n### bleve / bluge\\n\\n[Marty Schoch](https://github.com/mschoch) seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.\\n\\nhttps://github.com/blevesearch/bleve\\nhttps://github.com/blugelabs/bluge // next iteration of bleve\\n\\n#### projects using bluge\\n\\nAll bleeding edge afaik atm - but definitely good places to look at bluge usage\\n\\nhttps://github.com/prabhatsharma/zinc \\nhttps://github.com/mosuka/phalanx\\n\\n### Look ma I made a vector database\\n\\nGotta take a look at this one - will report later\\n\\nhttps://github.com/semi-technologies/weaviate"},{"id":"impact-of-3rd-party-scripts-on-performance","metadata":{"permalink":"/blog/impact-of-3rd-party-scripts-on-performance","editUrl":"https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-01-20-exploring-partytown/index.mdx","source":"@site/blog/2022-01-20-exploring-partytown/index.mdx","title":"Impact of 3rd party scripts on performance","description":"Issue with performance","date":"2022-01-20T00:00:00.000Z","formattedDate":"January 20, 2022","tags":[{"label":"frontend","permalink":"/blog/tags/frontend"},{"label":"performance","permalink":"/blog/tags/performance"}],"hasTruncateMarker":false,"authors":[{"name":"Marko Trebi\u017ean","title":"Frontend Dev","url":"https://github.com/themre","imageURL":"https://github.com/themre.png","key":"marko"}],"frontMatter":{"slug":"impact-of-3rd-party-scripts-on-performance","authors":["marko"],"tags":["frontend","performance"]},"prevItem":{"title":"The never ending search a search engine 2022-01 edition","permalink":"/blog/searching-for-search-engines"},"nextItem":{"title":"debugging Go map races in k8s","permalink":"/blog/debugging-go-map-races-in-k8s"}},"content":"## Issue with performance\\n\\nWhen building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).\\n\\nThis does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?\\n\\n## Partytown to the rescue\\n\\nDevelopers at BuilderIO created an library [Partytown](https://github.com/BuilderIO/partytown) that would allow relocating resources from 3rd party scripts off the main thread.\\nWe won\'t dive into specifics how it works, because they explain it nicely on their GitHub page.\\n\\nIn our stack we use [Next.js](https://nextjs.org/) React framework and we will go through the basic steps that will allow us to include Partytown for Google Tag Manager.\\n\\n### Setup\\n\\nPartytown script needs to be located inside our application and live on the same domain. Since we\'re using monorepo structure, we need to copy this script across all our frontend application. For that we used CopyPlugin webpack plugin in our Next.js config file:\\n\\n```javascript\\nconfig.plugins.push(\\n ...\\n new CopyPlugin({\\n patterns: [\\n {\\n // we copy script from node_modules partytown package to `~partytown` folder in our package that serves static files\\n from: path.join(path.dirname(require.resolve(\'@builder.io/partytown\')), \'lib\'),\\n // paths for SSR and client side rendering differ\\n to: path.join(`${isServer ? \'..\' : \'.\'}/static/assets/`, \'~partytown\'),\\n },\\n ],\\n })\\n );\\n```\\n\\nPartytown\'s requirement is that it needs to know what script should it load into own web worker. For that we set script type to `text/partytown`. This will prevent script to load on initial load.\\n\\nInside `_document.tsx` we add this:\\n```javascript\\n\\n ...\\n // include Partytown and set custom path due to multiple frontends\\n \\n // tag 3rd party script with partytown type\\n

Awesome list of software

A list of commercial and open source software we use, because it is awesome.


desktop software

devtools

IDEs

creative tools

cli utilities

k8s / docker

backup

software as a service

productivity / collaboration

CMS

- - + + \ No newline at end of file diff --git a/blog.html b/blog.html index b4e4b55..f8c2621 100644 --- a/blog.html +++ b/blog.html @@ -9,12 +9,14 @@ - - + +
-

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). +

Intro

Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors.

Finite accuracy of representation

Floating points are represented like this

Floating point representation

Not every number can be represented with a finite number of decimal places

0.01 —> 0.0000011001100110011…

Taking 17 places of the above results in 0.010000000000000001

Consider the following code snipet that shows the missing accuracy

func main() {

var n float64 = 0

for i := 0; i < 1000; i++ {
n += .01
}

fmt.Println(n)

}

Result: 9.999999999999831

Money computations

They can't be done with floating-point as it would inevitably lead to rounding errors.

Even the following packages are problematic:

github.com/shopspring/decimal

github.com/Rhymond/go-money

a := decimal.NewFromInt(2)
b := decimal.NewFromFloat(300.99)
c := a.Mul(b)
d := c.Div(decimal.NewFromInt(3))

Solution

Use Int by representing money in cents:

  • 10.99 -> 1099 (cents)
  • 10.9900 -> 109900 (4 digit tax)

Conclusio

Division is a problem!

1/3 - > 0.33333333… +Correct way: 0.33, 0.33, 0.34

When doing money calculations one should avoid division as it inevitably leads to loss of accuracy. +When dividing make sure to round to cent and deal with diffs.

Division by 10^k is ok till we are inside of the range of the data type.

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). So when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets.

Nobody likes waiting…

A study found that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site.

Sending large JavaScript payloads impacts the speed of your site significantly.

Mazzarri

What is a "bundle"?

Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application.

JS bundling is an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests.

Bundle Everywhere

Performance implications

  • Time to transmit over the network: considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times
  • JS parse and compile time: more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input
  • JS execution time: optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive
  • Memory consumption: everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!

AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly.

Mr Chao

What do we do then?

Meh

How to start decreasing the bundle size?

  • Measure: first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI) is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app.
  • Analyze: Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.

Stonks

Breaking up the bundle...

  • Monitor network requests: These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount.
  • Reduce the total dom nodes: the less the page needs to render, the less time it takes.
  • Moving work off the main thread: By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page
  • Caching: Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast

Breaking Bad

Which strategies can we adopt?

  • Minification and Dead Code Elimination: These processes are often summed up as minifying or uglifying.
  • Tree shaking: Tree shaking is dead code elimination on a project or library. Always try to use deps which support “tree shaking”, Bundlephobia could be your friend in this case.
  • Code Splitting and Lazy Loading: Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on.
  • Replace/rewrite large dependencies: Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example).
  • Feature module import: Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).

Strategy

Useful tools to help you reducing bundle size

  • Lighthouse: automated tool for improving the performance, quality, and correctness of your web apps
  • Bundlephobia: Bundlephobia helps you find the performance impact of npm packages
  • Webpack Bundle Analyzer: analyzes your bundle
  • VS Code: Import Cost plugin -> Display import/require package size in the editor

Tools

Conclusion

Performance cannot be stripped down to a single metric such as bundle size. It would be great! Unfortunately there is no single place to measure all of them.I think metrics like the Core Web Vitals and a general look at bundle size should be considered as a starting point. You will cry... A lot... But don’t give up!

The End

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! @@ -40,7 +42,7 @@ We need to deal with it, so that our prometheus instance can breathe again. In t https://github.com/blugelabs/bluge // next iteration of bleve

projects using bluge

All bleeding edge afaik atm - but definitely good places to look at bluge usage

https://github.com/prabhatsharma/zinc https://github.com/mosuka/phalanx

Look ma I made a vector database

Gotta take a look at this one - will report later

https://github.com/semi-technologies/weaviate

Marko Trebižan

Issue with performance

When building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).

This does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?

Partytown to the rescue

Developers at BuilderIO created an library Partytown that would allow relocating resources from 3rd party scripts off the main thread. We won't dive into specifics how it works, because they explain it nicely on their GitHub page.

In our stack we use Next.js React framework and we will go through the basic steps that will allow us to include Partytown for Google Tag Manager.

Setup

Partytown script needs to be located inside our application and live on the same domain. Since we're using monorepo structure, we need to copy this script across all our frontend application. For that we used CopyPlugin webpack plugin in our Next.js config file:

config.plugins.push(
...
new CopyPlugin({
patterns: [
{
// we copy script from node_modules partytown package to `~partytown` folder in our package that serves static files
from: path.join(path.dirname(require.resolve('@builder.io/partytown')), 'lib'),
// paths for SSR and client side rendering differ
to: path.join(`${isServer ? '..' : '.'}/static/assets/`, '~partytown'),
},
],
})
);

Partytown's requirement is that it needs to know what script should it load into own web worker. For that we set script type to text/partytown. This will prevent script to load on initial load.

Inside _document.tsx we add this:

<Head>
...
// include Partytown and set custom path due to multiple frontends
<Partytown lib={`${addTrailingSlash(this.props.basePath)}_next/static/assets/~partytown/`} debug={false} />
// tag 3rd party script with partytown type
<script type="text/partytown" src={`https://www.googletagmanager.com/gtm.js?id=${id}`} />
...
</Head>

Results

So now, does it work? We used one of our large Ecommerce sites to test the landing Lighthouse score.

This was before adding Partytown:

Lighthouse before Partytown

Here you can see 2 critical things: almost 1s of total blocking time (TBT) and 9s of time to interactive (TTI).

After we added Partytown, we got this:

Lighthouse after Partytown

Time to interactive went from 9s to 6.1s which is almost 33% improvement and total blocking time was reduce by more than 50%! We were more than impressed how easy it was to improve our performances.

Side note: Both screenshots were compressed using Squoosh App.

Next steps

After successful testing of Partytown for Google Tag Manager script, we are more than interested in trying it out on our other scripts. One important topic will be to test Partytown with other service-worker related libraries and how to use them together.

Jan Halfar

A few years ago we abandoned the previous version of https://www.foomo.org as we did not want to maintain the old wordpress installation and the project was only living in README.md in the repos living under https://www.github.com/foomo .

As things have grown over time we have decided to re-launch a website / cross project documentation.

So welcome back and enjoy the view to the past:

blast from the past

- - + + \ No newline at end of file diff --git a/blog/accuracy-of-decimal-computations.html b/blog/accuracy-of-decimal-computations.html new file mode 100644 index 0000000..4bf894f --- /dev/null +++ b/blog/accuracy-of-decimal-computations.html @@ -0,0 +1,23 @@ + + + + + +Accuracy of decimal computations | foomo project docs + + + + + + + + + +
+

Accuracy of decimal computations

Intro

Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors.

Finite accuracy of representation

Floating points are represented like this

Floating point representation

Not every number can be represented with a finite number of decimal places

0.01 —> 0.0000011001100110011…

Taking 17 places of the above results in 0.010000000000000001

Consider the following code snipet that shows the missing accuracy

func main() {

var n float64 = 0

for i := 0; i < 1000; i++ {
n += .01
}

fmt.Println(n)

}

Result: 9.999999999999831

Money computations

They can't be done with floating-point as it would inevitably lead to rounding errors.

Even the following packages are problematic:

github.com/shopspring/decimal

github.com/Rhymond/go-money

a := decimal.NewFromInt(2)
b := decimal.NewFromFloat(300.99)
c := a.Mul(b)
d := c.Div(decimal.NewFromInt(3))

Solution

Use Int by representing money in cents:

  • 10.99 -> 1099 (cents)
  • 10.9900 -> 109900 (4 digit tax)

Conclusio

Division is a problem!

1/3 - > 0.33333333… +Correct way: 0.33, 0.33, 0.34

When doing money calculations one should avoid division as it inevitably leads to loss of accuracy. +When dividing make sure to round to cent and deal with diffs.

Division by 10^k is ok till we are inside of the range of the data type.

+ + + + \ No newline at end of file diff --git a/blog/archive.html b/blog/archive.html index 315f19a..dd7ee8b 100644 --- a/blog/archive.html +++ b/blog/archive.html @@ -9,13 +9,13 @@ - - + + - - +
+ + \ No newline at end of file diff --git a/blog/atom.xml b/blog/atom.xml index 4c4cfb4..681fa2c 100644 --- a/blog/atom.xml +++ b/blog/atom.xml @@ -2,11 +2,28 @@ https://www.foomo.org/blog foomo project docs Blog - 2022-03-17T00:00:00.000Z + 2023-03-06T00:00:00.000Z https://github.com/jpmonette/feed foomo project docs Blog https://www.foomo.org/img/favicon.ico + + <![CDATA[Accuracy of decimal computations]]> + https://www.foomo.org/blog/accuracy-of-decimal-computations + + 2023-03-06T00:00:00.000Z + + Intro

Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors.

Finite accuracy of representation

Floating points are represented like this

Floating point representation

Not every number can be represented with a finite number of decimal places

0.01 —> 0.0000011001100110011…

Taking 17 places of the above results in 0.010000000000000001

Consider the following code snipet that shows the missing accuracy

func main() {

var n float64 = 0

for i := 0; i < 1000; i++ {
n += .01
}

fmt.Println(n)

}

Result: 9.999999999999831

Money computations

They can't be done with floating-point as it would inevitably lead to rounding errors.

Even the following packages are problematic:

github.com/shopspring/decimal

github.com/Rhymond/go-money

a := decimal.NewFromInt(2)
b := decimal.NewFromFloat(300.99)
c := a.Mul(b)
d := c.Div(decimal.NewFromInt(3))

Solution

Use Int by representing money in cents:

  • 10.99 -> 1099 (cents)
  • 10.9900 -> 109900 (4 digit tax)

Conclusio

Division is a problem!

1/3 - > 0.33333333… +Correct way: 0.33, 0.33, 0.34

When doing money calculations one should avoid division as it inevitably leads to loss of accuracy. +When dividing make sure to round to cent and deal with diffs.

Division by 10^k is ok till we are inside of the range of the data type.

]]>
+ + Patrick Buchner + https://github.com/smartinov + + + + +
<![CDATA[Why bundle size is important?]]> https://www.foomo.org/blog/why-bundle-size-is-important diff --git a/blog/debugging-go-map-races-in-k8s.html b/blog/debugging-go-map-races-in-k8s.html index ce6ba0f..5d2c5bc 100644 --- a/blog/debugging-go-map-races-in-k8s.html +++ b/blog/debugging-go-map-races-in-k8s.html @@ -9,13 +9,13 @@ - - + + - - +
+ + \ No newline at end of file diff --git a/blog/impact-of-3rd-party-scripts-on-performance.html b/blog/impact-of-3rd-party-scripts-on-performance.html index eab499c..2f22075 100644 --- a/blog/impact-of-3rd-party-scripts-on-performance.html +++ b/blog/impact-of-3rd-party-scripts-on-performance.html @@ -9,14 +9,14 @@ - - + +
-

Impact of 3rd party scripts on performance

Marko Trebižan

Issue with performance

When building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).

This does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?

Partytown to the rescue

Developers at BuilderIO created an library Partytown that would allow relocating resources from 3rd party scripts off the main thread. +

Impact of 3rd party scripts on performance

Marko Trebižan

Issue with performance

When building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).

This does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?

Partytown to the rescue

Developers at BuilderIO created an library Partytown that would allow relocating resources from 3rd party scripts off the main thread. We won't dive into specifics how it works, because they explain it nicely on their GitHub page.

In our stack we use Next.js React framework and we will go through the basic steps that will allow us to include Partytown for Google Tag Manager.

Setup

Partytown script needs to be located inside our application and live on the same domain. Since we're using monorepo structure, we need to copy this script across all our frontend application. For that we used CopyPlugin webpack plugin in our Next.js config file:

config.plugins.push(
...
new CopyPlugin({
patterns: [
{
// we copy script from node_modules partytown package to `~partytown` folder in our package that serves static files
from: path.join(path.dirname(require.resolve('@builder.io/partytown')), 'lib'),
// paths for SSR and client side rendering differ
to: path.join(`${isServer ? '..' : '.'}/static/assets/`, '~partytown'),
},
],
})
);

Partytown's requirement is that it needs to know what script should it load into own web worker. For that we set script type to text/partytown. This will prevent script to load on initial load.

Inside _document.tsx we add this:

<Head>
...
// include Partytown and set custom path due to multiple frontends
<Partytown lib={`${addTrailingSlash(this.props.basePath)}_next/static/assets/~partytown/`} debug={false} />
// tag 3rd party script with partytown type
<script type="text/partytown" src={`https://www.googletagmanager.com/gtm.js?id=${id}`} />
...
</Head>

Results

So now, does it work? We used one of our large Ecommerce sites to test the landing Lighthouse score.

This was before adding Partytown:

Lighthouse before Partytown

Here you can see 2 critical things: almost 1s of total blocking time (TBT) and 9s of time to interactive (TTI).

After we added Partytown, we got this:

Lighthouse after Partytown

Time to interactive went from 9s to 6.1s which is almost 33% improvement and total blocking time was reduce by more than 50%! We were more than impressed how easy it was to improve our performances.

Side note: Both screenshots were compressed using Squoosh App.

Next steps

After successful testing of Partytown for Google Tag Manager script, we are more than interested in trying it out on our other scripts. One important topic will be to test Partytown with other service-worker related libraries and how to use them together.

- - + + \ No newline at end of file diff --git a/blog/prometheus-cardinality-issues.html b/blog/prometheus-cardinality-issues.html index 41e25f9..f58276b 100644 --- a/blog/prometheus-cardinality-issues.html +++ b/blog/prometheus-cardinality-issues.html @@ -9,12 +9,12 @@ - - + +
-

Prometheus Is Out Of Memory. Again.

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! +

- - + + \ No newline at end of file diff --git a/blog/rss.xml b/blog/rss.xml index 4d8830a..dac7ae0 100644 --- a/blog/rss.xml +++ b/blog/rss.xml @@ -4,10 +4,23 @@ foomo project docs Blog https://www.foomo.org/blog foomo project docs Blog - Thu, 17 Mar 2022 00:00:00 GMT + Mon, 06 Mar 2023 00:00:00 GMT https://validator.w3.org/feed/docs/rss2.html https://github.com/jpmonette/feed en + + <![CDATA[Accuracy of decimal computations]]> + https://www.foomo.org/blog/accuracy-of-decimal-computations + https://www.foomo.org/blog/accuracy-of-decimal-computations + Mon, 06 Mar 2023 00:00:00 GMT + + Intro

Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors.

Finite accuracy of representation

Floating points are represented like this

Floating point representation

Not every number can be represented with a finite number of decimal places

0.01 —> 0.0000011001100110011…

Taking 17 places of the above results in 0.010000000000000001

Consider the following code snipet that shows the missing accuracy

func main() {

var n float64 = 0

for i := 0; i < 1000; i++ {
n += .01
}

fmt.Println(n)

}

Result: 9.999999999999831

Money computations

They can't be done with floating-point as it would inevitably lead to rounding errors.

Even the following packages are problematic:

github.com/shopspring/decimal

github.com/Rhymond/go-money

a := decimal.NewFromInt(2)
b := decimal.NewFromFloat(300.99)
c := a.Mul(b)
d := c.Div(decimal.NewFromInt(3))

Solution

Use Int by representing money in cents:

  • 10.99 -> 1099 (cents)
  • 10.9900 -> 109900 (4 digit tax)

Conclusio

Division is a problem!

1/3 - > 0.33333333… +Correct way: 0.33, 0.33, 0.34

When doing money calculations one should avoid division as it inevitably leads to loss of accuracy. +When dividing make sure to round to cent and deal with diffs.

Division by 10^k is ok till we are inside of the range of the data type.

]]>
+ golang + currency + decimal accuracy +
<![CDATA[Why bundle size is important?]]> https://www.foomo.org/blog/why-bundle-size-is-important diff --git a/blog/searching-for-search-engines.html b/blog/searching-for-search-engines.html index f14e892..f18d6cc 100644 --- a/blog/searching-for-search-engines.html +++ b/blog/searching-for-search-engines.html @@ -9,15 +9,15 @@ - - + +
-

The never ending search a search engine 2022-01 edition

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve +

The never ending search a search engine 2022-01 edition

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve https://github.com/blugelabs/bluge // next iteration of bleve

projects using bluge

All bleeding edge afaik atm - but definitely good places to look at bluge usage

https://github.com/prabhatsharma/zinc https://github.com/mosuka/phalanx

Look ma I made a vector database

Gotta take a look at this one - will report later

https://github.com/semi-technologies/weaviate

- - + + \ No newline at end of file diff --git a/blog/tags.html b/blog/tags.html index 6ecd10b..f64f811 100644 --- a/blog/tags.html +++ b/blog/tags.html @@ -9,13 +9,13 @@ - - + + - - +
+ + \ No newline at end of file diff --git a/blog/tags/backend.html b/blog/tags/backend.html index acd5cbb..3c4ae04 100644 --- a/blog/tags/backend.html +++ b/blog/tags/backend.html @@ -9,15 +9,15 @@ - - + +
-

2 posts tagged with "backend"

View All Tags

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve +

2 posts tagged with "backend"

View All Tags

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve https://github.com/blugelabs/bluge // next iteration of bleve

projects using bluge

All bleeding edge afaik atm - but definitely good places to look at bluge usage

https://github.com/prabhatsharma/zinc https://github.com/mosuka/phalanx

Look ma I made a vector database

Gotta take a look at this one - will report later

https://github.com/semi-technologies/weaviate

- - + + \ No newline at end of file diff --git a/blog/tags/bundle-size.html b/blog/tags/bundle-size.html index 7771f05..99a1853 100644 --- a/blog/tags/bundle-size.html +++ b/blog/tags/bundle-size.html @@ -9,16 +9,16 @@ - - + +
-

One post tagged with "bundle size"

View All Tags

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). +

One post tagged with "bundle size"

View All Tags

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). So when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets.

Nobody likes waiting…

A study found that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site.

Sending large JavaScript payloads impacts the speed of your site significantly.

Mazzarri

What is a "bundle"?

Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application.

JS bundling is an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests.

Bundle Everywhere

Performance implications

  • Time to transmit over the network: considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times
  • JS parse and compile time: more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input
  • JS execution time: optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive
  • Memory consumption: everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!

AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly.

Mr Chao

What do we do then?

Meh

How to start decreasing the bundle size?

  • Measure: first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI) is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app.
  • Analyze: Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.

Stonks

Breaking up the bundle...

  • Monitor network requests: These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount.
  • Reduce the total dom nodes: the less the page needs to render, the less time it takes.
  • Moving work off the main thread: By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page
  • Caching: Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast

Breaking Bad

Which strategies can we adopt?

  • Minification and Dead Code Elimination: These processes are often summed up as minifying or uglifying.
  • Tree shaking: Tree shaking is dead code elimination on a project or library. Always try to use deps which support “tree shaking”, Bundlephobia could be your friend in this case.
  • Code Splitting and Lazy Loading: Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on.
  • Replace/rewrite large dependencies: Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example).
  • Feature module import: Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).

Strategy

Useful tools to help you reducing bundle size

  • Lighthouse: automated tool for improving the performance, quality, and correctness of your web apps
  • Bundlephobia: Bundlephobia helps you find the performance impact of npm packages
  • Webpack Bundle Analyzer: analyzes your bundle
  • VS Code: Import Cost plugin -> Display import/require package size in the editor

Tools

Conclusion

Performance cannot be stripped down to a single metric such as bundle size. It would be great! Unfortunately there is no single place to measure all of them.I think metrics like the Core Web Vitals and a general look at bundle size should be considered as a starting point. You will cry... A lot... But don’t give up!

The End

- - + + \ No newline at end of file diff --git a/blog/tags/bundle.html b/blog/tags/bundle.html index 78f823e..0b6dfbc 100644 --- a/blog/tags/bundle.html +++ b/blog/tags/bundle.html @@ -9,16 +9,16 @@ - - + +
-

One post tagged with "bundle"

View All Tags

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). +

One post tagged with "bundle"

View All Tags

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). So when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets.

Nobody likes waiting…

A study found that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site.

Sending large JavaScript payloads impacts the speed of your site significantly.

Mazzarri

What is a "bundle"?

Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application.

JS bundling is an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests.

Bundle Everywhere

Performance implications

  • Time to transmit over the network: considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times
  • JS parse and compile time: more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input
  • JS execution time: optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive
  • Memory consumption: everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!

AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly.

Mr Chao

What do we do then?

Meh

How to start decreasing the bundle size?

  • Measure: first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI) is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app.
  • Analyze: Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.

Stonks

Breaking up the bundle...

  • Monitor network requests: These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount.
  • Reduce the total dom nodes: the less the page needs to render, the less time it takes.
  • Moving work off the main thread: By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page
  • Caching: Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast

Breaking Bad

Which strategies can we adopt?

  • Minification and Dead Code Elimination: These processes are often summed up as minifying or uglifying.
  • Tree shaking: Tree shaking is dead code elimination on a project or library. Always try to use deps which support “tree shaking”, Bundlephobia could be your friend in this case.
  • Code Splitting and Lazy Loading: Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on.
  • Replace/rewrite large dependencies: Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example).
  • Feature module import: Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).

Strategy

Useful tools to help you reducing bundle size

  • Lighthouse: automated tool for improving the performance, quality, and correctness of your web apps
  • Bundlephobia: Bundlephobia helps you find the performance impact of npm packages
  • Webpack Bundle Analyzer: analyzes your bundle
  • VS Code: Import Cost plugin -> Display import/require package size in the editor

Tools

Conclusion

Performance cannot be stripped down to a single metric such as bundle size. It would be great! Unfortunately there is no single place to measure all of them.I think metrics like the Core Web Vitals and a general look at bundle size should be considered as a starting point. You will cry... A lot... But don’t give up!

The End

- - + + \ No newline at end of file diff --git a/blog/tags/cardinality.html b/blog/tags/cardinality.html index 6a6e99e..2377672 100644 --- a/blog/tags/cardinality.html +++ b/blog/tags/cardinality.html @@ -9,12 +9,12 @@ - - + +
-

One post tagged with "cardinality"

View All Tags

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! +

- - + + \ No newline at end of file diff --git a/blog/tags/currency.html b/blog/tags/currency.html new file mode 100644 index 0000000..628c4ee --- /dev/null +++ b/blog/tags/currency.html @@ -0,0 +1,23 @@ + + + + + +One post tagged with "currency" | foomo project docs + + + + + + + + + +
+

One post tagged with "currency"

View All Tags

Intro

Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors.

Finite accuracy of representation

Floating points are represented like this

Floating point representation

Not every number can be represented with a finite number of decimal places

0.01 —> 0.0000011001100110011…

Taking 17 places of the above results in 0.010000000000000001

Consider the following code snipet that shows the missing accuracy

func main() {

var n float64 = 0

for i := 0; i < 1000; i++ {
n += .01
}

fmt.Println(n)

}

Result: 9.999999999999831

Money computations

They can't be done with floating-point as it would inevitably lead to rounding errors.

Even the following packages are problematic:

github.com/shopspring/decimal

github.com/Rhymond/go-money

a := decimal.NewFromInt(2)
b := decimal.NewFromFloat(300.99)
c := a.Mul(b)
d := c.Div(decimal.NewFromInt(3))

Solution

Use Int by representing money in cents:

  • 10.99 -> 1099 (cents)
  • 10.9900 -> 109900 (4 digit tax)

Conclusio

Division is a problem!

1/3 - > 0.33333333… +Correct way: 0.33, 0.33, 0.34

When doing money calculations one should avoid division as it inevitably leads to loss of accuracy. +When dividing make sure to round to cent and deal with diffs.

Division by 10^k is ok till we are inside of the range of the data type.

+ + + + \ No newline at end of file diff --git a/blog/tags/debugging.html b/blog/tags/debugging.html index ca61e0a..edf1420 100644 --- a/blog/tags/debugging.html +++ b/blog/tags/debugging.html @@ -9,13 +9,13 @@ - - + + - - +
+ + \ No newline at end of file diff --git a/blog/tags/decimal-accuracy.html b/blog/tags/decimal-accuracy.html new file mode 100644 index 0000000..f5820bc --- /dev/null +++ b/blog/tags/decimal-accuracy.html @@ -0,0 +1,23 @@ + + + + + +One post tagged with "decimal accuracy" | foomo project docs + + + + + + + + + +
+

One post tagged with "decimal accuracy"

View All Tags

Intro

Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors.

Finite accuracy of representation

Floating points are represented like this

Floating point representation

Not every number can be represented with a finite number of decimal places

0.01 —> 0.0000011001100110011…

Taking 17 places of the above results in 0.010000000000000001

Consider the following code snipet that shows the missing accuracy

func main() {

var n float64 = 0

for i := 0; i < 1000; i++ {
n += .01
}

fmt.Println(n)

}

Result: 9.999999999999831

Money computations

They can't be done with floating-point as it would inevitably lead to rounding errors.

Even the following packages are problematic:

github.com/shopspring/decimal

github.com/Rhymond/go-money

a := decimal.NewFromInt(2)
b := decimal.NewFromFloat(300.99)
c := a.Mul(b)
d := c.Div(decimal.NewFromInt(3))

Solution

Use Int by representing money in cents:

  • 10.99 -> 1099 (cents)
  • 10.9900 -> 109900 (4 digit tax)

Conclusio

Division is a problem!

1/3 - > 0.33333333… +Correct way: 0.33, 0.33, 0.34

When doing money calculations one should avoid division as it inevitably leads to loss of accuracy. +When dividing make sure to round to cent and deal with diffs.

Division by 10^k is ok till we are inside of the range of the data type.

+ + + + \ No newline at end of file diff --git a/blog/tags/devops.html b/blog/tags/devops.html index 9ace53d..5905348 100644 --- a/blog/tags/devops.html +++ b/blog/tags/devops.html @@ -9,12 +9,12 @@ - - + +
-

One post tagged with "devops"

View All Tags

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! +

- - + + \ No newline at end of file diff --git a/blog/tags/foomo.html b/blog/tags/foomo.html index d49df43..13be471 100644 --- a/blog/tags/foomo.html +++ b/blog/tags/foomo.html @@ -9,13 +9,13 @@ - - + +
-

One post tagged with "foomo"

View All Tags

Jan Halfar

A few years ago we abandoned the previous version of https://www.foomo.org as we did not want to maintain the old wordpress installation and the project was only living in README.md in the repos living under https://www.github.com/foomo .

As things have grown over time we have decided to re-launch a website / cross project documentation.

So welcome back and enjoy the view to the past:

blast from the past

- - +

One post tagged with "foomo"

View All Tags

Jan Halfar

A few years ago we abandoned the previous version of https://www.foomo.org as we did not want to maintain the old wordpress installation and the project was only living in README.md in the repos living under https://www.github.com/foomo .

As things have grown over time we have decided to re-launch a website / cross project documentation.

So welcome back and enjoy the view to the past:

blast from the past

+ + \ No newline at end of file diff --git a/blog/tags/frontend.html b/blog/tags/frontend.html index 6a1035d..2b39ff2 100644 --- a/blog/tags/frontend.html +++ b/blog/tags/frontend.html @@ -9,14 +9,14 @@ - - + +
-

One post tagged with "frontend"

View All Tags

Marko Trebižan

Issue with performance

When building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).

This does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?

Partytown to the rescue

Developers at BuilderIO created an library Partytown that would allow relocating resources from 3rd party scripts off the main thread. +

One post tagged with "frontend"

View All Tags

Marko Trebižan

Issue with performance

When building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).

This does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?

Partytown to the rescue

Developers at BuilderIO created an library Partytown that would allow relocating resources from 3rd party scripts off the main thread. We won't dive into specifics how it works, because they explain it nicely on their GitHub page.

In our stack we use Next.js React framework and we will go through the basic steps that will allow us to include Partytown for Google Tag Manager.

Setup

Partytown script needs to be located inside our application and live on the same domain. Since we're using monorepo structure, we need to copy this script across all our frontend application. For that we used CopyPlugin webpack plugin in our Next.js config file:

config.plugins.push(
...
new CopyPlugin({
patterns: [
{
// we copy script from node_modules partytown package to `~partytown` folder in our package that serves static files
from: path.join(path.dirname(require.resolve('@builder.io/partytown')), 'lib'),
// paths for SSR and client side rendering differ
to: path.join(`${isServer ? '..' : '.'}/static/assets/`, '~partytown'),
},
],
})
);

Partytown's requirement is that it needs to know what script should it load into own web worker. For that we set script type to text/partytown. This will prevent script to load on initial load.

Inside _document.tsx we add this:

<Head>
...
// include Partytown and set custom path due to multiple frontends
<Partytown lib={`${addTrailingSlash(this.props.basePath)}_next/static/assets/~partytown/`} debug={false} />
// tag 3rd party script with partytown type
<script type="text/partytown" src={`https://www.googletagmanager.com/gtm.js?id=${id}`} />
...
</Head>

Results

So now, does it work? We used one of our large Ecommerce sites to test the landing Lighthouse score.

This was before adding Partytown:

Lighthouse before Partytown

Here you can see 2 critical things: almost 1s of total blocking time (TBT) and 9s of time to interactive (TTI).

After we added Partytown, we got this:

Lighthouse after Partytown

Time to interactive went from 9s to 6.1s which is almost 33% improvement and total blocking time was reduce by more than 50%! We were more than impressed how easy it was to improve our performances.

Side note: Both screenshots were compressed using Squoosh App.

Next steps

After successful testing of Partytown for Google Tag Manager script, we are more than interested in trying it out on our other scripts. One important topic will be to test Partytown with other service-worker related libraries and how to use them together.

- - + + \ No newline at end of file diff --git a/blog/tags/go.html b/blog/tags/go.html index b8bc6c4..a21ea93 100644 --- a/blog/tags/go.html +++ b/blog/tags/go.html @@ -9,15 +9,15 @@ - - + +
-

2 posts tagged with "go"

View All Tags

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve +

2 posts tagged with "go"

View All Tags

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve https://github.com/blugelabs/bluge // next iteration of bleve

projects using bluge

All bleeding edge afaik atm - but definitely good places to look at bluge usage

https://github.com/prabhatsharma/zinc https://github.com/mosuka/phalanx

Look ma I made a vector database

Gotta take a look at this one - will report later

https://github.com/semi-technologies/weaviate

- - + + \ No newline at end of file diff --git a/blog/tags/golang.html b/blog/tags/golang.html new file mode 100644 index 0000000..b085f6b --- /dev/null +++ b/blog/tags/golang.html @@ -0,0 +1,23 @@ + + + + + +One post tagged with "golang" | foomo project docs + + + + + + + + + +
+

One post tagged with "golang"

View All Tags

Intro

Calculating with money can be tricky if not taken proper precautions. Some might be tempted to use float representation for calculating with currency values. That is problematic because of possible rounding errors.

Finite accuracy of representation

Floating points are represented like this

Floating point representation

Not every number can be represented with a finite number of decimal places

0.01 —> 0.0000011001100110011…

Taking 17 places of the above results in 0.010000000000000001

Consider the following code snipet that shows the missing accuracy

func main() {

var n float64 = 0

for i := 0; i < 1000; i++ {
n += .01
}

fmt.Println(n)

}

Result: 9.999999999999831

Money computations

They can't be done with floating-point as it would inevitably lead to rounding errors.

Even the following packages are problematic:

github.com/shopspring/decimal

github.com/Rhymond/go-money

a := decimal.NewFromInt(2)
b := decimal.NewFromFloat(300.99)
c := a.Mul(b)
d := c.Div(decimal.NewFromInt(3))

Solution

Use Int by representing money in cents:

  • 10.99 -> 1099 (cents)
  • 10.9900 -> 109900 (4 digit tax)

Conclusio

Division is a problem!

1/3 - > 0.33333333… +Correct way: 0.33, 0.33, 0.34

When doing money calculations one should avoid division as it inevitably leads to loss of accuracy. +When dividing make sure to round to cent and deal with diffs.

Division by 10^k is ok till we are inside of the range of the data type.

+ + + + \ No newline at end of file diff --git a/blog/tags/javascript.html b/blog/tags/javascript.html index 3febf39..01f638d 100644 --- a/blog/tags/javascript.html +++ b/blog/tags/javascript.html @@ -9,16 +9,16 @@ - - + +
-

One post tagged with "javascript"

View All Tags

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). +

One post tagged with "javascript"

View All Tags

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). So when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets.

Nobody likes waiting…

A study found that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site.

Sending large JavaScript payloads impacts the speed of your site significantly.

Mazzarri

What is a "bundle"?

Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application.

JS bundling is an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests.

Bundle Everywhere

Performance implications

  • Time to transmit over the network: considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times
  • JS parse and compile time: more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input
  • JS execution time: optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive
  • Memory consumption: everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!

AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly.

Mr Chao

What do we do then?

Meh

How to start decreasing the bundle size?

  • Measure: first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI) is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app.
  • Analyze: Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.

Stonks

Breaking up the bundle...

  • Monitor network requests: These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount.
  • Reduce the total dom nodes: the less the page needs to render, the less time it takes.
  • Moving work off the main thread: By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page
  • Caching: Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast

Breaking Bad

Which strategies can we adopt?

  • Minification and Dead Code Elimination: These processes are often summed up as minifying or uglifying.
  • Tree shaking: Tree shaking is dead code elimination on a project or library. Always try to use deps which support “tree shaking”, Bundlephobia could be your friend in this case.
  • Code Splitting and Lazy Loading: Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on.
  • Replace/rewrite large dependencies: Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example).
  • Feature module import: Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).

Strategy

Useful tools to help you reducing bundle size

  • Lighthouse: automated tool for improving the performance, quality, and correctness of your web apps
  • Bundlephobia: Bundlephobia helps you find the performance impact of npm packages
  • Webpack Bundle Analyzer: analyzes your bundle
  • VS Code: Import Cost plugin -> Display import/require package size in the editor

Tools

Conclusion

Performance cannot be stripped down to a single metric such as bundle size. It would be great! Unfortunately there is no single place to measure all of them.I think metrics like the Core Web Vitals and a general look at bundle size should be considered as a starting point. You will cry... A lot... But don’t give up!

The End

- - + + \ No newline at end of file diff --git a/blog/tags/k-8-s.html b/blog/tags/k-8-s.html index 07b4252..fb3d3b4 100644 --- a/blog/tags/k-8-s.html +++ b/blog/tags/k-8-s.html @@ -9,12 +9,12 @@ - - + +
-

One post tagged with "k8s"

View All Tags

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! +

- - + + \ No newline at end of file diff --git a/blog/tags/memory.html b/blog/tags/memory.html index 1dbe5c1..d285de9 100644 --- a/blog/tags/memory.html +++ b/blog/tags/memory.html @@ -9,12 +9,12 @@ - - + +
-

One post tagged with "memory"

View All Tags

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! +

- - + + \ No newline at end of file diff --git a/blog/tags/oom.html b/blog/tags/oom.html index ff5282a..dff81e7 100644 --- a/blog/tags/oom.html +++ b/blog/tags/oom.html @@ -9,12 +9,12 @@ - - + +
-

One post tagged with "oom"

View All Tags

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! +

- - + + \ No newline at end of file diff --git a/blog/tags/ops.html b/blog/tags/ops.html index eb0168c..c886123 100644 --- a/blog/tags/ops.html +++ b/blog/tags/ops.html @@ -9,12 +9,12 @@ - - + +
-

One post tagged with "ops"

View All Tags

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! +

- - + + \ No newline at end of file diff --git a/blog/tags/performance.html b/blog/tags/performance.html index a7abcc0..acff0f5 100644 --- a/blog/tags/performance.html +++ b/blog/tags/performance.html @@ -9,14 +9,14 @@ - - + +
-

One post tagged with "performance"

View All Tags

Marko Trebižan

Issue with performance

When building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).

This does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?

Partytown to the rescue

Developers at BuilderIO created an library Partytown that would allow relocating resources from 3rd party scripts off the main thread. +

One post tagged with "performance"

View All Tags

Marko Trebižan

Issue with performance

When building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).

This does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?

Partytown to the rescue

Developers at BuilderIO created an library Partytown that would allow relocating resources from 3rd party scripts off the main thread. We won't dive into specifics how it works, because they explain it nicely on their GitHub page.

In our stack we use Next.js React framework and we will go through the basic steps that will allow us to include Partytown for Google Tag Manager.

Setup

Partytown script needs to be located inside our application and live on the same domain. Since we're using monorepo structure, we need to copy this script across all our frontend application. For that we used CopyPlugin webpack plugin in our Next.js config file:

config.plugins.push(
...
new CopyPlugin({
patterns: [
{
// we copy script from node_modules partytown package to `~partytown` folder in our package that serves static files
from: path.join(path.dirname(require.resolve('@builder.io/partytown')), 'lib'),
// paths for SSR and client side rendering differ
to: path.join(`${isServer ? '..' : '.'}/static/assets/`, '~partytown'),
},
],
})
);

Partytown's requirement is that it needs to know what script should it load into own web worker. For that we set script type to text/partytown. This will prevent script to load on initial load.

Inside _document.tsx we add this:

<Head>
...
// include Partytown and set custom path due to multiple frontends
<Partytown lib={`${addTrailingSlash(this.props.basePath)}_next/static/assets/~partytown/`} debug={false} />
// tag 3rd party script with partytown type
<script type="text/partytown" src={`https://www.googletagmanager.com/gtm.js?id=${id}`} />
...
</Head>

Results

So now, does it work? We used one of our large Ecommerce sites to test the landing Lighthouse score.

This was before adding Partytown:

Lighthouse before Partytown

Here you can see 2 critical things: almost 1s of total blocking time (TBT) and 9s of time to interactive (TTI).

After we added Partytown, we got this:

Lighthouse after Partytown

Time to interactive went from 9s to 6.1s which is almost 33% improvement and total blocking time was reduce by more than 50%! We were more than impressed how easy it was to improve our performances.

Side note: Both screenshots were compressed using Squoosh App.

Next steps

After successful testing of Partytown for Google Tag Manager script, we are more than interested in trying it out on our other scripts. One important topic will be to test Partytown with other service-worker related libraries and how to use them together.

- - + + \ No newline at end of file diff --git a/blog/tags/prometheus.html b/blog/tags/prometheus.html index 27c2634..0b465bd 100644 --- a/blog/tags/prometheus.html +++ b/blog/tags/prometheus.html @@ -9,12 +9,12 @@ - - + +
-

One post tagged with "prometheus"

View All Tags

The Annoyance

So, we've all been there. You go to your trusty grafana, search for some sweet metrics that you implemented and WHAM! +

- - + + \ No newline at end of file diff --git a/blog/tags/search-engine.html b/blog/tags/search-engine.html index 85d384f..5867970 100644 --- a/blog/tags/search-engine.html +++ b/blog/tags/search-engine.html @@ -9,15 +9,15 @@ - - + +
-

One post tagged with "search-engine"

View All Tags

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve +

One post tagged with "search-engine"

View All Tags

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve https://github.com/blugelabs/bluge // next iteration of bleve

projects using bluge

All bleeding edge afaik atm - but definitely good places to look at bluge usage

https://github.com/prabhatsharma/zinc https://github.com/mosuka/phalanx

Look ma I made a vector database

Gotta take a look at this one - will report later

https://github.com/semi-technologies/weaviate

- - + + \ No newline at end of file diff --git a/blog/tags/search.html b/blog/tags/search.html index bc854df..1c8d968 100644 --- a/blog/tags/search.html +++ b/blog/tags/search.html @@ -9,15 +9,15 @@ - - + +
-

One post tagged with "search"

View All Tags

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve +

One post tagged with "search"

View All Tags

Jan Halfar

While building this website and integrating https://docsearch.algolia.com and evaluating another solution by a large company in parallel I could not help to search github and the web for the current state of search engines and search related services.

Since I had done the same thing about a year ago, I was surprised to see how quickly things are moving atm.

Algolia

I was blown away by the quality of https://www.algolia.com and I wish it was open source, but I guess, we all have to make a living ;)

To see how awesome a web (search) interface can be check out https://www.lacoste.com/us/#query=red%20jackets%20for%20men

Apart from that the UI/UX of their backend tools is fantastic.

Elastic

When it comes to https://www.elastic.com I am a bit nervous about the future of the licensing, despite the fact, that I understand their motivation. At the same time the https://opensearch.org does not seem to be an ampty threat.

typesense.org

I do not know, who was hiding under a rock, but I had not seen https://typesense.org before and they certainly have a bold claim: "The Open Source Algolia Alternative" / "The Easier To Use ElasticSearch Alternative"

When looking at https://github.com/typesense/typesense/graphs/contributors it seems, that Kishore Nallan has been working on this for a while. Unfourtunately I do not really see a lot of external contributions, C++ does not seem to attract a lot of contribution.

MeiliSearch

This Rust project https://www.meilisearch.com/ seems to be picking up speed and is definetly on the test short list. It is a fresh codebase with siginficant open source contributions and certainly will attract new developers with Rust and a modern architecture.

Go eco system

Obviously we are very interested in Go powered software and there are a few notable projects. ATM I do not see anything elastic or algolia like, that would be really mature.

bleve / bluge

Marty Schoch seems to be the man when it comes down to text indexing libraries in written in Go and bluge seems to be THE library, that is solid and modern, when implementing text search in your Go application.

https://github.com/blevesearch/bleve https://github.com/blugelabs/bluge // next iteration of bleve

projects using bluge

All bleeding edge afaik atm - but definitely good places to look at bluge usage

https://github.com/prabhatsharma/zinc https://github.com/mosuka/phalanx

Look ma I made a vector database

Gotta take a look at this one - will report later

https://github.com/semi-technologies/weaviate

- - + + \ No newline at end of file diff --git a/blog/welcome-back-2021.html b/blog/welcome-back-2021.html index 4a6ec0b..f0a7a18 100644 --- a/blog/welcome-back-2021.html +++ b/blog/welcome-back-2021.html @@ -9,13 +9,13 @@ - - + +
-

Relaunching foomo.org

Jan Halfar

A few years ago we abandoned the previous version of https://www.foomo.org as we did not want to maintain the old wordpress installation and the project was only living in README.md in the repos living under https://www.github.com/foomo .

As things have grown over time we have decided to re-launch a website / cross project documentation.

So welcome back and enjoy the view to the past:

blast from the past

- - +

Relaunching foomo.org

Jan Halfar

A few years ago we abandoned the previous version of https://www.foomo.org as we did not want to maintain the old wordpress installation and the project was only living in README.md in the repos living under https://www.github.com/foomo .

As things have grown over time we have decided to re-launch a website / cross project documentation.

So welcome back and enjoy the view to the past:

blast from the past

+ + \ No newline at end of file diff --git a/blog/why-bundle-size-is-important.html b/blog/why-bundle-size-is-important.html index 4da7d1d..25013a4 100644 --- a/blog/why-bundle-size-is-important.html +++ b/blog/why-bundle-size-is-important.html @@ -9,16 +9,16 @@ - - + +
-

Why bundle size is important?

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). +

Why bundle size is important?

Nicola Turcato

Intro

JavaScript is parsed, compiled and executed in the main thread of the browser. Which means that users have to wait for all of this before they can interact with the website.

Frontend performance optimization is critical because it accounts for around 80-90% of user response time (10-20% backend). So when a user is waiting for a page to load, around 80-90% of the time is due to frontend related code and assets.

Nobody likes waiting…

A study found that if a site takes longer than 4 seconds to load, up to 25% of users would abandon the site.

Sending large JavaScript payloads impacts the speed of your site significantly.

Mazzarri

What is a "bundle"?

Your frontend application needs a bunch of JS files to run. These files can be in the format of internal dependency like the JS files you have written yourself. But they can also be external dependencies you use to build your application.

JS bundling is an optimization technique to reduce the number of server requests for JavaScript files. Bundling accomplishes this by merging multiple JA files together into one file to reduce the number of page requests.

Bundle Everywhere

Performance implications

  • Time to transmit over the network: considering slow connections with some mobile devices, it's possible that your page will not be interactive until it loads.-> More bytes = longer download times
  • JS parse and compile time: more code you load, more the browser must parse.-> JS gets parsed and compiled on the main thread, when the main thread is busy, the page can't respond to user input
  • JS execution time: optimally you will only pack the code that you expect to execute. The more code you want to execute the longer it will take. It's possible that your page won't be interactive until some of this completes.-> JS is also executed on the main thread, if your page runs a lot of code before it's really needed, that also delays your Time to Interactive
  • Memory consumption: everything fills up the space -> code itself, runtime variables, DOM elements created, etc.-> Pages appear slow when it consumes a lot of memory. Memory leaks can cause your page to freeze up completely!!

AS SMALL AS POSSIBLE! I experienced that is not really possible to give a precise answer because each application is different. Generally you want the resources on initial load to be as small as possible, so that you decrease the initial load time, and then load more resources as needed on the fly.

Mr Chao

What do we do then?

Meh

How to start decreasing the bundle size?

  • Measure: first of all you want to measure. The first step is to use Lighthouse and try to understand the results. It will give you a couple of interesting metrics and some tips. Time to interactive (TTI) is a good reflection of your bundle size because your bundle needs to be evaluated entirely before a user can interact with your web app.
  • Analyze: Consists on analyzing the bundle in order to detect critical chunks. A useful tool is Webpack Bundle Analyzer.

Stonks

Breaking up the bundle...

  • Monitor network requests: These happens between our FCP and TTI. As the initial request for data often occurs when our components initially mount.
  • Reduce the total dom nodes: the less the page needs to render, the less time it takes.
  • Moving work off the main thread: By moving heavy computations to a web worker, the computation will be run on a separate thread, and not block the actual rendering of the page
  • Caching: Even if not useful for users on first page landing, caching data, bundles, and assets can make subsequent visits way fast

Breaking Bad

Which strategies can we adopt?

  • Minification and Dead Code Elimination: These processes are often summed up as minifying or uglifying.
  • Tree shaking: Tree shaking is dead code elimination on a project or library. Always try to use deps which support “tree shaking”, Bundlephobia could be your friend in this case.
  • Code Splitting and Lazy Loading: Code splitting consists on taking a collection of modules and remove them from the main JS bundle. Lazy loading means we can load this newly created bundle later on.
  • Replace/rewrite large dependencies: Consider replacing or rewriting libraries that are large in size where you might not need all of its functionalities (Moment.js for example).
  • Feature module import: Check to see if you are using only a feature module of the library that can be imported alone without importing the whole library (Lodash for example).

Strategy

Useful tools to help you reducing bundle size

  • Lighthouse: automated tool for improving the performance, quality, and correctness of your web apps
  • Bundlephobia: Bundlephobia helps you find the performance impact of npm packages
  • Webpack Bundle Analyzer: analyzes your bundle
  • VS Code: Import Cost plugin -> Display import/require package size in the editor

Tools

Conclusion

Performance cannot be stripped down to a single metric such as bundle size. It would be great! Unfortunately there is no single place to measure all of them.I think metrics like the Core Web Vitals and a general look at bundle size should be considered as a starting point. -You will cry... A lot... But don’t give up!

The End

- - +You will cry... A lot... But don’t give up!

The End

+ + \ No newline at end of file diff --git a/docs/backend/go-by-example/cli-applications.html b/docs/backend/go-by-example/cli-applications.html index 32d5cc4..39dea6c 100644 --- a/docs/backend/go-by-example/cli-applications.html +++ b/docs/backend/go-by-example/cli-applications.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/context.html b/docs/backend/go-by-example/context.html index dc72858..41378a4 100644 --- a/docs/backend/go-by-example/context.html +++ b/docs/backend/go-by-example/context.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/defer.html b/docs/backend/go-by-example/defer.html index cf57f64..839671c 100644 --- a/docs/backend/go-by-example/defer.html +++ b/docs/backend/go-by-example/defer.html @@ -9,8 +9,8 @@ - - + +
@@ -22,7 +22,7 @@ What would happen if we add the defer keyword before each of our prints?

It's good practice to use defer to close a response body right after you have opened it. In this way you make sure all resources that have been opened have been closed and in this way it can prevent some bugs. What you will see often is something like this:

func main() {
resp, err := http.Get("http://www.foomo.org")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
}

You open a resource, check if there is an error and after it use defer to close it before the function returns.

Another thing to keep in mind with defer is that it will execute with the value given to it at the time. To demonstrate:

func main() {
myVar := "hello"
defer fmt.Println(myVar)
myVar = "goodbye"
}

What do you think this prints? You might think it will print 'goodbye' because that is the last value of the variable before the main function returns. Surprisingly the value printed is 'hello', which is likely the result of a compiler optimization.

- - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/embed.html b/docs/backend/go-by-example/embed.html index 01d08ae..b23f850 100644 --- a/docs/backend/go-by-example/embed.html +++ b/docs/backend/go-by-example/embed.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/files.html b/docs/backend/go-by-example/files.html index 43b754b..e2e524d 100644 --- a/docs/backend/go-by-example/files.html +++ b/docs/backend/go-by-example/files.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/goroutines-and-channels.html b/docs/backend/go-by-example/goroutines-and-channels.html index 732dd4d..d3917bc 100644 --- a/docs/backend/go-by-example/goroutines-and-channels.html +++ b/docs/backend/go-by-example/goroutines-and-channels.html @@ -9,8 +9,8 @@ - - + +
@@ -26,7 +26,7 @@ go into a waiting state once it has sent the data, until this data is read by th So until the data is read of the channel this go routine is blocked.

Buffered Channels

You can set a limit on the capacity of a channel by passing the limit to the make function:

func main() {
myChannel := make(chan string, 5)
}

To demonstrate how an unbuffered channel only allows for synchronous communication consider the following example:

... loading sources

You see that even though we made both go routines wait when the channel was read, the go routine using the buffered channel printed out all of the statements at once. And the go routine using the unbuffered channel had to wait each time until the channel was read out to be able to continue singing the greatest song of all time.

- - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/http.html b/docs/backend/go-by-example/http.html index e42989b..7d40b51 100644 --- a/docs/backend/go-by-example/http.html +++ b/docs/backend/go-by-example/http.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/interfaces.html b/docs/backend/go-by-example/interfaces.html index 21e9836..30f6f7e 100644 --- a/docs/backend/go-by-example/interfaces.html +++ b/docs/backend/go-by-example/interfaces.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/map-racing.html b/docs/backend/go-by-example/map-racing.html index 53a101d..e5361cd 100644 --- a/docs/backend/go-by-example/map-racing.html +++ b/docs/backend/go-by-example/map-racing.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/mongodb.html b/docs/backend/go-by-example/mongodb.html index 58e0f22..2cac394 100644 --- a/docs/backend/go-by-example/mongodb.html +++ b/docs/backend/go-by-example/mongodb.html @@ -9,14 +9,14 @@ - - + +

MongoDB

Make sure to use the official golang mongo driver:

go.mongodb.org/mongo-driver/mongo

This documentation is a simplified version of the tutorial on MongoDB's website

Set client connections

clientOptions := options.Client().ApplyURI(<MongoDB-database-URI>)

Connect with the database

client, err := mongo.Connect(context.TODO(), clientOptions)

Check connection

err = client.Ping(context.TODO(), nil)

A collection is a grouping of MongoDB documents. Documents within a collection can have different fields. A collection is the equivalent of a table in a relational database system. A collection exists within a single database

source: Geeks for Geeks https://www.geeksforgeeks.org/mongodb-database-collection-and-document/

JSON documents in MongoDB are stored in a binary representation called BSON (Binary-encoded JSON). Unlike other databases that store JSON data as simple strings and numbers, the BSON encoding extends the JSON representation to include additional types such as int, long, date, floating point, and decimal128. This makes it much easier for applications to reliably process, sort, and compare data. The Go Driver has two families of types for representing BSON data: The D types and the Raw types. The D family of types is used to concisely build BSON objects using native Go types:

  • D: A BSON document. This type should be used in situations where order matters, such as MongoDB commands.
  • M: An unordered map. It is the same as D, except it does not preserve order.
  • A: A BSON array.
  • E: A single element inside a D.

You use filters to get the specific data you ask for.

CRUD Operations

Insert one item

insertResult, err := collection.InsertOne(context.TODO(), <item>)

Insert Many

this takes a slice of objects

my-slice := []interface{}{item1, item2}
insertManyResult, err := collection.InsertMany(context.TODO(), my-slice)

Update a single document

Requires a filter document to match documents in the database and an update document to describe the update operation.

filter := bson.D{{"name", “item1”}}
update := bson.D{
{"$inc", bson.D{ // Increases var1 with 1
{“var1”, 1},
}},
}
updateResult, err := collection.UpdateOne(context.TODO(), filter, update)

Find a single document

Requires a filter document and a pointer to a value into which the result can be decoded, returns a single result which can be decoded into a value.

var item_result Item // value into which the result can be decoded
err = collection.FindOne(context.TODO(), filter).Decode(&result)

Find multiple documents

This method returns a Cursor. A Cursor provides a stream of documents through which you can iterate and decode one at a time. Once a Cursor has been exhausted, you should close the Cursor.

findOptions := options.Find()
var results []*Item
cur, err := collection.Find(context.TODO(), bson.D{{}}, findOptions)
for cur.Next(context.TODO()) {
var elem Item
err := cur.Decode(&elem)
if err != nil {
log.Fatal(err)
}
results = append(results, &elem)
}
cur.Close(context.TODO())

Delete documents

You can choose to use collection.DeleteOne() or collection.DeleteMany(), both take a filter document to match the documents in the collection.

deleteResult, err := collection.DeleteMany(context.TODO(), bson.D{{}})

Close connection

Best to keep connection open if you have to do multiple things. It does not make sense to open and close a connection if you have to query the database multiple times.

err = client.Disconnect(context.TODO())
- - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/nil-maps.html b/docs/backend/go-by-example/nil-maps.html index bacca44..204871e 100644 --- a/docs/backend/go-by-example/nil-maps.html +++ b/docs/backend/go-by-example/nil-maps.html @@ -9,8 +9,8 @@ - - + +
@@ -22,7 +22,7 @@ without a problem to the other. Map1 is a nil map, because it has not b with the make statement you can add elements to this map later on in your program. Nil maps could for example be used for structs that have optional data. In that case we don't want to allocate them every time, only when the data is present.


While you can not add elements to a nil map, read operations work just fine. Try it out yourself in the following example:

... loading sources
- - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/panic-and-recover.html b/docs/backend/go-by-example/panic-and-recover.html index 222913e..1347067 100644 --- a/docs/backend/go-by-example/panic-and-recover.html +++ b/docs/backend/go-by-example/panic-and-recover.html @@ -9,8 +9,8 @@ - - + +
@@ -19,7 +19,7 @@ So the order of execution is: Execute called function, then execute defer statements, and in case of a panic program execution will stop. So even if your application will panic defer statements are handled and therefore resources will be closed accordingly.

Panic and Recover

Try out the following example:

... loading sources
The function that panics will stop because it can no longer function so we don't see 'Is this printed?' printed. The recover function makes it possible to obtain the error in case a panic occurred, and leaves the decision how to proceed to the programmer. In this example, we decided to just log the error and continue to run. The function that panicked will stop execution at the panic, but the code that called it will continue to execute, which is why we see 'End' being printed.
- - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/ranging.html b/docs/backend/go-by-example/ranging.html index d386bb0..8b941f6 100644 --- a/docs/backend/go-by-example/ranging.html +++ b/docs/backend/go-by-example/ranging.html @@ -9,14 +9,14 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/reflection.html b/docs/backend/go-by-example/reflection.html index 478ff5d..bafea97 100644 --- a/docs/backend/go-by-example/reflection.html +++ b/docs/backend/go-by-example/reflection.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/type-casting.html b/docs/backend/go-by-example/type-casting.html index 35569fb..2eb08d1 100644 --- a/docs/backend/go-by-example/type-casting.html +++ b/docs/backend/go-by-example/type-casting.html @@ -9,14 +9,14 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/go-by-example/yaml-magic.html b/docs/backend/go-by-example/yaml-magic.html index 1d1d287..8515351 100644 --- a/docs/backend/go-by-example/yaml-magic.html +++ b/docs/backend/go-by-example/yaml-magic.html @@ -9,14 +9,14 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/gograpple.html b/docs/backend/gograpple.html index 2ee57b7..fd2a78b 100644 --- a/docs/backend/gograpple.html +++ b/docs/backend/gograpple.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/intro.html b/docs/backend/intro.html index 341fcb8..97b25e0 100644 --- a/docs/backend/intro.html +++ b/docs/backend/intro.html @@ -9,14 +9,14 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/rtfm.html b/docs/backend/rtfm.html index b2eb499..7f83e67 100644 --- a/docs/backend/rtfm.html +++ b/docs/backend/rtfm.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/backend/setup.html b/docs/backend/setup.html index 0ef0cda..a548d0f 100644 --- a/docs/backend/setup.html +++ b/docs/backend/setup.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/devops/bookmarks.html b/docs/devops/bookmarks.html index 0dd5837..805765d 100644 --- a/docs/devops/bookmarks.html +++ b/docs/devops/bookmarks.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/devops/infrastructure/conventions.html b/docs/devops/infrastructure/conventions.html index 847cd9d..aba5311 100644 --- a/docs/devops/infrastructure/conventions.html +++ b/docs/devops/infrastructure/conventions.html @@ -9,13 +9,13 @@ - - + +

Conventions

When creating resources the most important thing is to be consistent.

Resource Naming Conventions

The following resource convention is preferred if no other exist in the project:

[customer*]-[project]-[resource*]-[env*]-[name*]-[region/location]-[index]

The fields with a * are required.

Legend:

customer:          bestbytes, foomo
project: hmd
reqource: s3, pql, vpc
env: prod, stage, dev, int, test
name: default, general, catalogue-backend
region/location: region for this resource if it's region specific
index: numbering of the resource, starting from 1 (3 numbers, leading zeros)

Examples:

# Foomo customer s3 bucket for prod environment with the described role (catalogue-backend/site-images)
foomo-s3-prod-NAME

- foomo-s3-prod-catalogue-backend
- foomo-s3-prod-site-images

# Foomo customer VPC for stage environment with the described role (default/mongodb)
foomo-vpc-stage-NAME

- foomo-vpc-stage-default
- foomo-vpc-stage-mongodb

# Bestbytes customer for HMD project, postgresql instance for stage environment and default usage
bestbytes-hmd-pql-stage-default

# Bestbytes customer VPN Tunnel #1 in the stage environment for externalcustomer with numbering
bestbytes-vpt-stage-externalcustomer-001
- - + + \ No newline at end of file diff --git a/docs/devops/intro.html b/docs/devops/intro.html index 9b0b0f6..ea02a3e 100644 --- a/docs/devops/intro.html +++ b/docs/devops/intro.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/devops/k8s.html b/docs/devops/k8s.html index 7d32ef8..c013ea7 100644 --- a/docs/devops/k8s.html +++ b/docs/devops/k8s.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/devops/kubernetes/spot-instance-node-pools.html b/docs/devops/kubernetes/spot-instance-node-pools.html index 3d53e8a..82d6a96 100644 --- a/docs/devops/kubernetes/spot-instance-node-pools.html +++ b/docs/devops/kubernetes/spot-instance-node-pools.html @@ -9,8 +9,8 @@ - - + +
@@ -18,7 +18,7 @@ What could happen is that nodes that are hosting the applications start terminating, and our application becomes unresponsive until the application is re-located to another node. To avoid that situation, for the instances we need to configure pod disruption budget on our helm deployments.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: application-name
spec:
maxAvailable: 50%
selector:
matchLabels:
app: application-name

For more details check out here

Setting Up Termination Handling

Setting Up K8s Cron Shutdown Cleanup

- - + + \ No newline at end of file diff --git a/docs/devops/monitoring/grafana.html b/docs/devops/monitoring/grafana.html index 153758a..0367633 100644 --- a/docs/devops/monitoring/grafana.html +++ b/docs/devops/monitoring/grafana.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/devops/monitoring/intro.html b/docs/devops/monitoring/intro.html index e84e8a6..a4ea10d 100644 --- a/docs/devops/monitoring/intro.html +++ b/docs/devops/monitoring/intro.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/devops/monitoring/jaeger.html b/docs/devops/monitoring/jaeger.html index eaa46e1..d25e8e5 100644 --- a/docs/devops/monitoring/jaeger.html +++ b/docs/devops/monitoring/jaeger.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/frontend/css.html b/docs/frontend/css.html index 9579bf6..2d0a531 100644 --- a/docs/frontend/css.html +++ b/docs/frontend/css.html @@ -9,13 +9,13 @@ - - + +
- - + + \ No newline at end of file diff --git a/docs/frontend/debugging_js.html b/docs/frontend/debugging_js.html index 22b1007..e6ba75b 100644 --- a/docs/frontend/debugging_js.html +++ b/docs/frontend/debugging_js.html @@ -9,13 +9,13 @@ - - + +

Debugging in JavaScript

Debugging experience is very important because it can save you hours of depressing search for a bug.

console logging

Probably 95% of devs nowadays still use console.log since it's the most convenient way of outputting something. There are also some nicer ways to output something, especially when having an array of object. In that case it's much nicer to use console.table(array) because it will create a nice table with all fields.

Sometimes a debugger in the browser won't create a breakpoint like you want it or you can't find a source file where you would want. A nice trick is to add a debugger keyword in your code which will instantly stop executing script on that place (but only if you have devtools open).

Bisecting

When you can't find what causes an error, a very common approach is doing bisection. This is simply removing half of the code and see if it still works or not. If it works, then the bug is in the removed code, otherwise start removing other half in existing code.

Chrome/Firefox devtools

Today's browsers have really good devtools and we can't imagine developing without them. And they all nice of helper tricks that ease our development and especially debugging.

... TODO: @themre

- - + + \ No newline at end of file diff --git a/docs/frontend/intro.html b/docs/frontend/intro.html index 14cbc07..ea837cf 100644 --- a/docs/frontend/intro.html +++ b/docs/frontend/intro.html @@ -9,13 +9,13 @@ - - + +

Frontend Guide

In this section you will find a guide on how to develop frontends with the foomo stack. Please also see the general guide.

Let me share a few thoughts on frontend development from our journey @bestbytes the company behind https://www.foomo.org .

Web development has been a wild ride since the beginning of the www in the mid 1990s. Today we take it as granted, that the default way to build applications is with web technologies.

Not too long ago this seemed absurd, since browsers were meant to share scientific research papers and therefore were extremely limited in their capabilities.

It was the era of experimentation, that turned the web into the application runtime, which it is today. Plugins like Macromedias flash inspired the rich APIs we can use today, when building web applications.

A little history

The current stack is the result of a more than 20 year journey.

Last millenium

The open source eco system was in its infancy, there was no github (is that really open source as it should be 🤔), there was not even git, there were no real web frameworks and agile methodologies were an exotic nerd topic.

Browsers would sometimes render things in a recognisable way and a table was the way to render your layout. Reliable interactivity could only result from a server round trip and calling JavaScript had a good chance to crash your browser.

Security in browsers was a complete nightmare, it was a time, when one tab could access anothers tabs dom 🤯

Early 2000s

As Microsoft had won the browser wars, we were stuck with IE 6 and like others we were building web applications with the limited resources we had. JavaScript frameworks were still

The plugin era / FLASH

As browsers were slow, buggy and inconsistent FLASH presented this amazing way to build highly interactive websites. It was the time of loaders, which people accepted, because amazing experiences awaited them: animated vector graphics (artists went wild ...), games, the first videos, client server communications, sockets and a canvas API.

Also ActionScript especially AS3 felt so superior to JavaScript at the time.

Flex

Flex used the capabilities of the flash player to provide a fantastic developer experience to build RIAs (rich internet applications). The resulting productivity, application performance and features were unparalled in the JavaScript eco system until long after the demise of the flash player.

After "thoughts on flash"

After the release of the iPhone and the beginning of the walled garden era flash was one of the initial victims. Just for the record, I definitely prefer an independent eco system, which the web is at least to a certain extent, but it certainly was not noble motives, that were driving Apple when pushing for HTML5 in their thoughts on flash.

HTML5

At its arrival HTML5 could not deliver on the many promises, that were made around it. Browser compatibilty was a nightmare, JavaScript performance was poor, the eco system was in its infancy.

As we left the flash eco system we stopped by RequireJS and were using BACKBONE.JS as we felt extremely burnt by Adobe, after they had dropped their whole eco system like a hot potatoe once Apple had declared the end of flash.

TypeScript and the wild framework years

Despite the fact, that we were very sceptic about trusting large vendors, we adopted TypeScript right after it was initially released and we have remained happy users of it until the present day.

The early years of the Node.js community were extremely wild, there was jokes about the number of frameworks released per day. The number of languages that compiled to JavaScript exploded and it just seemed impossible to keep up with the changing environment.

2020s

As we wake up today as frontend developers, we do not expect, that we will keep on doing things as we do them today until the end of our careers, but we at least see a chance, that the code base of a project will not be outdated with delivery of a MVP.

- - + + \ No newline at end of file diff --git a/docs/frontend/performance.html b/docs/frontend/performance.html index 1dfa780..61dd44b 100644 --- a/docs/frontend/performance.html +++ b/docs/frontend/performance.html @@ -9,14 +9,14 @@ - - + +

Performance

JS

JS is nowadays extremely fast and yet we have many performance issues. Here you can find few common mistakes that occur in JS that can decrease performance.

Extensive use of .map, .filter

Let's say you have a large list of objects and you would like to filter them and transform them in some form. Usually we do this:

const largeArray = [ .... ]
largeArray.map(obj => transformObj(obj)).filter(omitBadObject)

In the above case we first loop through whole set, transform it and then filter things out. Not only does this goes through all the items twice, but it also first time goes through all the items and then filters them. One optimization would be to first filter them and then transform them, but ideally we should just use a normal for loop or forEach where you go through items only once.

const finalArray = []
largeArray.forEach(obj => {
if (omitBadObject(obj)) {
finalArray.push(transformObj(obj))
}
})

This code will skip another loop of items.

- - + + \ No newline at end of file diff --git a/docs/frontend/pitfalls.html b/docs/frontend/pitfalls.html index 658bbab..44a938a 100644 --- a/docs/frontend/pitfalls.html +++ b/docs/frontend/pitfalls.html @@ -9,13 +9,13 @@ - - + +

Pitfalls

This section is very important to avoid dangerous bugs in your code. Of course each of our languages or libraries in our stack has many advantages, but they came with dangerous pitfalls.

JavaScript

This section is probably too small to write all the dangerous things in JavaScript, but we hope developers won't do some crazy things like concatenating numbers and strings and such sort of forbidden things will be catched by TS.

But nevertheless, very often we run into issues that are hard to debug.

Mutation

Mutation in JS is a very common problem and thus leads to dangerous bugs.

A very common mutation occurs in spreading. So if you spread an object and it's deeply nested, you need to know that this will only create a shallow copy. So that means that deeply nested fields will still be referenced by the original object. If you need to do a immutable instance we advice in using either klona or immer.

When doing sorting on the array like [1,2,3].sort(...), this does mutate the original array. Devs are used to create new array with .map or .filter, but this here is not the case. So be careful with that. Also do not forget that objects in the array will have a reference to objects in the original array and thus they also needs to be cloned.

Have in mind that doing immutability costs and sometimes it's better to mutate, but also know that in React if you don't create a new reference, setting state won't react. So always have in mind pros and cons of doing mutation.

typeof

typeof is used for checking type of some variables. So when checking if a variable is an array of an object, we try to use typeof. But we should be very careful since typeof works nicely on simple primitive types like number, string, boolean.

When you try to check whether a variable is an object or an array, you try to use typeof. But both are object. So in this case we should use Array.isArray(variable). But be careful, because also null is an object! If you want to deep dive into this, read here.

Numbers are also fun when it comes to NaN. If you check isNaN with typeof, it's actually a number! So for this use-case you need to use Number.isNaN(myNum).

- - + + \ No newline at end of file diff --git a/docs/frontend/rtfm.html b/docs/frontend/rtfm.html index 768a1c5..7025cff 100644 --- a/docs/frontend/rtfm.html +++ b/docs/frontend/rtfm.html @@ -9,13 +9,13 @@ - - + +

External documentation resources

Runtime / browser

In general the Mozilla Developer Network - MDN is a great resource, if you want to know, what your browser is capable of.

Once you found out, how great an API is, the question to answer will be "can I use" feature X. https://caniuse.com/ is a great resource to find the answers, when trying to understand, if a browser API / feature is ready to use for your audience.

JavaScript

JavaScript historically has a very bad reputation. Please enjoy the following classic piece of infotainment: https://www.destroyallsoftware.com/talks/wat

As JavaScript has been massively iterated on, the runtimes hav ecome crazy fast and the language keeps on evolving.

The (mostly functional) subset of the language, that is being used in modern JavaScript / TypeScript projects to is highly expressive and reads well.

Please take the time and learn about

  • functional programming
  • variable scope
  • modern JavaScript syntax
    • arrow functions
    • new keywords
    • spreading
    • ...
  • promises

CSS

  • CSS block model
  • flex box

Browser APIs

  • canvas
  • fetch
  • local storage
  • websockets
  • sse server side events
  • built in types

TypeScript

- - + + \ No newline at end of file diff --git a/docs/frontend/setup.html b/docs/frontend/setup.html index 47427a4..1f208cc 100644 --- a/docs/frontend/setup.html +++ b/docs/frontend/setup.html @@ -9,13 +9,13 @@ - - + +

Frontend setup

How to setup your machine for frontend development

general topics

setting up your IDE

  • vscode

frontend specific

  • yarn / npm / package.json
  • nvm
  • browser extensions
    • preact
    • redux
    • (google analytics)

debugging with emulators / devices

  • xcode
  • android studio

Install software

Mac

First of all install brew from https://brew.sh

brew install nvm
brew cask install iterm2

Linux

Windows

Install Linux ;)

- - + + \ No newline at end of file diff --git a/docs/frontend/stack.html b/docs/frontend/stack.html index 0b7f772..99f3461 100644 --- a/docs/frontend/stack.html +++ b/docs/frontend/stack.html @@ -9,13 +9,13 @@ - - + +

Frontend Stack

Our frontend stack is permanently changing as the underlying eco system does. We are trying to adopt technologies at the "Slope of Enlightenment" in the hype cycle.

Former iterations of our stack were MVC or MVVM frontend frameworks. Since the arrival of React and state mangement libraries like Redux and Zustand we have been building reactive applications.

Reactive frontends are fun to develop and they scale.

TypeScript

Is our language of choice to build frontends for web applications.

We have adopted TypeScript very early, right after its initial public release in 2012. Here is a list of motives:

  • it is a superset JavaScript
  • it does not try to replace JavaScript like many other languages, which compile to JavaScript, it tries to complement and improve it, while staying compatible
  • good type system
  • great tooling

While it seemed to be crazy to trust Microsoft as a friendly open source company, we have not been disappointed so far.

React / Preact

Declarative components and views, fast to develop and fast at runtime.

gotsrpc

Since we are building services in Go and not with Node.js we have created a light weight RPC framework to integrate TypeScript with Go.

When creating TS definitions on the Go side we follow camel case convention of naming fields e.g. lastDateModified instead of LastDateModified.

- - + + \ No newline at end of file diff --git a/docs/frontend/typescript/objects.html b/docs/frontend/typescript/objects.html index 97827dc..92aa7fe 100644 --- a/docs/frontend/typescript/objects.html +++ b/docs/frontend/typescript/objects.html @@ -9,15 +9,15 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/frontend/typescript/spreading.html b/docs/frontend/typescript/spreading.html index 1861f83..1d991dd 100644 --- a/docs/frontend/typescript/spreading.html +++ b/docs/frontend/typescript/spreading.html @@ -9,14 +9,14 @@ - - + +

Spreading

JavaScript spread syntax (...) is a surprisingly powerful construct. It has two main use cases in our applications:

Shallow copying

Spreading creates new instances of objects or array, but we need to be very careful because it only does a shallow copy. If you have a deeply nested object or array, nested entities will still hold a reference to an original value and hence dangerous bugs can occur.

Copying is needed when doing state changes (either local or state management e.g. Redux). If deep cloning is required, structuredClone can be used.

function () {
// let´s start with a relatively simple object
const foo = {
a: 1,
b: 2,
nested: {
child: "is not a copy",
},
};
// this will create a shallow copy of foo and add a field "c"
const bar = { ...foo, c: 3 };
// please note, that the nested property "nested" is not deeply copied,
// thus changes to this object will also affect foo.nested
bar.nested.child += " <- I told you so";

// .foo has been copied though and changes to it affect the original only
foo.a += 1;
return (
<>
<ul>
<li>
<code>foo.a</code> was incremented by 1 and is now <code>2</code>
</li>
<li>
accessing <code>bar.nested.child</code> also changed{" "}
<code>foo.nested.child</code>
</li>
</ul>
<pre>foo: {JSON.stringify(foo)}</pre>
<ul>
<li>
<code>bar.a</code> has kept its original value <code>1</code>
</li>
<li>
a new property <code>c</code> was added
</li>
</ul>
<pre>bar: {JSON.stringify(bar)}</pre>
</>
);
}

Populating jsx attributes

function App() {
// a simple Component, that will render all fields in props
const Foo = (props) => (
<ul>
{
Object
.keys(props)
.map(key => (
<li>
<code>{key}</code>:{props[key]}
</li>
)
)
}
</ul>
);
const data = {
a: 1,
b: 2,
c: 3
}

const { c, ...omittedObject } = data;
return (
<>
{/*
Each of the `data` fields are spreaded as props
*/}
<p>Spread all props</p>
<Foo {...data}/>

<p>Add additional prop</p>
{/*
After we spread, we also add `d` prop.
*/}
<Foo {...data} d={4}/>

<p>Order of props is important</p>
{/*
We will replace `a` with 10
*/}
<Foo {...data} a={10} />
{/*
But this won't replace original `a` with 10
*/}
<Foo a={10} {...data} />

<p>Omit certain properties</p>
{/*
If you wish to omit certain fields, you need to write fields
that you wish to omit and with `...{newVariableName}` you will create a new
object with that name. In our part it's `omittedObject` name.
*/}
<Foo {...omittedObject} />
</>
);
}
- - + + \ No newline at end of file diff --git a/docs/frontend/vscode.html b/docs/frontend/vscode.html index 65f289f..7d04be3 100644 --- a/docs/frontend/vscode.html +++ b/docs/frontend/vscode.html @@ -9,13 +9,13 @@ - - + +
- - + + \ No newline at end of file diff --git a/docs/general/essentials.html b/docs/general/essentials.html index 38562f6..6de982c 100644 --- a/docs/general/essentials.html +++ b/docs/general/essentials.html @@ -9,13 +9,13 @@ - - + +

(Random) essentials

Markdown

Learn markdown(this is a markdown document 🤓)

Vim

Vim is everywhere so no matter if you ssh into a place or try to edit a file in a container, you are going to need it.

Here is a super minimal cheat sheet:

# edit/create a file
vim path/file

Now the shortcuts:

shortcutfunctionnote
:h<enter>helpa bit overwhelming
:q<enter>quitimmediate instinct after looking at help 🤣
:q!<enter>quit ignoring changes! means, that you actually mean it and can be combined with a lot of commands
:w<enter>write / save file
:x<enter> save and exit
:x!<enter> force save and exit
11Ggo to line 11
$ go to last char in line
dddelete line
x delete char
i enter insert modethat is where you can actually edit stuff - press escape to exit insert mode
<esc>exit insert mode
<ctrl>vvisual blockthen use cursors to edit selection
xcut
ppaste

ssh

allows you to remotely and securely log into computers - man ssh should be available on any shell.

digital ocean has a decent intro into ssh https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys

There is a lot of other tutorials - your typical use cases will be:

  • logging into other computers
  • executing commands on those computers
  • tunneling network connections

Once ssh is set up correctly scp, git and a lot of other programs, that rely on ssh under the covers are fun to use too.

git

https://git-scm.com/doc

github

Yes despite the fact, that m$ bought them, we use them and you have to enable 2fa

Some data formats

yaml

https://yaml.org/ some love it for good a reason, some hate it for another good reason, but atm there is just no way around it.

json

https://www.json.org/json-en.html similar love and hate situation like with yaml - also no way out.

CSV

If you think parsing or serializing CSV is trivial, you have been warned.

https://datatracker.ietf.org/doc/html/rfc4180

protocol buffers

Fast, compact not human readable - not necessary for most use cases

https://developers.google.com/protocol-buffers

xml

https://www.w3.org/TR/REC-xml/ only little love here

- - + + \ No newline at end of file diff --git a/docs/general/intro.html b/docs/general/intro.html index 27657a1..17e139f 100644 --- a/docs/general/intro.html +++ b/docs/general/intro.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/general/package-managers.html b/docs/general/package-managers.html index bd6a517..7f0ed08 100644 --- a/docs/general/package-managers.html +++ b/docs/general/package-managers.html @@ -9,13 +9,13 @@ - - + +

Package managers

Whenever you can, do not manage software on your computer manually ...

  • comfort
  • versions
  • security

macOS

On the mac https://brew.sh/ has become the de facto standard - we use it to distribute binaries of some of our open source projects as well.

Windows

...

- - + + \ No newline at end of file diff --git a/docs/general/security.html b/docs/general/security.html index b7b28f9..5900e33 100644 --- a/docs/general/security.html +++ b/docs/general/security.html @@ -9,13 +9,13 @@ - - + +

Security

TODO: @dreadl0ck knock yourself out

OS / Application setup

  • disable telemetry whereever possible

Keep your data safe

  • encrypt your file system to make sure so that if your computer gets stolen at least your data remain secure
  • make sure to have multiple backups in different places i.e. one backup disk at home and one in the office
- - + + \ No newline at end of file diff --git a/docs/general/setup/computer.html b/docs/general/setup/computer.html index 20e5d5f..0bd4707 100644 --- a/docs/general/setup/computer.html +++ b/docs/general/setup/computer.html @@ -9,13 +9,13 @@ - - + +

Setting up your computer

This is a general setup guide for your computer. Make sure that you setup your worpkplace properly too.

Start

  • read this document before you start
  • only use a computer from a trustworthy source
  • reset the computer
  • encrypt your harddrive in order to be on the safe side, if a computer get stolen
  • upgrade to the latest version of the OS you want to use

Privacy and security

Follow the instructions on security when you setup and maintain your system.

Install software

Mac

First of all install brew from https://brew.sh

brew cask install iterm2

Linux

Windows

Install Linux ;)

- - + + \ No newline at end of file diff --git a/docs/general/setup/workplace.html b/docs/general/setup/workplace.html index bb76741..7ee2ee5 100644 --- a/docs/general/setup/workplace.html +++ b/docs/general/setup/workplace.html @@ -9,13 +9,13 @@ - - + +

Setting up your workplace

No matter where you work, you need a proper workplace:

  • ergonomic office chair / desk combination
  • large high pixel density display
  • ergonomic input devices
  • good lighting
  • correct position in the room

Make sure that you take the time to set up your workplace well, your health depends upon it.

- - + + \ No newline at end of file diff --git a/docs/general/technologies/sse.html b/docs/general/technologies/sse.html index 06d8cf7..c9eafe2 100644 --- a/docs/general/technologies/sse.html +++ b/docs/general/technologies/sse.html @@ -9,13 +9,13 @@ - - + +

SSE Server Sent Events

Server Sent Events SSE are a well established web standard.

They allow a web server to push messages to the client.

I have created a minimal example https://github.com/janhalfar/sse-playground/tree/main/minimal to illustrate the technology.

Minimal Example in action

if you clone https://github.com/janhalfar/sse-playground locally and run go run minimal/main.go you will be able to open http://localhost:8080 :

screenshot of chrome debugging SSE

Minimal server

This server will:

Let´s take a look at the server response with:

curl -v localhost:8080/sse/time

% curl -v localhost:8080/sse/time
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /sse/time HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/event-stream
< Date: Fri, 16 Sep 2022 14:49:17 GMT
< Transfer-Encoding: chunked
<
event: time
id: 1
data: 2022-09-16T16:49:17.482796+02:00

event: time
id: 2
data: 2022-09-16T16:49:17.498366+02:00

event: time
id: 3
data: 2022-09-16T16:49:17.514079+02:00

event: time
id: 4
data: 2022-09-16T16:49:17.529639+02:00

event: time
id: 5
data: 2022-09-16T16:49:17.545335+02:00

...

serving the frontend

The first thing the server is to serve a frontend, which is described below:

serve the embedded index.html
loading...

serving time events

serve an event stream of 100 server sent events
loading...

Minimal client

a minimal and incomplete client example
loading...
- - + + \ No newline at end of file diff --git a/docs/general/utilities/k9s.html b/docs/general/utilities/k9s.html index 4d0bba3..9df2875 100644 --- a/docs/general/utilities/k9s.html +++ b/docs/general/utilities/k9s.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/general/work/general.html b/docs/general/work/general.html index 504599c..4a2407b 100644 --- a/docs/general/work/general.html +++ b/docs/general/work/general.html @@ -9,13 +9,13 @@ - - + +

Working as a software developer

Working as a software developer in a sustainable way is challenging - here are a few observations of healthy habits:

  • do not work too much
  • physical exercise is essential
  • clearly separate between working and not working
  • reflect and iterate on your working habits
- - + + \ No newline at end of file diff --git a/docs/general/work/remote-work.html b/docs/general/work/remote-work.html index b765a32..e8f8e10 100644 --- a/docs/general/work/remote-work.html +++ b/docs/general/work/remote-work.html @@ -9,13 +9,13 @@ - - + +

Working remotely

Especially since the beginning of the corona pandemy working remotely has become a very important topic. The foomo team has extensive experience working remotely as we are a distributed team.

Disclaimer: we are almost exclusively working in one timezone.

Requirements

  • fast and reliable internet connection
  • a proper workplace

The good parts

  • no commute
  • less distractions from team members

The bad parts

  • harder to separate between work and your private life
  • less informal communication with teammates
  • less human interaction

When working from home

  • make sure, that you have a routine, that still takes you to work
    • fixed working hours
    • "go to work" and "leave work" even if you do not leave your home
    • if possible use a room, that is for work only
    • have clear rules for your family / roomates, when at work
  • when communication with teammates use video calls
  • take time for your teammates and have a virtual coffee break with someone at least once a day
  • invest half the time, that you save by not communiting to exercise
- - + + \ No newline at end of file diff --git a/docs/project-management/intro.html b/docs/project-management/intro.html index b78bd2d..81db383 100644 --- a/docs/project-management/intro.html +++ b/docs/project-management/intro.html @@ -9,13 +9,13 @@ - - + +

Project Managament

We scrumming in our way ...

Values

  • project managers manage projects not people

Epics

Epics are the starting point ....

- - + + \ No newline at end of file diff --git a/docs/project-management/responsibility.html b/docs/project-management/responsibility.html index b068f5b..4e28ee6 100644 --- a/docs/project-management/responsibility.html +++ b/docs/project-management/responsibility.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/projects/architecture.html b/docs/projects/architecture.html index ab9db6d..bf81991 100644 --- a/docs/projects/architecture.html +++ b/docs/projects/architecture.html @@ -9,13 +9,13 @@ - - + +

Architecture overview

backend services

When it comes to writing backend services we have decided for Go https://go.dev - let me list the main reasons why - Go is:

  • simple and fun
  • fast when compiling
  • fast at runtime
  • friendly to your machines
  • friendly to you as a programmer
  • equipped with a top notch runtime
  • extremely well balanced in its design as a language, that is highly consumable for humans and machines
  • not about the features it has
  • about what has been left out
  • easy to read
  • sustainable

Foomo projects supporting development with Go

  • keel - opinionated way to run services
  • gotsrpc - rpc framework / code generator
  • gograpple - human friendly way to debug go programs running in k8s
  • webgrapple - a development proxy

Frontends

Foomo projects supporting development with Next.js

- - + + \ No newline at end of file diff --git a/docs/projects/cms/contentful.html b/docs/projects/cms/contentful.html index 8ca3f07..9c21c83 100644 --- a/docs/projects/cms/contentful.html +++ b/docs/projects/cms/contentful.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/projects/cms/contentserver.html b/docs/projects/cms/contentserver.html index a525896..10e94e2 100644 --- a/docs/projects/cms/contentserver.html +++ b/docs/projects/cms/contentserver.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/projects/cms/gocontentful/api-reference.html b/docs/projects/cms/gocontentful/api-reference.html index f138c88..c7e7a1a 100644 --- a/docs/projects/cms/gocontentful/api-reference.html +++ b/docs/projects/cms/gocontentful/api-reference.html @@ -9,8 +9,8 @@ - - + +
@@ -57,7 +57,7 @@ set it will substitute the IMG tag with the returned HTML snippet. This allows y images, e.g. a PICTURE tag.

type LinkResolverFunc func(url string) (resolvedAttrs map[string]string, resolveError error)

type EntryLinkResolverFunc func(entryID string, locale Locale) (resolvedAttrs map[string]string, resolveError error)

type ImageResolverFunc func(assetID string, locale Locale) (attrs map[string]string, customHTML string, resolveError error)

type EmbeddedEntryResolverFunc func(entryID string, locale Locale) (html string, resolveError error)

All the three functions above can be passed as nil with different levels of graceful degrading.

Constants and global variables

Each generated content type library file exports a constant with the Contentful ID of the content type itself, for example in contentful_vo_lib_person.go:

const ContentTypePerson = "person"

Constants are available for each locale supported by the space at the time of code generation, e.g.:

const SpaceLocaleGerman Locale = "de"
const SpaceLocaleFrench Locale = "fr"
const defaultLocale Locale = SpaceLocaleGerman

Four levels of logging are supported (even if only partially used at this time):

const (
LogDebug = 0
LogInfo = 1
LogWarn = 2
LogError = 3
)

A global variable named SpaceContentTypeInfoMap contains an ID-indexed map of all content types with their names and descriptions

- - + + \ No newline at end of file diff --git a/docs/projects/cms/gocontentful/caching.html b/docs/projects/cms/gocontentful/caching.html index 2550f76..3a24786 100644 --- a/docs/projects/cms/gocontentful/caching.html +++ b/docs/projects/cms/gocontentful/caching.html @@ -9,8 +9,8 @@ - - + +
@@ -50,7 +50,7 @@ of entries (in the order of less than some hundreds) and do that at significant (e.g. every hour). In this case your application code can be simpler and there won't be any performance penalty. The other case is when you need to run a lot of custom queries or use XPath, which is currently not supported by gocontentful directly.

- - + + \ No newline at end of file diff --git a/docs/projects/cms/gocontentful/getting-started.html b/docs/projects/cms/gocontentful/getting-started.html index e82881e..8739075 100644 --- a/docs/projects/cms/gocontentful/getting-started.html +++ b/docs/projects/cms/gocontentful/getting-started.html @@ -9,8 +9,8 @@ - - + +
@@ -20,7 +20,7 @@ A better approach is to log in to Contentful using the official Contentful C To install the CLI refer to the official documentation at Contentful.com.

After installing the CLI log in inside your terminal with:

$ contentful login
$ gocontentful

ERROR: Please specify either a Contentful Space ID and CMA access token or an export file name

SYNOPSIS
gocontentful -spaceid SpaceID -cmakey CMAKey [-contenttypes firsttype,secondtype...lasttype] path/to/target/package

-cmakey string
[Optional] Contentful CMA key
-contenttypes string
[Optional] Content type IDs to parse, comma separated
-environment string
[Optional] Contentful space environment
-exportfile string
Space export file to generate the API from
-help
Print version and exit
-spaceid string
Contentful space ID
-version
Print version and exit

Notes:
- The last segment of the path/to/target/package will be used as package name
- The -cmakey parameter can be omitted if you logged in with the Contentful CLI

Notes:

  • The last segment of the path/to/target/package will be used as package name
  • You need to pass gocontentful either cmakey/spaceid (and optional environment) to generate the API from a live space or exportfile to generate it from a local space export file. The cmakey can be omitted if you are logged in through the Contentful CLI.
- - + + \ No newline at end of file diff --git a/docs/projects/cms/gocontentful/introduction.html b/docs/projects/cms/gocontentful/introduction.html index 13947c3..f551e77 100644 --- a/docs/projects/cms/gocontentful/introduction.html +++ b/docs/projects/cms/gocontentful/introduction.html @@ -9,13 +9,13 @@ - - + +

Introduction

What is Contentful

Contentful is a content platform (often referred to as headless CMS) for micro-content. There's no pages or content trees in Contentful, the CMS focuses on structured data. The data model is built from scratch for the purpose of the consuming application, is completely flexible and can be created and hot-changed through the same Web UI that the content editors use. The model dictates which content types can reference others and the final structure is a graph.

What is gocontentful

A golang API code generator that simplifies interacting with a Contentful space. The generated API:

  • Supports most of the Contentful APIs to perform all read/write operation on entries and assets
  • Hides the complexity of the Contentful REST/JSON APIs behind an idiomatic set of golang functions and methods
  • Allows for in-memory caching of an entire Contentful space

Rationale

Calling a remote CMS repository across the Internet whenever your service needs a piece of content is not an option because of latency and response time. Hence, you need to cache all the content at the running service and make sure your cache is always up-to-date. In addition, you need to deal with generic entries in JSON format and maintain a Go model with value objects to reflect every change at the CMS' content model, writing functions and methods to import and export entries to/from typed objects.

Trust me: both things quickly scale to royal-PITA level.

Gocontentful wipes out both complexities by generating the content model automatically and providing an idiomatic API to handle interaction with remote content while keeping a cache stays constantly in-sync with the Contentful space. If the content model changes, running gocontentful again will update the Go code for the model and API to reflect those changes automatically.

How much code is that? As an example of a real-world production scenario where gocontentful is in use as of 2022, a space content model with 11 content types ranging from 3 to over 40 fields each generated around 50,000 lines of Go code. Do you need all those lines? You might not need all setters if you don't manage content through the API but you'll definitely need most of the getters otherwise those should not be in the model at all.

- - + + \ No newline at end of file diff --git a/docs/projects/cms/gocontentful/test-api.html b/docs/projects/cms/gocontentful/test-api.html index 775822a..3851397 100644 --- a/docs/projects/cms/gocontentful/test-api.html +++ b/docs/projects/cms/gocontentful/test-api.html @@ -9,8 +9,8 @@ - - + +
@@ -35,7 +35,7 @@ The object returned is a generic *testapi.EntryReference that, amon is the actual *testapi.CfBrand. That's why in the second line we had to cast it.

The test now logs the brand company name:

INFO[0000] Brand                                         name="Normann Copenhagen"

What if we want to follow the reference the other way around and find out which entries link to this brand?

parentRefs, errParents := brand.GetParents()
require.NoError(t, errParents)
testLogger.WithField("parent count", len(parentRefs)).Info("Parents")
for _, parentRef := range parentRefs {
switch parentRef.ContentType {
case testapi.ContentTypeProduct:
parentProduct := parentRef.VO.(*testapi.CfProduct)
testLogger.WithField("name", parentProduct.ProductName()).Info("Parent product")
}
}

Again, the GetParents() method returns references and not objects. It's a good idea to use the reference ContentType attribute to switch before casting the VO to the type, because as we just said referenced objects can come in different types and casting to the wrong one would make the runtime panic. Running the test we find out the two products that belong to this brand:

INFO[0000] Parents                                       parent count=2
INFO[0000] Parent product name="Whisk Beater"
INFO[0000] Parent product name="Hudson Wall Cup"
- - + + \ No newline at end of file diff --git a/docs/projects/cms/gocontentful/working-with-gocontentful-api.html b/docs/projects/cms/gocontentful/working-with-gocontentful-api.html index 09397a9..ea3b112 100644 --- a/docs/projects/cms/gocontentful/working-with-gocontentful-api.html +++ b/docs/projects/cms/gocontentful/working-with-gocontentful-api.html @@ -9,8 +9,8 @@ - - + +
@@ -63,7 +63,7 @@ the value object of entry B to the reference field in A. First you need to conve object to a ContentTypeSys object because that's what Contentful expects in reference fields:

(vo *CfPerson) ToReference() (refSys ContentTypeSys)

Finally, you can get the parents (AKA referring) entries of either an entry or an EntryReference with the GetParents() method. This returns a slice of []EntryReference:

(vo *CfPerson) GetParents() (parents []EntryReference, err error)
(ref *EntryReference) GetParents(cc *ContentfulClient) (parents []EntryReference, err error)

Other useful functions

Another thing you might want to know is the content type of an entry with a given ID:

(cc *ContentfulClient) GetContentTypeOfID(ID string) (contentType string)

Caveats and limitations

  • Avoid creating content types that have field IDs equal to reserved Go words (e.g. "type"). Gocontentful won't scan for them and the generated code will break.
- - + + \ No newline at end of file diff --git a/docs/projects/cms/intro.html b/docs/projects/cms/intro.html index d880344..1fc0500 100644 --- a/docs/projects/cms/intro.html +++ b/docs/projects/cms/intro.html @@ -9,13 +9,13 @@ - - + +

Intro

The foomo team has extensive experience with a wide range of CMS systems. Our long journey in the field has brought us very close to the https://jamstack.org . We almost exclusively work with https://app.contentful.com/ but we are watching others like https://www.stripe.com/ very closely.

Expectations and challenges

  • application developers want an environment, that ensures maximum productivity, they do not think of semantic structures, they think of routes
  • customers expect maximum control and flexibility when working with content and do not distinguish between content and applications

The need for dynamic rendering

If you can - render static content and distribute it with a CDN.

There are use cases though, where static site generation does not work like

  • highly personalized content
  • mixing content with entities from other systems, that have a different life cycle, like products

Application routes vs semantic URL structures

Bridging the conceptual gap between sematic content and applications.

Content especially when created with a focus on SEO comes as a semantic graph. This typically conflicts with how application developers see the world.

e-commerce as an example

Let us take a look at a real world example:

application route / ingressapp developers viewSEO URL requirement
/content:id/content/1/
/content/2/mens
/category:id/category/1/mens/shirts
/category/2/mens/shirts/business
/product:id/product/1/mens-shirt-awesome-blue-medium
/store:id/store/1/mens/stores/london-perfect-shirts
/store/2/kids/stores/lego-paradise

our approach

contentserver allows you to resolve URIs to mime types, which can be handled by applications.

Let us return to our ecommerce example.

model content

mime typecms entityapplication eg k8s service
application/x-pagepagehttps://frontend_service_page
application/x-categorycategoryhttps://frontend_service_category
application/x-storestorehttps://frontend_service_store

export contentent to contentserver

contentserver allows you to export your content tree as json

resolving URIs

Use standard application routing whereever possible, since it is the most efficient option.

Once all standard URI resolution fails, query contentserver and it will return the resolved node


Now you have the mime-type and you know which application can handle it.

- - + + \ No newline at end of file diff --git a/docs/projects/gotsrpc.html b/docs/projects/gotsrpc.html index c0984d3..7109710 100644 --- a/docs/projects/gotsrpc.html +++ b/docs/projects/gotsrpc.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/projects/intro.html b/docs/projects/intro.html index 922d12b..2079a73 100644 --- a/docs/projects/intro.html +++ b/docs/projects/intro.html @@ -9,13 +9,13 @@ - - + +

foomo project overview

"Stuff we wrote, because nobody else wanted to"

All foomo projects are available here https://github.com/foomo also see architecture

We are using the best industry standards and only fill in our own bits, when necessary.

The foomo project maintains libraries, utilities and daemons, which power most projects at https://www.bestbytes.com

Projects running on the foomo stack typically are

  • relatively large with hundreds of thousands of lines of code
  • composed of dozens of microservices
  • written / maintained by dozens of contributors
  • using Go on the server side
  • using Next.js / TypeScript on the client side
  • running on k8s
  • deeply integrated with a headless CMS
  • built with a project specific frontend component set

Everything is loosely coupled, since we know, that the only constant is change.

- - + + \ No newline at end of file diff --git a/docs/projects/libraries/keel-circuit-breaker.html b/docs/projects/libraries/keel-circuit-breaker.html index 7fd5ee9..68f6cd6 100644 --- a/docs/projects/libraries/keel-circuit-breaker.html +++ b/docs/projects/libraries/keel-circuit-breaker.html @@ -9,13 +9,13 @@ - - + +

Circuit Breaker

Sometimes things go wrong and a service does not respond anymore. Be it because of maintainance or because the whole data center burned to the ground. In such a scenario, you might not want to wait until your request times out. This is where circuit breakers come in handy.

Simply put a circuit breaker has three different states:

We did not re-invent the wheel (yet), but rather used an existing circuit breaker. However, we extended the functionality a bit. More on that later. For referance, here are links to the underlying circuit breaker and some more information on circuit breakers in general.

How to use

In order to configure the circuit breaker there are two kinds of configuration. The "base" configuration using the CircuitBreakerSettings and optional configuration using CircuitBreakerOptions.

CircuitBreakerSettings

The settings are relatively straight forward and the same as with the underlying repository - with one exception. Our settings are missing the IsSuccessful field.

net/http/roundtripware/circuitbreaker.go
loading...

CircuitBreakerOptions

Currently, there are two options one for metrics and one for somewhat advanced usage.

Metrics

The option for metrics is, again, straigth forward. When the CircuitBreakerWithMetric option is used the roundtripware will create a counter on the provided meter and count the number of requests.

The attributes added to every count are:

  • previous_state (String): the state of the circuit breaker before the current request. Either "closed", "half-open" or "open"
  • current_state (String): the state of the circuit breaker after the current request. Either "closed", "half-open" or "open"
  • state_change (Bool): helper containing current_state != previous_state
  • error (Bool): false if the request was not passed through or was unsuccessful
net/http/roundtripware/circuitbreaker.go
loading...

IsSuccessful

As mentioned previously, the IsSuccessful field was removed from the basic settings. The reason is that the signature of that function was a bit limiting. As you can see below our IsSuccessful-function can use the request and response. Additionally, if copyReqBody and/or copyRespBody are set to true, you can even read from the respective body, without worrying about consuming the io.ReadCloser.

net/http/roundtripware/circuitbreaker.go
loading...

The ignore value that is returned alongside an error indicates whether the result of the call should be registered with the circuit breaker. For most use cases it should be set to false.

When the IsSuccessful-function returns an error (and the ignore value is set to false), the request will be counted as unsuccessful. Accordingly, a nil error paired with ignored set to false indicates a successful request.

Examples

Let's say we want to stop sending requests once we encountered three consecutive failures.

client := keelhttp.NewHTTPClient(
keelhttp.HTTPClientWithRoundTripware(l,
roundtripware.CircuitBreaker(&roundtripware.CircuitBreakerSettings{
Name: "my little circuit breaker™",
// 2 requests can pass in half-open state & it takes 2 consecutive,
// successful requests to change to closed state
MaxRequests: 2,
// counts are not reset in closed state
Interval: 0,
// breaker will go from open to half-open state after 30s
Timeout: 30 * time.Second,
// go to open state after the 3rd consecutive, unsuccessful request
ReadyToTrip: func(counts gobreaker.Counts) bool {
return counts.ConsecutiveFailures >= 3
},
}),
),
)

Now lets say we see we also want to detect network problems such as a BadGateway. For this we can use the IsSuccessful option.

client := keelhttp.NewHTTPClient(
keelhttp.HTTPClientWithRoundTripware(l,
roundtripware.CircuitBreaker(&roundtripware.CircuitBreakerSettings{
// as before ...
},
roundtripware.CircuitBreakerWithIsSuccessful(
func(err error, req *http.Request, resp *http.Response) (error, bool) {
if err != nil {
return err, false
}
if resp.StatusCode >= http.StatusInternalServerError {
return errors.New("invalid status code"), false
}
return nil, false
}, false, false,
),
),
),
)

Lastly, let's assume we use the client for multiple different endpoints. And we only want to base the circuit breakers state on a single endpoint, but stop request on all endpoints once the breaker changes to open. Again we can use the IsSuccessful option and ignore certain endpoints.

client := keelhttp.NewHTTPClient(
keelhttp.HTTPClientWithRoundTripware(l,
roundtripware.CircuitBreaker(&roundtripware.CircuitBreakerSettings{
// as before ...
},
roundtripware.CircuitBreakerWithIsSuccessful(
func(err error, req *http.Request, resp *http.Response) (error, bool) {
if req.URL.Path != "/important/path" {
return err, false
}

// possibly more checks ...

return err, true
}, false, false,
),
),
),
)

General advice & notes of caution

Using ratios in ReadyToTrip

When using ratios in ready to trip, the Interval should be set to a non-zero value in order to reset the counts periodically. Otherwise, after a long period of successful requests it will also take a long time to impact the ratio and trip the breaker.

    ReadyToTrip: func(counts gobreaker.Counts) bool {
failureRatio := float64(counts.TotalFailures) / float64(counts.Requests)
return counts.Requests >= 3 && failureRatio >= 0.6
},
- - + + \ No newline at end of file diff --git a/docs/projects/libraries/keel.html b/docs/projects/libraries/keel.html index 3fdc450..6eec3fc 100644 --- a/docs/projects/libraries/keel.html +++ b/docs/projects/libraries/keel.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/projects/pagespeed-exporter.html b/docs/projects/pagespeed-exporter.html index 422ced4..b0e35ca 100644 --- a/docs/projects/pagespeed-exporter.html +++ b/docs/projects/pagespeed-exporter.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/projects/site-reliability.html b/docs/projects/site-reliability.html index fcb5bab..17e7d7a 100644 --- a/docs/projects/site-reliability.html +++ b/docs/projects/site-reliability.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/projects/utilities/gograpple.html b/docs/projects/utilities/gograpple.html index e9b881e..2c5205e 100644 --- a/docs/projects/utilities/gograpple.html +++ b/docs/projects/utilities/gograpple.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/projects/webgrapple.html b/docs/projects/webgrapple.html index 97cbd94..2ca81ea 100644 --- a/docs/projects/webgrapple.html +++ b/docs/projects/webgrapple.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/tags.html b/docs/tags.html index 51948fe..f5d20c0 100644 --- a/docs/tags.html +++ b/docs/tags.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/docs/tags/frontend.html b/docs/tags/frontend.html index ef6b496..dcf4f0a 100644 --- a/docs/tags/frontend.html +++ b/docs/tags/frontend.html @@ -9,13 +9,13 @@ - - + +

One doc tagged with "frontend"

View All Tags

Stack

Our frontend stack is permanently changing as the underlying eco system does. We are trying to adopt technologies at the "Slope of Enlightenment" in the hype cycle.

- - + + \ No newline at end of file diff --git a/docs/tags/go-basics.html b/docs/tags/go-basics.html index b77a024..953998d 100644 --- a/docs/tags/go-basics.html +++ b/docs/tags/go-basics.html @@ -9,13 +9,13 @@ - - + +

5 docs tagged with "Go Basics"

View All Tags

Defer

In a normal Go application, control flows from the top to the bottom of any function that we call (this is if you don't use branching or looping).

Maps

Maps are unordered key value pairs where each key is unique.

MongoDB

Make sure to use the official golang mongo driver:

- - + + \ No newline at end of file diff --git a/docs/tags/go-intermediate.html b/docs/tags/go-intermediate.html index 3ba887a..cf90ea9 100644 --- a/docs/tags/go-intermediate.html +++ b/docs/tags/go-intermediate.html @@ -9,13 +9,13 @@ - - + +

One doc tagged with "Go Intermediate"

View All Tags
- - + + \ No newline at end of file diff --git a/docs/tags/go.html b/docs/tags/go.html index 0cbc173..d079d1f 100644 --- a/docs/tags/go.html +++ b/docs/tags/go.html @@ -9,13 +9,13 @@ - - + +

One doc tagged with "go"

View All Tags
- - + + \ No newline at end of file diff --git a/docs/tags/javascript.html b/docs/tags/javascript.html index 75759d9..2d97d41 100644 --- a/docs/tags/javascript.html +++ b/docs/tags/javascript.html @@ -9,13 +9,13 @@ - - + +

One doc tagged with "javascript"

View All Tags
- - + + \ No newline at end of file diff --git a/docs/tags/overview.html b/docs/tags/overview.html index 4b63f08..19a01d8 100644 --- a/docs/tags/overview.html +++ b/docs/tags/overview.html @@ -9,13 +9,13 @@ - - + +

One doc tagged with "overview"

View All Tags

Stack

Our frontend stack is permanently changing as the underlying eco system does. We are trying to adopt technologies at the "Slope of Enlightenment" in the hype cycle.

- - + + \ No newline at end of file diff --git a/docs/tags/sse.html b/docs/tags/sse.html index 1826c63..892ffb4 100644 --- a/docs/tags/sse.html +++ b/docs/tags/sse.html @@ -9,13 +9,13 @@ - - + +

One doc tagged with "sse"

View All Tags
- - + + \ No newline at end of file diff --git a/etc/imprint.html b/etc/imprint.html index a5d82ea..7c8315d 100644 --- a/etc/imprint.html +++ b/etc/imprint.html @@ -9,8 +9,8 @@ - - + +
@@ -22,7 +22,7 @@ E-Mail: Haftung für Inhalte

Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.

Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.

Quellenangaben: Disclaimer eRecht24 - https://www.e-recht24.de/muster-disclaimer.html

Website-Design, Texte, Grafiken und Layout Copyright © 1998 - today bestbytes. ALLE RECHTE VORBEHALTEN. Das Kopieren oder die Reproduktion der gesamten Website bzw. von Teilen dieser Website ist untersagt, es sei denn, bestbytes hat dem vorher schriftlich oder elektronisch zugestimmt. Alle Markenzeichen und Logos, die auf dieser Internetseite verwendet werden, sind urheberrechtlich geschützt.

- - + + \ No newline at end of file diff --git a/index.html b/index.html index aea7821..be7593c 100644 --- a/index.html +++ b/index.html @@ -9,13 +9,13 @@ - - + +

foomo project docs

Stuff we wrote, because nobody else wanted to


foomo is an open source project, that has been maintained by the bestbytes team since 2011. It provides a wide range of utilities, libraries and daemons, that help us to tackle challenging projects.

foomo can help, if you are

  • using Go to write services
  • building frontends with TypeScript and Next.js
  • running your software on k8s
  • looking for a solution to deeply integrate your frontends with a headless cms
If more than two points apply, it will actually help a LOT

General guides

no matter if frontend or backend - there is somtehing for everyone in here

Frontend guides

Build frontends with TypeScript, Next.js, styled components, gotsrpc

Backend guides

Write fast and reliable services in Go and run them in the cloud

Projects

Foomo projects - libraries, utilities, friendly daemons and more

CMS

foomo has extensive support for headless CMS Systems

Architecture

Show me the big picture - how does foomo integrate into the k8s and Next.js eco system

Awesome Software

a curated list of software we use in the cloud, on our desktops and our devices

DevOps

our approach to run cloud native applications where they belong

Blog

random information about programming, our ecosystem and misc fun topics

- - + + \ No newline at end of file diff --git a/search.html b/search.html index ab483b5..ab3d3ab 100644 --- a/search.html +++ b/search.html @@ -9,13 +9,13 @@ - - + + - - + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 3f41ec7..72cb050 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://www.foomo.org/awesome-softwareweekly0.5https://www.foomo.org/blogweekly0.5https://www.foomo.org/blog/archiveweekly0.5https://www.foomo.org/blog/debugging-go-map-races-in-k8sweekly0.5https://www.foomo.org/blog/impact-of-3rd-party-scripts-on-performanceweekly0.5https://www.foomo.org/blog/prometheus-cardinality-issuesweekly0.5https://www.foomo.org/blog/searching-for-search-enginesweekly0.5https://www.foomo.org/blog/tagsweekly0.5https://www.foomo.org/blog/tags/backendweekly0.5https://www.foomo.org/blog/tags/bundleweekly0.5https://www.foomo.org/blog/tags/bundle-sizeweekly0.5https://www.foomo.org/blog/tags/cardinalityweekly0.5https://www.foomo.org/blog/tags/debuggingweekly0.5https://www.foomo.org/blog/tags/devopsweekly0.5https://www.foomo.org/blog/tags/foomoweekly0.5https://www.foomo.org/blog/tags/frontendweekly0.5https://www.foomo.org/blog/tags/goweekly0.5https://www.foomo.org/blog/tags/javascriptweekly0.5https://www.foomo.org/blog/tags/k-8-sweekly0.5https://www.foomo.org/blog/tags/memoryweekly0.5https://www.foomo.org/blog/tags/oomweekly0.5https://www.foomo.org/blog/tags/opsweekly0.5https://www.foomo.org/blog/tags/performanceweekly0.5https://www.foomo.org/blog/tags/prometheusweekly0.5https://www.foomo.org/blog/tags/searchweekly0.5https://www.foomo.org/blog/tags/search-engineweekly0.5https://www.foomo.org/blog/welcome-back-2021weekly0.5https://www.foomo.org/blog/why-bundle-size-is-importantweekly0.5https://www.foomo.org/docs/tagsweekly0.5https://www.foomo.org/docs/tags/frontendweekly0.5https://www.foomo.org/docs/tags/goweekly0.5https://www.foomo.org/docs/tags/go-basicsweekly0.5https://www.foomo.org/docs/tags/go-intermediateweekly0.5https://www.foomo.org/docs/tags/javascriptweekly0.5https://www.foomo.org/docs/tags/overviewweekly0.5https://www.foomo.org/docs/tags/sseweekly0.5https://www.foomo.org/etc/imprintweekly0.5https://www.foomo.org/searchweekly0.5https://www.foomo.org/docs/backend/go-by-example/cli-applicationsweekly0.5https://www.foomo.org/docs/backend/go-by-example/contextweekly0.5https://www.foomo.org/docs/backend/go-by-example/deferweekly0.5https://www.foomo.org/docs/backend/go-by-example/embedweekly0.5https://www.foomo.org/docs/backend/go-by-example/filesweekly0.5https://www.foomo.org/docs/backend/go-by-example/goroutines-and-channelsweekly0.5https://www.foomo.org/docs/backend/go-by-example/httpweekly0.5https://www.foomo.org/docs/backend/go-by-example/interfacesweekly0.5https://www.foomo.org/docs/backend/go-by-example/map-racingweekly0.5https://www.foomo.org/docs/backend/go-by-example/mongodbweekly0.5https://www.foomo.org/docs/backend/go-by-example/nil-mapsweekly0.5https://www.foomo.org/docs/backend/go-by-example/panic-and-recoverweekly0.5https://www.foomo.org/docs/backend/go-by-example/rangingweekly0.5https://www.foomo.org/docs/backend/go-by-example/reflectionweekly0.5https://www.foomo.org/docs/backend/go-by-example/type-castingweekly0.5https://www.foomo.org/docs/backend/go-by-example/yaml-magicweekly0.5https://www.foomo.org/docs/backend/gograppleweekly0.5https://www.foomo.org/docs/backend/introweekly0.5https://www.foomo.org/docs/backend/rtfmweekly0.5https://www.foomo.org/docs/backend/setupweekly0.5https://www.foomo.org/docs/devops/bookmarksweekly0.5https://www.foomo.org/docs/devops/infrastructure/conventionsweekly0.5https://www.foomo.org/docs/devops/introweekly0.5https://www.foomo.org/docs/devops/k8sweekly0.5https://www.foomo.org/docs/devops/kubernetes/spot-instance-node-poolsweekly0.5https://www.foomo.org/docs/devops/monitoring/grafanaweekly0.5https://www.foomo.org/docs/devops/monitoring/introweekly0.5https://www.foomo.org/docs/devops/monitoring/jaegerweekly0.5https://www.foomo.org/docs/frontend/cssweekly0.5https://www.foomo.org/docs/frontend/debugging_jsweekly0.5https://www.foomo.org/docs/frontend/introweekly0.5https://www.foomo.org/docs/frontend/performanceweekly0.5https://www.foomo.org/docs/frontend/pitfallsweekly0.5https://www.foomo.org/docs/frontend/rtfmweekly0.5https://www.foomo.org/docs/frontend/setupweekly0.5https://www.foomo.org/docs/frontend/stackweekly0.5https://www.foomo.org/docs/frontend/typescript/objectsweekly0.5https://www.foomo.org/docs/frontend/typescript/spreadingweekly0.5https://www.foomo.org/docs/frontend/vscodeweekly0.5https://www.foomo.org/docs/general/essentialsweekly0.5https://www.foomo.org/docs/general/introweekly0.5https://www.foomo.org/docs/general/package-managersweekly0.5https://www.foomo.org/docs/general/securityweekly0.5https://www.foomo.org/docs/general/setup/computerweekly0.5https://www.foomo.org/docs/general/setup/workplaceweekly0.5https://www.foomo.org/docs/general/technologies/sseweekly0.5https://www.foomo.org/docs/general/utilities/k9sweekly0.5https://www.foomo.org/docs/general/work/generalweekly0.5https://www.foomo.org/docs/general/work/remote-workweekly0.5https://www.foomo.org/docs/project-management/introweekly0.5https://www.foomo.org/docs/project-management/responsibilityweekly0.5https://www.foomo.org/docs/projects/architectureweekly0.5https://www.foomo.org/docs/projects/cms/contentfulweekly0.5https://www.foomo.org/docs/projects/cms/contentserverweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/api-referenceweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/cachingweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/getting-startedweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/introductionweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/test-apiweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/working-with-gocontentful-apiweekly0.5https://www.foomo.org/docs/projects/cms/introweekly0.5https://www.foomo.org/docs/projects/gotsrpcweekly0.5https://www.foomo.org/docs/projects/introweekly0.5https://www.foomo.org/docs/projects/libraries/keelweekly0.5https://www.foomo.org/docs/projects/libraries/keel-circuit-breakerweekly0.5https://www.foomo.org/docs/projects/pagespeed-exporterweekly0.5https://www.foomo.org/docs/projects/site-reliabilityweekly0.5https://www.foomo.org/docs/projects/utilities/gograppleweekly0.5https://www.foomo.org/docs/projects/webgrappleweekly0.5https://www.foomo.org/weekly0.5 \ No newline at end of file +https://www.foomo.org/awesome-softwareweekly0.5https://www.foomo.org/blogweekly0.5https://www.foomo.org/blog/accuracy-of-decimal-computationsweekly0.5https://www.foomo.org/blog/archiveweekly0.5https://www.foomo.org/blog/debugging-go-map-races-in-k8sweekly0.5https://www.foomo.org/blog/impact-of-3rd-party-scripts-on-performanceweekly0.5https://www.foomo.org/blog/prometheus-cardinality-issuesweekly0.5https://www.foomo.org/blog/searching-for-search-enginesweekly0.5https://www.foomo.org/blog/tagsweekly0.5https://www.foomo.org/blog/tags/backendweekly0.5https://www.foomo.org/blog/tags/bundleweekly0.5https://www.foomo.org/blog/tags/bundle-sizeweekly0.5https://www.foomo.org/blog/tags/cardinalityweekly0.5https://www.foomo.org/blog/tags/currencyweekly0.5https://www.foomo.org/blog/tags/debuggingweekly0.5https://www.foomo.org/blog/tags/decimal-accuracyweekly0.5https://www.foomo.org/blog/tags/devopsweekly0.5https://www.foomo.org/blog/tags/foomoweekly0.5https://www.foomo.org/blog/tags/frontendweekly0.5https://www.foomo.org/blog/tags/goweekly0.5https://www.foomo.org/blog/tags/golangweekly0.5https://www.foomo.org/blog/tags/javascriptweekly0.5https://www.foomo.org/blog/tags/k-8-sweekly0.5https://www.foomo.org/blog/tags/memoryweekly0.5https://www.foomo.org/blog/tags/oomweekly0.5https://www.foomo.org/blog/tags/opsweekly0.5https://www.foomo.org/blog/tags/performanceweekly0.5https://www.foomo.org/blog/tags/prometheusweekly0.5https://www.foomo.org/blog/tags/searchweekly0.5https://www.foomo.org/blog/tags/search-engineweekly0.5https://www.foomo.org/blog/welcome-back-2021weekly0.5https://www.foomo.org/blog/why-bundle-size-is-importantweekly0.5https://www.foomo.org/docs/tagsweekly0.5https://www.foomo.org/docs/tags/frontendweekly0.5https://www.foomo.org/docs/tags/goweekly0.5https://www.foomo.org/docs/tags/go-basicsweekly0.5https://www.foomo.org/docs/tags/go-intermediateweekly0.5https://www.foomo.org/docs/tags/javascriptweekly0.5https://www.foomo.org/docs/tags/overviewweekly0.5https://www.foomo.org/docs/tags/sseweekly0.5https://www.foomo.org/etc/imprintweekly0.5https://www.foomo.org/searchweekly0.5https://www.foomo.org/docs/backend/go-by-example/cli-applicationsweekly0.5https://www.foomo.org/docs/backend/go-by-example/contextweekly0.5https://www.foomo.org/docs/backend/go-by-example/deferweekly0.5https://www.foomo.org/docs/backend/go-by-example/embedweekly0.5https://www.foomo.org/docs/backend/go-by-example/filesweekly0.5https://www.foomo.org/docs/backend/go-by-example/goroutines-and-channelsweekly0.5https://www.foomo.org/docs/backend/go-by-example/httpweekly0.5https://www.foomo.org/docs/backend/go-by-example/interfacesweekly0.5https://www.foomo.org/docs/backend/go-by-example/map-racingweekly0.5https://www.foomo.org/docs/backend/go-by-example/mongodbweekly0.5https://www.foomo.org/docs/backend/go-by-example/nil-mapsweekly0.5https://www.foomo.org/docs/backend/go-by-example/panic-and-recoverweekly0.5https://www.foomo.org/docs/backend/go-by-example/rangingweekly0.5https://www.foomo.org/docs/backend/go-by-example/reflectionweekly0.5https://www.foomo.org/docs/backend/go-by-example/type-castingweekly0.5https://www.foomo.org/docs/backend/go-by-example/yaml-magicweekly0.5https://www.foomo.org/docs/backend/gograppleweekly0.5https://www.foomo.org/docs/backend/introweekly0.5https://www.foomo.org/docs/backend/rtfmweekly0.5https://www.foomo.org/docs/backend/setupweekly0.5https://www.foomo.org/docs/devops/bookmarksweekly0.5https://www.foomo.org/docs/devops/infrastructure/conventionsweekly0.5https://www.foomo.org/docs/devops/introweekly0.5https://www.foomo.org/docs/devops/k8sweekly0.5https://www.foomo.org/docs/devops/kubernetes/spot-instance-node-poolsweekly0.5https://www.foomo.org/docs/devops/monitoring/grafanaweekly0.5https://www.foomo.org/docs/devops/monitoring/introweekly0.5https://www.foomo.org/docs/devops/monitoring/jaegerweekly0.5https://www.foomo.org/docs/frontend/cssweekly0.5https://www.foomo.org/docs/frontend/debugging_jsweekly0.5https://www.foomo.org/docs/frontend/introweekly0.5https://www.foomo.org/docs/frontend/performanceweekly0.5https://www.foomo.org/docs/frontend/pitfallsweekly0.5https://www.foomo.org/docs/frontend/rtfmweekly0.5https://www.foomo.org/docs/frontend/setupweekly0.5https://www.foomo.org/docs/frontend/stackweekly0.5https://www.foomo.org/docs/frontend/typescript/objectsweekly0.5https://www.foomo.org/docs/frontend/typescript/spreadingweekly0.5https://www.foomo.org/docs/frontend/vscodeweekly0.5https://www.foomo.org/docs/general/essentialsweekly0.5https://www.foomo.org/docs/general/introweekly0.5https://www.foomo.org/docs/general/package-managersweekly0.5https://www.foomo.org/docs/general/securityweekly0.5https://www.foomo.org/docs/general/setup/computerweekly0.5https://www.foomo.org/docs/general/setup/workplaceweekly0.5https://www.foomo.org/docs/general/technologies/sseweekly0.5https://www.foomo.org/docs/general/utilities/k9sweekly0.5https://www.foomo.org/docs/general/work/generalweekly0.5https://www.foomo.org/docs/general/work/remote-workweekly0.5https://www.foomo.org/docs/project-management/introweekly0.5https://www.foomo.org/docs/project-management/responsibilityweekly0.5https://www.foomo.org/docs/projects/architectureweekly0.5https://www.foomo.org/docs/projects/cms/contentfulweekly0.5https://www.foomo.org/docs/projects/cms/contentserverweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/api-referenceweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/cachingweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/getting-startedweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/introductionweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/test-apiweekly0.5https://www.foomo.org/docs/projects/cms/gocontentful/working-with-gocontentful-apiweekly0.5https://www.foomo.org/docs/projects/cms/introweekly0.5https://www.foomo.org/docs/projects/gotsrpcweekly0.5https://www.foomo.org/docs/projects/introweekly0.5https://www.foomo.org/docs/projects/libraries/keelweekly0.5https://www.foomo.org/docs/projects/libraries/keel-circuit-breakerweekly0.5https://www.foomo.org/docs/projects/pagespeed-exporterweekly0.5https://www.foomo.org/docs/projects/site-reliabilityweekly0.5https://www.foomo.org/docs/projects/utilities/gograppleweekly0.5https://www.foomo.org/docs/projects/webgrappleweekly0.5https://www.foomo.org/weekly0.5 \ No newline at end of file