A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>The (extremely) loud minority (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <meta name="robots" content="noindex, nofollow">
  53. <meta content="origin-when-cross-origin" name="referrer">
  54. <!-- Canonical URL for SEO purposes -->
  55. <link rel="canonical" href="https://andy-bell.co.uk/the-extremely-loud-minority/">
  56. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  57. <article>
  58. <header>
  59. <h1>The (extremely) loud minority</h1>
  60. </header>
  61. <nav>
  62. <p class="center">
  63. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  64. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  65. </svg> Accueil</a> •
  66. <a href="https://andy-bell.co.uk/the-extremely-loud-minority/" title="Lien vers le contenu original">Source originale</a>
  67. </p>
  68. </nav>
  69. <hr>
  70. <p>Often on Twitter, we’ll hear stuff like this:</p>
  71. <blockquote class="wp-block-quote">
  72. <p>Best practices don’t actually work</p>
  73. </blockquote>
  74. <p>Or: </p>
  75. <blockquote class="wp-block-quote">
  76. <p>TypeScript has won, and it’s only a matter of time you’re using it whether you like it or not.</p>
  77. </blockquote>
  78. <p>These may be true for a <em>tiny</em> minority of cases, such as in a code-factory: full of developers, independently working on small pieces of a very large product, but this doesn’t represent the web industry. In fact, the JS-driven cohort represents a <em>tiny</em> percentage of the web industry as a whole.</p>
  79. <p>How small is that percentage, though? I’m glad you asked. We’re going to be using data from <a href="https://w3techs.com/faq">W3Techs, who crawl the <strong>top 10 million websites</strong></a> to calculate what market share certain technologies have. For this example, I’ll compare WordPress with React and Vue, because if you didn’t look at the data, you’d think everyone was building with them, right? Absolutely wrong. </p>
  80. <blockquote class="wp-block-quote">
  81. <p>WordPress is used by 63.4% of all the websites whose content management system we know. This is <strong>43.1% of all websites</strong>.</p>
  82. <cite><a href="https://w3techs.com/technologies/details/cm-wordpress">W3Techs</a></cite></blockquote>
  83. <p>And to compare:</p>
  84. <blockquote class="wp-block-quote">
  85. <p>React is used by 4.0% of all the websites whose JavaScript library we know. <strong>This is 3.3% of all websites</strong>.</p>
  86. <cite><a href="https://w3techs.com/technologies/details/js-react">W3Techs</a></cite></blockquote>
  87. <p>And finally:</p>
  88. <blockquote class="wp-block-quote">
  89. <p>Vue.js is used by 0.9% of all the websites whose JavaScript library we know. <strong>This is 0.8% of all websites.</strong></p>
  90. <cite><a href="https://w3techs.com/technologies/details/js-vuejs">W3Techs</a></cite></blockquote>
  91. <p>Emphasis on both examples, mine and the data is accurate as of February 14th, 2023. Also worth mentioning that this is just one data source. You could merge various sources, but the difference between the majority of the web industry—AKA people slinging websites with WordPress etc—and the loud, but very small web industry is <strong>huge.</strong></p>
  92. <p>Even when you consider the reality that these technology paths likely cross and some sites hide the tech they are using, the difference is <em>extreme</em>. Even if you <a href="https://w3techs.com/technologies/comparison/js-react,js-vuejs">add together React and Vue</a>, it’s still <strong>less than 5% of all websites</strong>.</p>
  93. <p>It’s also worth caveating (for the sake of my mentions) that React and Vue usage doesn’t mean that we’re only talking about single page apps (SPAs). Those likely account for such a small percentage of the web, it’s barely worth counting. That percentage is likely going to fall now too, because the JavaScript community have seemingly finally woken up to the idea that SPAs are not good actually. <a href="https://infrequently.org/2022/12/performance-baseline-2023/">Shame about the decade we lost on them</a>…</p>
  94. <p>Just for fun, here’s React and Vue’s combined, rounded market share, visually represented by 100 people:</p>
  95. <p class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper"></p>
  96. <p>Now, here’s WordPress:</p>
  97. <p class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper"></p>
  98. <h2 id="heading-the-point-i-am-trying-to-make">The point I am trying to make</h2>
  99. <p>It’s understandable to think that JavaScript frameworks and their communities are eating the web because places like Twitter are <em>awash with very loud voices from said communities</em>.</p>
  100. <p>Always remember that although a <strong>subset of the JavaScript community</strong> can be <strong>very loud</strong>, they represent a <strong>paltry portion of the web as a whole</strong>. This means that when <em>they</em> say something like “Best practices don’t actually work”—what they mean is “Best practices don’t actually work for a small subset of less than 5 percent of the web”.</p>
  101. <p>Now when you look at it like that, it makes you wonder why we give these people such a large stage while the <em>very quiet</em> <strong>majority</strong> don’t get a voice at all. The very quiet majority are out there building more than 90% of the web, after all.</p>
  102. <p>Even a slight change in that dynamic would likely have a massive positive impact.</p>
  103. <hr class="wp-block-separator has-alpha-channel-opacity">
  104. <p><strong>Update</strong>: I just want to emphasise that W3Tech’s data is for the top 10 million websites. Based on that, React’s &lt; 4% share is probably microscopic on the web as a whole. Even if you discount that: considering React has been around for a decade now, &lt; 4% share of the top 10 million websites is <em>pathetic</em>, considering how much we are made to feel like it is the “biggest framework” (well, at least in bundle size, that’s true).</p>
  105. <p>Another point I want to address is the “well, the web is massive and old, so of course there are loads of WordPress sites”. This is very true, but WordPress keeps growing in popularity*! I’d accept that if its share was depleting. Also, again, all of the above is in reference to the top 10 million websites, which if React is as popular as it’s made out to be, it would feature a lot more prominently…</p>
  106. <p></p>
  107. <p>* based on when I last monitored this report for <a href="https://www.youtube.com/watch?v=8oMekThCB9k">my talk on CUBE CSS</a> when WordPress’ share was around 36%.</p>
  108. </article>
  109. <hr>
  110. <footer>
  111. <p>
  112. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  113. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  114. </svg> Accueil</a> •
  115. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  116. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  117. </svg> Suivre</a> •
  118. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  119. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  120. </svg> Pro</a> •
  121. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  122. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  123. </svg> Email</a> •
  124. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  125. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  126. </svg> Légal</abbr>
  127. </p>
  128. <template id="theme-selector">
  129. <form>
  130. <fieldset>
  131. <legend><svg class="icon icon-brightness-contrast">
  132. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  133. </svg> Thème</legend>
  134. <label>
  135. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  136. </label>
  137. <label>
  138. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  139. </label>
  140. <label>
  141. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  142. </label>
  143. </fieldset>
  144. </form>
  145. </template>
  146. </footer>
  147. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  148. <script>
  149. function loadThemeForm(templateName) {
  150. const themeSelectorTemplate = document.querySelector(templateName)
  151. const form = themeSelectorTemplate.content.firstElementChild
  152. themeSelectorTemplate.replaceWith(form)
  153. form.addEventListener('change', (e) => {
  154. const chosenColorScheme = e.target.value
  155. localStorage.setItem('theme', chosenColorScheme)
  156. toggleTheme(chosenColorScheme)
  157. })
  158. const selectedTheme = localStorage.getItem('theme')
  159. if (selectedTheme && selectedTheme !== 'undefined') {
  160. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  161. }
  162. }
  163. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  164. window.addEventListener('load', () => {
  165. let hasDarkRules = false
  166. for (const styleSheet of Array.from(document.styleSheets)) {
  167. let mediaRules = []
  168. for (const cssRule of styleSheet.cssRules) {
  169. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  170. continue
  171. }
  172. // WARNING: Safari does not have/supports `conditionText`.
  173. if (cssRule.conditionText) {
  174. if (cssRule.conditionText !== prefersColorSchemeDark) {
  175. continue
  176. }
  177. } else {
  178. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  179. continue
  180. }
  181. }
  182. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  183. }
  184. // WARNING: do not try to insert a Rule to a styleSheet you are
  185. // currently iterating on, otherwise the browser will be stuck
  186. // in a infinite loop…
  187. for (const mediaRule of mediaRules) {
  188. styleSheet.insertRule(mediaRule.cssText)
  189. hasDarkRules = true
  190. }
  191. }
  192. if (hasDarkRules) {
  193. loadThemeForm('#theme-selector')
  194. }
  195. })
  196. </script>
  197. </body>
  198. </html>