diff --git a/404.html b/404.html index 6eba684..c4e5b10 100644 --- a/404.html +++ b/404.html @@ -7,13 +7,13 @@ Page Not Found | foomo project docs - +
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/js/f768d962.7067cd04.js b/assets/js/f768d962.7067cd04.js deleted file mode 100644 index 4927b46..0000000 --- a/assets/js/f768d962.7067cd04.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[9196],{3905:function(e,t,r){r.d(t,{Zo:function(){return p},kt:function(){return m}});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=u(e,["components","mdxType","originalType","parentName"]),f=c(r),m=o,d=f["".concat(l,".").concat(m)]||f[m]||s[m]||a;return r?n.createElement(d,i(i({ref:t},p),{},{components:r})):n.createElement(d,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var u={};for(var l in t)hasOwnProperty.call(t,l)&&(u[l]=t[l]);u.originalType=e,u.mdxType="string"==typeof e?e:o,i[1]=u;for(var c=2;c=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=u(e,["components","mdxType","originalType","parentName"]),m=p(r),d=o,f=m["".concat(l,".").concat(d)]||m[d]||s[d]||a;return r?n.createElement(f,i(i({ref:t},c),{},{components:r})):n.createElement(f,i({ref:t},c))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var u={};for(var l in t)hasOwnProperty.call(t,l)&&(u[l]=t[l]);u.originalType=e,u.mdxType="string"==typeof e?e:o,i[1]=u;for(var p=2;p=d)&&Object.keys(b.O).every((function(e){return b.O[e](f[r])}))?f.splice(r--,1):(n=!1,d0&&e[u-1][2]>d;u--)e[u]=e[u-1];e[u]=[f,a,d]},b.n=function(e){var c=e&&e.__esModule?function(){return e.default}:function(){return e};return b.d(c,{a:c}),c},f=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},b.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var d=Object.create(null);b.r(d);var t={};c=c||[null,f({}),f([]),f(f)];for(var n=2&a&&e;"object"==typeof n&&!~c.indexOf(n);n=f(n))Object.getOwnPropertyNames(n).forEach((function(c){t[c]=function(){return e[c]}}));return t.default=function(){return e},b.d(d,t),d},b.d=function(e,c){for(var f in c)b.o(c,f)&&!b.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:c[f]})},b.f={},b.e=function(e){return Promise.all(Object.keys(b.f).reduce((function(c,f){return b.f[f](e,c),c}),[]))},b.u=function(e){return"assets/js/"+({53:"935f2afb",206:"43dc0045",405:"8047a11d",533:"b2b675dd",801:"2b6f3ca6",899:"b8302cf9",1064:"a8a1ab13",1213:"559c04ef",1435:"26ea2a44",1477:"b2f554cd",1713:"a7023ddc",1880:"bee3f77a",1911:"1aa4b20d",2078:"d1323eba",2233:"3352bb21",2302:"7c1f10d1",2364:"f12ae7d6",2416:"395ebfc6",2423:"87b8e9c4",2471:"866d8221",2535:"814f3328",2648:"0606a637",2672:"ac94ec9c",2833:"9a50dba7",2880:"ba52226f",3085:"1f391b9e",3089:"a6aa9e1f",3181:"c99de435",3223:"4c37729a",3237:"1df93b7f",3363:"c00dc5e0",3411:"78a933e5",3608:"9e4087bc",3626:"8139c962",3751:"3720c009",3866:"c6d1405e",3899:"99bb4438",3969:"c1acf0e3",4013:"01a85c17",4033:"a15e8276",4121:"55960ee5",4170:"beea6c26",4195:"b3d5163b",4491:"c6f71f2b",4574:"36213d62",4622:"29f10043",4742:"f0d1e73f",4761:"02493ab9",4859:"f7d870b9",4894:"5d6cc085",5211:"6a670c2a",5260:"45c436a9",5398:"d9c065e5",5408:"e25ea6ac",5500:"7071e909",5709:"5e9fc3ef",5791:"3338c0e0",5817:"e35f371e",5839:"7fdf1619",5867:"feda6906",5900:"35b210c0",5902:"f1808d3f",6009:"cd2041f2",6073:"72cf7f21",6081:"9e4ef427",6083:"146489e7",6103:"ccc49370",6222:"4ec6c0ec",6227:"5039a037",6465:"c3ad09c3",6487:"d7c843b2",6512:"b59d5feb",6579:"2cb19d2e",6582:"c2b2df4f",6660:"04056cce",6788:"050cf89e",6840:"5f154b3e",7027:"70617f54",7183:"cce78ecb",7355:"dd79439c",7533:"3b233ea0",7566:"0911540a",7602:"66aa330a",7659:"fc3deafd",7696:"2b793916",7785:"3d3976a7",7918:"17896441",7958:"4d194efc",8423:"12623ccc",8495:"0a5fa0dd",8503:"8077e178",8610:"6875c492",8666:"b0751d67",8735:"37e97a4e",8868:"f11ea25e",9116:"e62c5aa0",9196:"f768d962",9514:"1be78505",9543:"1b3e71b9",9746:"78460e70",9924:"df203c0f"}[e]||e)+"."+{53:"46bd8175",206:"467764a2",405:"755508ed",533:"f2a000a1",801:"50feec02",831:"f853ed42",899:"cefdb98e",1064:"489cc9ab",1213:"297c1867",1435:"81d24c57",1477:"c833b075",1713:"e8b09d8a",1880:"fcfe54e7",1911:"bc141a6f",2078:"1511095e",2233:"54e6102c",2302:"dc6edffb",2364:"e9d79601",2416:"12e14e7c",2423:"287a267b",2471:"901c740a",2535:"64b41501",2648:"226328e0",2672:"cf7d4283",2833:"8e2db19f",2880:"aabf92f8",3085:"612a1c5c",3089:"78e39833",3181:"439c87f4",3223:"ce7863ff",3237:"108ac62c",3363:"4b0947e7",3411:"fce2842b",3608:"2f2e19e1",3626:"b08a1760",3751:"8226915e",3866:"88b33387",3899:"4efc3c78",3969:"f08a316d",4013:"7d0034a3",4033:"4bf24eb1",4121:"9ef8ee8c",4170:"cb555b3c",4195:"f320ce24",4491:"4b0c206c",4574:"d07b30c0",4608:"e01af379",4622:"0e0358dd",4742:"f4f11b36",4761:"65b30b90",4773:"35fd21a1",4859:"f0746677",4894:"5729b9ea",5211:"ae6c49e2",5260:"66eb0372",5398:"35da157f",5408:"6949efbe",5500:"0607ec7f",5709:"37c23cb4",5791:"8358d78e",5817:"a0e2ba97",5839:"606f17ea",5867:"7bd6a2b4",5900:"e1207f0f",5902:"2c7246ee",6009:"7397c385",6073:"06e4fa59",6081:"3bbe91d9",6083:"292f8ca2",6103:"a543dd59",6222:"c17e0af0",6227:"d8dc4935",6465:"4176b8c9",6487:"a4fa1d70",6512:"e3dd92cd",6579:"7ea38433",6582:"68ace947",6660:"c415efdc",6788:"12b00b37",6840:"b1bee85d",6945:"30550d05",7027:"5ceba1c9",7183:"5b615186",7355:"d55b8b75",7533:"3cfcb579",7566:"799fdb1a",7602:"f6a99bac",7659:"79582d77",7696:"13262be8",7785:"4a2e13fe",7918:"648b34d3",7958:"fab83860",8423:"f1d74277",8495:"2de33e94",8503:"2da53a07",8576:"ff637482",8610:"debafd69",8666:"9471a0a1",8735:"0b478ffc",8868:"b186bcec",8894:"b472b857",9116:"b53cb1cf",9196:"7067cd04",9514:"6726295f",9543:"35bef058",9746:"f7040909",9924:"d9fb985e"}[e]+".js"},b.miniCssF=function(e){return"assets/css/styles.47738ace.css"},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=function(e,c){return Object.prototype.hasOwnProperty.call(e,c)},a={},d="foomo:",b.l=function(e,c,f,t){if(a[e])a[e].push(c);else{var n,r;if(void 0!==f)for(var o=document.getElementsByTagName("script"),u=0;u=d)&&Object.keys(b.O).every((function(e){return b.O[e](f[r])}))?f.splice(r--,1):(n=!1,d0&&e[u-1][2]>d;u--)e[u]=e[u-1];e[u]=[f,a,d]},b.n=function(e){var c=e&&e.__esModule?function(){return e.default}:function(){return e};return b.d(c,{a:c}),c},f=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},b.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var d=Object.create(null);b.r(d);var t={};c=c||[null,f({}),f([]),f(f)];for(var n=2&a&&e;"object"==typeof n&&!~c.indexOf(n);n=f(n))Object.getOwnPropertyNames(n).forEach((function(c){t[c]=function(){return e[c]}}));return t.default=function(){return e},b.d(d,t),d},b.d=function(e,c){for(var f in c)b.o(c,f)&&!b.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:c[f]})},b.f={},b.e=function(e){return Promise.all(Object.keys(b.f).reduce((function(c,f){return b.f[f](e,c),c}),[]))},b.u=function(e){return"assets/js/"+({53:"935f2afb",206:"43dc0045",405:"8047a11d",533:"b2b675dd",801:"2b6f3ca6",899:"b8302cf9",1064:"a8a1ab13",1213:"559c04ef",1435:"26ea2a44",1477:"b2f554cd",1713:"a7023ddc",1880:"bee3f77a",1911:"1aa4b20d",2078:"d1323eba",2233:"3352bb21",2302:"7c1f10d1",2364:"f12ae7d6",2416:"395ebfc6",2423:"87b8e9c4",2471:"866d8221",2535:"814f3328",2648:"0606a637",2672:"ac94ec9c",2833:"9a50dba7",2880:"ba52226f",3085:"1f391b9e",3089:"a6aa9e1f",3181:"c99de435",3223:"4c37729a",3237:"1df93b7f",3363:"c00dc5e0",3411:"78a933e5",3608:"9e4087bc",3626:"8139c962",3751:"3720c009",3866:"c6d1405e",3899:"99bb4438",3969:"c1acf0e3",4013:"01a85c17",4033:"a15e8276",4121:"55960ee5",4170:"beea6c26",4195:"b3d5163b",4491:"c6f71f2b",4574:"36213d62",4622:"29f10043",4742:"f0d1e73f",4761:"02493ab9",4859:"f7d870b9",4894:"5d6cc085",5211:"6a670c2a",5260:"45c436a9",5398:"d9c065e5",5408:"e25ea6ac",5500:"7071e909",5709:"5e9fc3ef",5791:"3338c0e0",5817:"e35f371e",5839:"7fdf1619",5867:"feda6906",5900:"35b210c0",5902:"f1808d3f",6009:"cd2041f2",6073:"72cf7f21",6081:"9e4ef427",6083:"146489e7",6103:"ccc49370",6222:"4ec6c0ec",6227:"5039a037",6465:"c3ad09c3",6487:"d7c843b2",6512:"b59d5feb",6579:"2cb19d2e",6582:"c2b2df4f",6660:"04056cce",6788:"050cf89e",6840:"5f154b3e",7027:"70617f54",7183:"cce78ecb",7355:"dd79439c",7533:"3b233ea0",7566:"0911540a",7602:"66aa330a",7659:"fc3deafd",7696:"2b793916",7785:"3d3976a7",7918:"17896441",7958:"4d194efc",8423:"12623ccc",8495:"0a5fa0dd",8503:"8077e178",8610:"6875c492",8666:"b0751d67",8735:"37e97a4e",8868:"f11ea25e",9116:"e62c5aa0",9196:"f768d962",9514:"1be78505",9543:"1b3e71b9",9746:"78460e70",9924:"df203c0f"}[e]||e)+"."+{53:"46bd8175",206:"467764a2",405:"755508ed",533:"f2a000a1",801:"50feec02",831:"f853ed42",899:"cefdb98e",1064:"489cc9ab",1213:"297c1867",1435:"81d24c57",1477:"c833b075",1713:"e8b09d8a",1880:"fcfe54e7",1911:"bc141a6f",2078:"1511095e",2233:"54e6102c",2302:"dc6edffb",2364:"e9d79601",2416:"12e14e7c",2423:"287a267b",2471:"901c740a",2535:"64b41501",2648:"226328e0",2672:"cf7d4283",2833:"8e2db19f",2880:"aabf92f8",3085:"612a1c5c",3089:"78e39833",3181:"439c87f4",3223:"ce7863ff",3237:"108ac62c",3363:"4b0947e7",3411:"fce2842b",3608:"2f2e19e1",3626:"b08a1760",3751:"8226915e",3866:"88b33387",3899:"4efc3c78",3969:"f08a316d",4013:"7d0034a3",4033:"4bf24eb1",4121:"9ef8ee8c",4170:"cb555b3c",4195:"f320ce24",4491:"4b0c206c",4574:"d07b30c0",4608:"e01af379",4622:"0e0358dd",4742:"f4f11b36",4761:"65b30b90",4773:"35fd21a1",4859:"f0746677",4894:"5729b9ea",5211:"ae6c49e2",5260:"66eb0372",5398:"35da157f",5408:"6949efbe",5500:"0607ec7f",5709:"37c23cb4",5791:"8358d78e",5817:"a0e2ba97",5839:"606f17ea",5867:"7bd6a2b4",5900:"e1207f0f",5902:"2c7246ee",6009:"7397c385",6073:"06e4fa59",6081:"3bbe91d9",6083:"292f8ca2",6103:"a543dd59",6222:"c17e0af0",6227:"d8dc4935",6465:"4176b8c9",6487:"a4fa1d70",6512:"e3dd92cd",6579:"7ea38433",6582:"68ace947",6660:"c415efdc",6788:"12b00b37",6840:"b1bee85d",6945:"30550d05",7027:"5ceba1c9",7183:"5b615186",7355:"d55b8b75",7533:"3cfcb579",7566:"799fdb1a",7602:"f6a99bac",7659:"79582d77",7696:"13262be8",7785:"4a2e13fe",7918:"648b34d3",7958:"fab83860",8423:"f1d74277",8495:"2de33e94",8503:"2da53a07",8576:"ff637482",8610:"debafd69",8666:"9471a0a1",8735:"0b478ffc",8868:"b186bcec",8894:"b472b857",9116:"b53cb1cf",9196:"ae667974",9514:"6726295f",9543:"35bef058",9746:"f7040909",9924:"d9fb985e"}[e]+".js"},b.miniCssF=function(e){return"assets/css/styles.47738ace.css"},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=function(e,c){return Object.prototype.hasOwnProperty.call(e,c)},a={},d="foomo:",b.l=function(e,c,f,t){if(a[e])a[e].push(c);else{var n,r;if(void 0!==f)for(var o=document.getElementsByTagName("script"),u=0;u foomo project docs - +

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 1b2060a..3bb1156 100644 --- a/blog.html +++ b/blog.html @@ -7,7 +7,7 @@ Blog | foomo project docs - + @@ -38,7 +38,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/archive.html b/blog/archive.html index 8ab9aa7..1438f62 100644 --- a/blog/archive.html +++ b/blog/archive.html @@ -7,13 +7,13 @@ Archive | foomo project docs - + - + \ No newline at end of file diff --git a/blog/debugging-go-map-races-in-k8s.html b/blog/debugging-go-map-races-in-k8s.html index f7b8c1a..142e4f0 100644 --- a/blog/debugging-go-map-races-in-k8s.html +++ b/blog/debugging-go-map-races-in-k8s.html @@ -7,13 +7,13 @@ debugging Go map races in k8s | foomo project docs - + - + \ 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 9510f69..69ce129 100644 --- a/blog/impact-of-3rd-party-scripts-on-performance.html +++ b/blog/impact-of-3rd-party-scripts-on-performance.html @@ -7,14 +7,14 @@ Impact of 3rd party scripts on performance | foomo project docs - +

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 f2f2252..4fd375d 100644 --- a/blog/prometheus-cardinality-issues.html +++ b/blog/prometheus-cardinality-issues.html @@ -7,7 +7,7 @@ Prometheus Is Out Of Memory. Again. | foomo project docs - + @@ -32,7 +32,7 @@ Or to quote user
/prometheus $ promtool tsdb analyze .

Which produced the result.

> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG
> Duration: 1h59m59.997s
> Series: 564171
> Label names: 285
> Postings (unique label pairs): 21139
> Postings entries (total label pairs): 6423664
>
> ...
>
> Highest cardinality metric names:
> 11340 haproxy_server_http_responses_total
> ...

We see the potential issue here, where the haproxy_server_http_responses_total metric is having a super-high cardinality which is growing. We need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.

... or burn it, up to you.

Flame Thrower

The Further Reading​

  1. WAL Definition
  2. WAL & Checkpoints
  3. Using TSDB
  4. Biggest Metrics
  5. Cardinality
- + \ No newline at end of file diff --git a/blog/searching-for-search-engines.html b/blog/searching-for-search-engines.html index dfaaff3..7e4209e 100644 --- a/blog/searching-for-search-engines.html +++ b/blog/searching-for-search-engines.html @@ -7,7 +7,7 @@ The never ending search a search engine 2022-01 edition | foomo project docs - + @@ -15,7 +15,7 @@

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 0b04722..294a144 100644 --- a/blog/tags.html +++ b/blog/tags.html @@ -7,13 +7,13 @@ Tags | foomo project docs - + - + \ No newline at end of file diff --git a/blog/tags/backend.html b/blog/tags/backend.html index dd9ea9e..8d3aad3 100644 --- a/blog/tags/backend.html +++ b/blog/tags/backend.html @@ -7,7 +7,7 @@ 2 posts tagged with "backend" | foomo project docs - + @@ -15,7 +15,7 @@

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 59b249d..b75c8dd 100644 --- a/blog/tags/bundle-size.html +++ b/blog/tags/bundle-size.html @@ -7,7 +7,7 @@ One post tagged with "bundle size" | foomo project docs - + @@ -16,7 +16,7 @@ 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 453ba6d..e998399 100644 --- a/blog/tags/bundle.html +++ b/blog/tags/bundle.html @@ -7,7 +7,7 @@ One post tagged with "bundle" | foomo project docs - + @@ -16,7 +16,7 @@ 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 0835781..38a2de2 100644 --- a/blog/tags/cardinality.html +++ b/blog/tags/cardinality.html @@ -7,7 +7,7 @@ One post tagged with "cardinality" | foomo project docs - + @@ -32,7 +32,7 @@ Or to quote user
/prometheus $ promtool tsdb analyze .

Which produced the result.

> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG
> Duration: 1h59m59.997s
> Series: 564171
> Label names: 285
> Postings (unique label pairs): 21139
> Postings entries (total label pairs): 6423664
>
> ...
>
> Highest cardinality metric names:
> 11340 haproxy_server_http_responses_total
> ...

We see the potential issue here, where the haproxy_server_http_responses_total metric is having a super-high cardinality which is growing. We need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.

... or burn it, up to you.

Flame Thrower

The Further Reading​

  1. WAL Definition
  2. WAL & Checkpoints
  3. Using TSDB
  4. Biggest Metrics
  5. Cardinality
- + \ No newline at end of file diff --git a/blog/tags/debugging.html b/blog/tags/debugging.html index 87d09b1..db9650f 100644 --- a/blog/tags/debugging.html +++ b/blog/tags/debugging.html @@ -7,13 +7,13 @@ One post tagged with "debugging" | foomo project docs - + - + \ No newline at end of file diff --git a/blog/tags/devops.html b/blog/tags/devops.html index 8fb6e19..7c31f76 100644 --- a/blog/tags/devops.html +++ b/blog/tags/devops.html @@ -7,7 +7,7 @@ One post tagged with "devops" | foomo project docs - + @@ -32,7 +32,7 @@ Or to quote user
/prometheus $ promtool tsdb analyze .

Which produced the result.

> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG
> Duration: 1h59m59.997s
> Series: 564171
> Label names: 285
> Postings (unique label pairs): 21139
> Postings entries (total label pairs): 6423664
>
> ...
>
> Highest cardinality metric names:
> 11340 haproxy_server_http_responses_total
> ...

We see the potential issue here, where the haproxy_server_http_responses_total metric is having a super-high cardinality which is growing. We need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.

... or burn it, up to you.

Flame Thrower

The Further Reading​

  1. WAL Definition
  2. WAL & Checkpoints
  3. Using TSDB
  4. Biggest Metrics
  5. Cardinality
- + \ No newline at end of file diff --git a/blog/tags/foomo.html b/blog/tags/foomo.html index 09c243e..167ae09 100644 --- a/blog/tags/foomo.html +++ b/blog/tags/foomo.html @@ -7,13 +7,13 @@ One post tagged with "foomo" | foomo project docs - +

One post tagged with "foomo"

View All Tags
- + \ No newline at end of file diff --git a/blog/tags/frontend.html b/blog/tags/frontend.html index 0831ea1..87d83ea 100644 --- a/blog/tags/frontend.html +++ b/blog/tags/frontend.html @@ -7,14 +7,14 @@ One post tagged with "frontend" | foomo project docs - +

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 d07215a..a6c974d 100644 --- a/blog/tags/go.html +++ b/blog/tags/go.html @@ -7,7 +7,7 @@ 2 posts tagged with "go" | foomo project docs - + @@ -15,7 +15,7 @@

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/javascript.html b/blog/tags/javascript.html index 4804973..82698c6 100644 --- a/blog/tags/javascript.html +++ b/blog/tags/javascript.html @@ -7,7 +7,7 @@ One post tagged with "javascript" | foomo project docs - + @@ -16,7 +16,7 @@ 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 05f8151..fc3f880 100644 --- a/blog/tags/k-8-s.html +++ b/blog/tags/k-8-s.html @@ -7,7 +7,7 @@ One post tagged with "k8s" | foomo project docs - + @@ -32,7 +32,7 @@ Or to quote user
/prometheus $ promtool tsdb analyze .

Which produced the result.

> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG
> Duration: 1h59m59.997s
> Series: 564171
> Label names: 285
> Postings (unique label pairs): 21139
> Postings entries (total label pairs): 6423664
>
> ...
>
> Highest cardinality metric names:
> 11340 haproxy_server_http_responses_total
> ...

We see the potential issue here, where the haproxy_server_http_responses_total metric is having a super-high cardinality which is growing. We need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.

... or burn it, up to you.

Flame Thrower

The Further Reading​

  1. WAL Definition
  2. WAL & Checkpoints
  3. Using TSDB
  4. Biggest Metrics
  5. Cardinality
- + \ No newline at end of file diff --git a/blog/tags/memory.html b/blog/tags/memory.html index 2b98f3a..c90cf6a 100644 --- a/blog/tags/memory.html +++ b/blog/tags/memory.html @@ -7,7 +7,7 @@ One post tagged with "memory" | foomo project docs - + @@ -32,7 +32,7 @@ Or to quote user
/prometheus $ promtool tsdb analyze .

Which produced the result.

> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG
> Duration: 1h59m59.997s
> Series: 564171
> Label names: 285
> Postings (unique label pairs): 21139
> Postings entries (total label pairs): 6423664
>
> ...
>
> Highest cardinality metric names:
> 11340 haproxy_server_http_responses_total
> ...

We see the potential issue here, where the haproxy_server_http_responses_total metric is having a super-high cardinality which is growing. We need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.

... or burn it, up to you.

Flame Thrower

The Further Reading​

  1. WAL Definition
  2. WAL & Checkpoints
  3. Using TSDB
  4. Biggest Metrics
  5. Cardinality
- + \ No newline at end of file diff --git a/blog/tags/oom.html b/blog/tags/oom.html index 04b6cf7..744cc17 100644 --- a/blog/tags/oom.html +++ b/blog/tags/oom.html @@ -7,7 +7,7 @@ One post tagged with "oom" | foomo project docs - + @@ -32,7 +32,7 @@ Or to quote user
/prometheus $ promtool tsdb analyze .

Which produced the result.

> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG
> Duration: 1h59m59.997s
> Series: 564171
> Label names: 285
> Postings (unique label pairs): 21139
> Postings entries (total label pairs): 6423664
>
> ...
>
> Highest cardinality metric names:
> 11340 haproxy_server_http_responses_total
> ...

We see the potential issue here, where the haproxy_server_http_responses_total metric is having a super-high cardinality which is growing. We need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.

... or burn it, up to you.

Flame Thrower

The Further Reading​

  1. WAL Definition
  2. WAL & Checkpoints
  3. Using TSDB
  4. Biggest Metrics
  5. Cardinality
- + \ No newline at end of file diff --git a/blog/tags/ops.html b/blog/tags/ops.html index e78f8c1..d17ec72 100644 --- a/blog/tags/ops.html +++ b/blog/tags/ops.html @@ -7,7 +7,7 @@ One post tagged with "ops" | foomo project docs - + @@ -32,7 +32,7 @@ Or to quote user
/prometheus $ promtool tsdb analyze .

Which produced the result.

> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG
> Duration: 1h59m59.997s
> Series: 564171
> Label names: 285
> Postings (unique label pairs): 21139
> Postings entries (total label pairs): 6423664
>
> ...
>
> Highest cardinality metric names:
> 11340 haproxy_server_http_responses_total
> ...

We see the potential issue here, where the haproxy_server_http_responses_total metric is having a super-high cardinality which is growing. We need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.

... or burn it, up to you.

Flame Thrower

The Further Reading​

  1. WAL Definition
  2. WAL & Checkpoints
  3. Using TSDB
  4. Biggest Metrics
  5. Cardinality
- + \ No newline at end of file diff --git a/blog/tags/performance.html b/blog/tags/performance.html index 2aba8ba..0171acc 100644 --- a/blog/tags/performance.html +++ b/blog/tags/performance.html @@ -7,14 +7,14 @@ One post tagged with "performance" | foomo project docs - +

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 b66a68d..c9cb6e3 100644 --- a/blog/tags/prometheus.html +++ b/blog/tags/prometheus.html @@ -7,7 +7,7 @@ One post tagged with "prometheus" | foomo project docs - + @@ -32,7 +32,7 @@ Or to quote user
/prometheus $ promtool tsdb analyze .

Which produced the result.

> Block ID: 01FT8E8YY4THHZ2S7C3G04GJMG
> Duration: 1h59m59.997s
> Series: 564171
> Label names: 285
> Postings (unique label pairs): 21139
> Postings entries (total label pairs): 6423664
>
> ...
>
> Highest cardinality metric names:
> 11340 haproxy_server_http_responses_total
> ...

We see the potential issue here, where the haproxy_server_http_responses_total metric is having a super-high cardinality which is growing. We need to deal with it, so that our prometheus instance can breathe again. In this particular case, the solution was updating the haproxy.

... or burn it, up to you.

Flame Thrower

The Further Reading​

  1. WAL Definition
  2. WAL & Checkpoints
  3. Using TSDB
  4. Biggest Metrics
  5. Cardinality
- + \ No newline at end of file diff --git a/blog/tags/search-engine.html b/blog/tags/search-engine.html index 8abd760..dba5e0c 100644 --- a/blog/tags/search-engine.html +++ b/blog/tags/search-engine.html @@ -7,7 +7,7 @@ One post tagged with "search-engine" | foomo project docs - + @@ -15,7 +15,7 @@

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 8344ced..62343f1 100644 --- a/blog/tags/search.html +++ b/blog/tags/search.html @@ -7,7 +7,7 @@ One post tagged with "search" | foomo project docs - + @@ -15,7 +15,7 @@

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 36eedfa..892183d 100644 --- a/blog/welcome-back-2021.html +++ b/blog/welcome-back-2021.html @@ -7,13 +7,13 @@ Relaunching foomo.org | foomo project docs - +

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 eb431ff..8503a11 100644 --- a/blog/why-bundle-size-is-important.html +++ b/blog/why-bundle-size-is-important.html @@ -7,7 +7,7 @@ Why bundle size is important? | foomo project docs - + @@ -16,7 +16,7 @@ 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/docs/backend/go-by-example/map-racing.html b/docs/backend/go-by-example/map-racing.html index 7ae8696..5ddfb27 100644 --- a/docs/backend/go-by-example/map-racing.html +++ b/docs/backend/go-by-example/map-racing.html @@ -7,13 +7,13 @@ map races | foomo project docs - + - + \ 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 17953d6..9d0abad 100644 --- a/docs/backend/go-by-example/nil-maps.html +++ b/docs/backend/go-by-example/nil-maps.html @@ -7,14 +7,14 @@ what you should now about nil maps | foomo project docs - +
- + \ 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 b6bdc3d..526684e 100644 --- a/docs/backend/go-by-example/panic-and-recover.html +++ b/docs/backend/go-by-example/panic-and-recover.html @@ -7,13 +7,13 @@ panic and recover | foomo project docs - + - + \ 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 1bf0725..9b5b83a 100644 --- a/docs/backend/go-by-example/ranging.html +++ b/docs/backend/go-by-example/ranging.html @@ -7,14 +7,14 @@ ranging and looping | foomo project docs - + - + \ 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 3a987e0..94ceded 100644 --- a/docs/backend/go-by-example/yaml-magic.html +++ b/docs/backend/go-by-example/yaml-magic.html @@ -7,14 +7,14 @@ yaml magic | foomo project docs - + - + \ No newline at end of file diff --git a/docs/backend/gograpple.html b/docs/backend/gograpple.html index 6d58580..579d89c 100644 --- a/docs/backend/gograpple.html +++ b/docs/backend/gograpple.html @@ -7,13 +7,13 @@ Gograpple | foomo project docs - + - + \ No newline at end of file diff --git a/docs/backend/intro.html b/docs/backend/intro.html index 7771572..626746f 100644 --- a/docs/backend/intro.html +++ b/docs/backend/intro.html @@ -7,14 +7,14 @@ building backend services with Go and foomo | foomo project docs - +
- + \ No newline at end of file diff --git a/docs/backend/rtfm.html b/docs/backend/rtfm.html index 9dabeda..e4413fa 100644 --- a/docs/backend/rtfm.html +++ b/docs/backend/rtfm.html @@ -7,13 +7,13 @@ External documentation resources | foomo project docs - + - + \ No newline at end of file diff --git a/docs/backend/setup.html b/docs/backend/setup.html index fef1055..d3c150d 100644 --- a/docs/backend/setup.html +++ b/docs/backend/setup.html @@ -7,13 +7,13 @@ setup your workspace | foomo project docs - + - + \ No newline at end of file diff --git a/docs/devops/bookmarks.html b/docs/devops/bookmarks.html index dc67a59..c8e582a 100644 --- a/docs/devops/bookmarks.html +++ b/docs/devops/bookmarks.html @@ -7,13 +7,13 @@ Bookmarks | foomo project docs - + - + \ No newline at end of file diff --git a/docs/devops/intro.html b/docs/devops/intro.html index 8214ff4..e9f88c8 100644 --- a/docs/devops/intro.html +++ b/docs/devops/intro.html @@ -7,13 +7,13 @@ How we run applications in the cloud | foomo project docs - + - + \ No newline at end of file diff --git a/docs/devops/k8s.html b/docs/devops/k8s.html index 3009f09..48a7753 100644 --- a/docs/devops/k8s.html +++ b/docs/devops/k8s.html @@ -7,13 +7,13 @@ k8s kubernetes | foomo project docs - + - + \ 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 b23f0e6..264c591 100644 --- a/docs/devops/kubernetes/spot-instance-node-pools.html +++ b/docs/devops/kubernetes/spot-instance-node-pools.html @@ -7,7 +7,7 @@ Spot Instance Node Pools | foomo project docs - + @@ -16,7 +16,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 979d1d0..a77c0f7 100644 --- a/docs/devops/monitoring/grafana.html +++ b/docs/devops/monitoring/grafana.html @@ -7,13 +7,13 @@ Grafana | foomo project docs - + - + \ No newline at end of file diff --git a/docs/devops/monitoring/intro.html b/docs/devops/monitoring/intro.html index 373c34d..41bfeda 100644 --- a/docs/devops/monitoring/intro.html +++ b/docs/devops/monitoring/intro.html @@ -7,13 +7,13 @@ Monitoring and Alerting | foomo project docs - + - + \ No newline at end of file diff --git a/docs/devops/monitoring/jaeger.html b/docs/devops/monitoring/jaeger.html index f300fff..14bfd3c 100644 --- a/docs/devops/monitoring/jaeger.html +++ b/docs/devops/monitoring/jaeger.html @@ -7,13 +7,13 @@ Jaeger | foomo project docs - + - + \ No newline at end of file diff --git a/docs/frontend/css.html b/docs/frontend/css.html index 42987ac..a5adfe0 100644 --- a/docs/frontend/css.html +++ b/docs/frontend/css.html @@ -7,13 +7,13 @@ CSS | foomo project docs - +
- + \ No newline at end of file diff --git a/docs/frontend/debugging_js.html b/docs/frontend/debugging_js.html index d099234..c29d4f8 100644 --- a/docs/frontend/debugging_js.html +++ b/docs/frontend/debugging_js.html @@ -7,13 +7,13 @@ Debugging in JavaScript | foomo project docs - +

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 9dd010a..9453d25 100644 --- a/docs/frontend/intro.html +++ b/docs/frontend/intro.html @@ -7,13 +7,13 @@ Frontend Guide | foomo project docs - +

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 746920b..13dc234 100644 --- a/docs/frontend/performance.html +++ b/docs/frontend/performance.html @@ -7,14 +7,14 @@ Performance | foomo project docs - +

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 f98e6c6..597acd0 100644 --- a/docs/frontend/pitfalls.html +++ b/docs/frontend/pitfalls.html @@ -7,13 +7,13 @@ Pitfalls | foomo project docs - +

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 c21ffb8..78822df 100644 --- a/docs/frontend/rtfm.html +++ b/docs/frontend/rtfm.html @@ -7,13 +7,13 @@ External documentation resources | foomo project docs - +

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 9a84da4..5e403a5 100644 --- a/docs/frontend/setup.html +++ b/docs/frontend/setup.html @@ -7,13 +7,13 @@ Setup | foomo project docs - +

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 eeaee68..246aba5 100644 --- a/docs/frontend/stack.html +++ b/docs/frontend/stack.html @@ -7,13 +7,13 @@ Stack | foomo project docs - +

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 10a6c1b..bcda404 100644 --- a/docs/frontend/typescript/objects.html +++ b/docs/frontend/typescript/objects.html @@ -7,7 +7,7 @@ Object declaration syntax in TypeScript | foomo project docs - + @@ -15,7 +15,7 @@
- + \ No newline at end of file diff --git a/docs/frontend/typescript/spreading.html b/docs/frontend/typescript/spreading.html index 511d160..14f8e90 100644 --- a/docs/frontend/typescript/spreading.html +++ b/docs/frontend/typescript/spreading.html @@ -7,7 +7,7 @@ Spreading | foomo project docs - + @@ -167,7 +167,7 @@ If you have a deeply nested object or array, nested entities will still hold a r } }
Result
Loading...
- + \ No newline at end of file diff --git a/docs/frontend/vscode.html b/docs/frontend/vscode.html index b50ce12..bf2964e 100644 --- a/docs/frontend/vscode.html +++ b/docs/frontend/vscode.html @@ -7,13 +7,13 @@ vscode | foomo project docs - +
- + \ No newline at end of file diff --git a/docs/general/essentials.html b/docs/general/essentials.html index a0c5bb7..2eccc17 100644 --- a/docs/general/essentials.html +++ b/docs/general/essentials.html @@ -7,13 +7,13 @@ (Random) essentials | foomo project docs - +

(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 5d17081..8a6ba66 100644 --- a/docs/general/intro.html +++ b/docs/general/intro.html @@ -7,13 +7,13 @@ General guide | foomo project docs - + - + \ No newline at end of file diff --git a/docs/general/package-managers.html b/docs/general/package-managers.html index 13de74f..a828ade 100644 --- a/docs/general/package-managers.html +++ b/docs/general/package-managers.html @@ -7,13 +7,13 @@ Package managers | foomo project docs - +

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 1155ab8..a2e6663 100644 --- a/docs/general/security.html +++ b/docs/general/security.html @@ -7,13 +7,13 @@ Security | foomo project docs - +

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 8f07554..4a77b70 100644 --- a/docs/general/setup/computer.html +++ b/docs/general/setup/computer.html @@ -7,13 +7,13 @@ Computer | foomo project docs - +
-

Setting up your computer

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

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 ;)

- +

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 ad3e438..e3f93df 100644 --- a/docs/general/setup/workplace.html +++ b/docs/general/setup/workplace.html @@ -7,13 +7,13 @@ Workplace | foomo project docs - +

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/utilities/k9s.html b/docs/general/utilities/k9s.html index 5daedcb..6df6262 100644 --- a/docs/general/utilities/k9s.html +++ b/docs/general/utilities/k9s.html @@ -7,13 +7,13 @@ k9s | foomo project docs - + - + \ No newline at end of file diff --git a/docs/general/work/general.html b/docs/general/work/general.html index 5aaab3e..e745b73 100644 --- a/docs/general/work/general.html +++ b/docs/general/work/general.html @@ -7,13 +7,13 @@ Working as a software developer | foomo project docs - +

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 486ee85..2003206 100644 --- a/docs/general/work/remote-work.html +++ b/docs/general/work/remote-work.html @@ -7,13 +7,13 @@ Working remotely | foomo project docs - +

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 3b06a20..72f0a4e 100644 --- a/docs/project-management/intro.html +++ b/docs/project-management/intro.html @@ -7,13 +7,13 @@ Project Managament | foomo project docs - +

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 d9ac1d7..a33be99 100644 --- a/docs/project-management/responsibility.html +++ b/docs/project-management/responsibility.html @@ -7,13 +7,13 @@ Responsibility | foomo project docs - + - + \ No newline at end of file diff --git a/docs/projects/architecture.html b/docs/projects/architecture.html index 5cf0b12..41b5b76 100644 --- a/docs/projects/architecture.html +++ b/docs/projects/architecture.html @@ -7,13 +7,13 @@ Architecture overview | foomo project docs - +

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 7f67d84..39d5140 100644 --- a/docs/projects/cms/contentful.html +++ b/docs/projects/cms/contentful.html @@ -7,13 +7,13 @@ contentful | foomo project docs - +
- + \ No newline at end of file diff --git a/docs/projects/cms/contentserver.html b/docs/projects/cms/contentserver.html index fb3504e..4bb39df 100644 --- a/docs/projects/cms/contentserver.html +++ b/docs/projects/cms/contentserver.html @@ -7,13 +7,13 @@ contentserver | foomo project docs - + - + \ No newline at end of file diff --git a/docs/projects/cms/intro.html b/docs/projects/cms/intro.html index 4a2dc7d..5788892 100644 --- a/docs/projects/cms/intro.html +++ b/docs/projects/cms/intro.html @@ -7,13 +7,13 @@ Intro | foomo project docs - +

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 fb9978f..d10cd9e 100644 --- a/docs/projects/gotsrpc.html +++ b/docs/projects/gotsrpc.html @@ -7,13 +7,13 @@ gotsrpc | foomo project docs - + - + \ No newline at end of file diff --git a/docs/projects/intro.html b/docs/projects/intro.html index bca79ac..b40baec 100644 --- a/docs/projects/intro.html +++ b/docs/projects/intro.html @@ -7,13 +7,13 @@ foomo project overview | foomo project docs - +

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.html b/docs/projects/libraries/keel.html index 849b3e1..b855d20 100644 --- a/docs/projects/libraries/keel.html +++ b/docs/projects/libraries/keel.html @@ -7,13 +7,13 @@ keel | foomo project docs - + - + \ No newline at end of file diff --git a/docs/projects/pagespeed-exporter.html b/docs/projects/pagespeed-exporter.html index 2db9163..48b1c84 100644 --- a/docs/projects/pagespeed-exporter.html +++ b/docs/projects/pagespeed-exporter.html @@ -7,13 +7,13 @@ pagespeed exporter | foomo project docs - + - + \ No newline at end of file diff --git a/docs/projects/site-reliability.html b/docs/projects/site-reliability.html index b51fbf8..302e970 100644 --- a/docs/projects/site-reliability.html +++ b/docs/projects/site-reliability.html @@ -7,13 +7,13 @@ Site reliability | foomo project docs - + - + \ No newline at end of file diff --git a/docs/projects/utilities/gograpple.html b/docs/projects/utilities/gograpple.html index ad0c3bc..026d526 100644 --- a/docs/projects/utilities/gograpple.html +++ b/docs/projects/utilities/gograpple.html @@ -7,13 +7,13 @@ gograpple | foomo project docs - + - + \ No newline at end of file diff --git a/docs/projects/webgrapple.html b/docs/projects/webgrapple.html index 730e01a..80c06a7 100644 --- a/docs/projects/webgrapple.html +++ b/docs/projects/webgrapple.html @@ -7,13 +7,13 @@ webgrapple | foomo project docs - + - + \ No newline at end of file diff --git a/docs/tags.html b/docs/tags.html index 4302de3..8f77acf 100644 --- a/docs/tags.html +++ b/docs/tags.html @@ -7,13 +7,13 @@ Tags | foomo project docs - + - + \ No newline at end of file diff --git a/docs/tags/frontend.html b/docs/tags/frontend.html index 35d8099..5176ca2 100644 --- a/docs/tags/frontend.html +++ b/docs/tags/frontend.html @@ -7,13 +7,13 @@ One doc tagged with "frontend" | foomo project docs - +

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/overview.html b/docs/tags/overview.html index d92844c..ceceea1 100644 --- a/docs/tags/overview.html +++ b/docs/tags/overview.html @@ -7,13 +7,13 @@ One doc tagged with "overview" | foomo project docs - +

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/etc/imprint.html b/etc/imprint.html index a541ac0..f0be421 100644 --- a/etc/imprint.html +++ b/etc/imprint.html @@ -7,7 +7,7 @@ foomo project docs - + @@ -20,7 +20,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 1902c1a..8d4c0ff 100644 --- a/index.html +++ b/index.html @@ -7,13 +7,13 @@ Hello from foomo project docs | foomo project docs - +

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 d2cbdaf..6c63754 100644 --- a/search.html +++ b/search.html @@ -7,13 +7,13 @@ Search the documentation | foomo project docs - +

Search the documentation

- + \ No newline at end of file