A place to cache linked articles (think custom and personal wayback machine)
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

index.html 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  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>
  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,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>React Is A Terrible Idea (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="https://www.pandastrike.com/posts/20150311-react-bad-idea">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. React Is A Terrible Idea (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="https://www.pandastrike.com/posts/20150311-react-bad-idea">Source originale du contenu</a></h3>
  445. <p>There&#39;s been a lot of excitement lately about React. React seems to have bumped Angular from the top of <a href="http://is.gd/wuZDbK">the hippest-framework mountain</a>. This is unfortunate, because both of these frameworks are <a href="https://news.ycombinator.com/item?id=9117028">bad for your application&#39;s health</a>. They&#39;re also bad for the entire software industry. For new applications, please, for the love of all things open, use <a href="http://webcomponents.org/">Web components</a> instead.</p>
  446. <p>React&#39;s design is bad. I could give you a lot of specifics—separation of concerns, coupling views with models, the focus on needless optimizations, the importance of supporting open standards—but I&#39;m going to tell you a story, instead. The story is about a startup with a popular product and lots of venture capital. This startup decided that they wanted to make their Web app extra special. Like many who came before them, they decided that HTML and CSS just weren&#39;t <em>quite</em> good enough for them.</p>
  447. <h2>The Wayward Startup</h2>
  448. <p>They went to a great deal of trouble to build their own rendering engine, using Canvas. And it worked! Their Web app was now extra special. However, as it turned out, the browser vendors were working on solving the very problems that had motivated this startup to write their own rendering engine. In fact, just two weeks after the startup announced their extra special rendering engine, a major browser release included a solution to one of the biggest problems of all.</p>
  449. <p>The startup is <a href="https://flipboard.com/">Flipboard</a>. The <a href="http://engineering.flipboard.com/2015/02/mobile-web/">major problem is smooth scrolling</a>, which <a href="https://www.mozilla.org/en-US/firefox/36.0/releasenotes/">just dropped in Firefox</a>. The framework they wrote is <a href="https://github.com/flipboard/react-canvas">React-Canvas</a>, which was largely motivated by the desire for smooth scrolling. Instead of contributing to various efforts to speed DOM rendering, Flipboard decided to write their own canvas-based rendering engine. Was it cool? Yes. Was it impressive? Yes. But was it wisely constructed? No. Instead of a solution everyone can benefit from, we have a solution you can only benefit from if you use React. Even if React was a good design (it&#39;s not), that&#39;s still severely limiting the potential audience.</p>
  450. <p>Panda Strike is not a mindless cult, of course. Some of us think it&#39;s silly to support 60 FPS animations so your users can look at magazines, aka static content. Some of us buy <a href="http://daringfireball.net/2015/02/60_frames_per_second_and_the_web">John Gruber&#39;s argument that iOS-level responsiveness is not really optional any more</a>. But we all agree the engineers at Flipboard are obviously very talented, and React Canvas might be useful to someone. And that it would have been better as a simple Canvas library, without being tightly coupled to React.</p>
  451. <h2>Every Innovation Does Not Need Its Own Framework</h2>
  452. <p>Internally, React depends on virtual DOM. The advantage over browser DOM is that virtual DOM nodes are relatively lightweight. You can create thousands of virtual DOM nodes without any performance impact on your application. Not only that, but you can diff virtual DOM trees and get a patch that can be applied to the actual browser DOM. That seems like it might, indeed, be handy. But what has that got to do with reactive programming? Or embedding markup in JavaScript?</p>
  453. <p>Nothing. As proof, I submit to you this <a href="https://github.com/Matt-Esch/virtual-dom">nice, stand-alone virtual DOM implementation</a>. Here&#39;s what the authors said about <a href="https://gist.github.com/Raynos/8414846">why they wrote a stand-alone version</a>:</p>
  454. <blockquote>
  455. <p>One important part of the virtual DOM approach is that it is a
  456. <strong>module</strong> and it <strong>should do one thing well</strong>. The virtual DOM
  457. is only concerned with representing the virtual DOM. The <code>diff</code>
  458. <code>batch</code> and <code>patch</code> functions are only concerned with the
  459. relevant algorithms for the virtual dom.</p>
  460. <p>The virtual DOM has nothing to do with events or representing
  461. application state. The below example demonstrates the usage
  462. of state with <code>observ</code> and events with <code>dom-delegator</code>. It
  463. could just as well have used <code>knockout</code> or <code>backbone</code> for state
  464. and used <code>jQuery</code> or <code>component/events</code> for events.</p>
  465. </blockquote>
  466. <p>The same things could be said of a Canvas-based rendering engine.</p>
  467. <h2>The Real Purpose of React</h2>
  468. <p>Even if Flipboard spent <a href="https://www.crunchbase.com/organization/flipboard">all their venture capital</a> on improving the rendering engines in browsers, they couldn&#39;t spend nearly as much as Facebook is capable of. Whatever sins of misplaced enthusiasm Flipboard may have committed, Facebook has committed tenfold with React. What if, instead of promoting an open source framework that only benefits applications that adopt it, they instead put their efforts into making open source browsers better?</p>
  469. <p>They won&#39;t do this, though, because it isn&#39;t in their interest to do so. You may recall <a href="http://techcrunch.com/2012/09/11/mark-zuckerberg-our-biggest-mistake-with-mobile-was-betting-too-much-on-html5/">Facebook&#39;s abrupt about-face on their mobile app</a> back in 2012, when Mark Zuckerberg said building on HTML5 was his company&#39;s &quot;biggest mistake.&quot; What you may not recall was <a href="http://www.sencha.com/blog/the-making-of-fastbook-an-html5-love-story/">Sencha took this claim as a challenge, and built a great HTML5 implementation of the same app</a>, effectively demonstrating that Facebook&#39;s criticisms of HTML5 were largely unfounded. Unlike Google, whose revenue largely depends on their search engine–which, in turn, depends on people using the Web for everything–Facebook has <a href="http://www.theverge.com/2015/1/4/7488495/facebook-is-the-new-aol">always benefited from being a walled garden</a>. Put another way, Facebook doesn&#39;t care if you use the Web, it only cares that you use Facebook.</p>
  470. <p>So why release an open source Web framework at all? Because <a href="http://www.thewire.com/technology/2014/07/inside-the-ugly-recruitment-battle-between-facebook-and-google/374386/">Facebook is battling Google for engineers</a>. So you&#39;ve got a big fight between two companies over which company is the coolest place to work, and both of them are companies that your grandparents love. How are you going to win this fight? One way is to have the hippest Web framework.</p>
  471. <p>Basically, both Google and Facebook are desperate to find a baseball cap
  472. that they can put on backwards. Angular is Google&#39;s baseball cap. React is
  473. Facebook&#39;s.</p>
  474. <p><img src="https://www.pandastrike.com/assets/images/web-surfin-time.gif"></p>
  475. <h2>The Open Web Is More Important Than You Think</h2>
  476. <p>Meanwhile, Web components are now available in Chrome and Firefox, with polyfills for older browsers. Web components are the biggest leap forward for the Open Web in years…and, yet, we&#39;re talking about React, a completely unnecessary framework. (Seriously, why not just introduce JSX and virtual DOM as separate libraries? And, as far as the data flow stuff goes, that&#39;s not even a new thing. People have been doing that for years.) This is bad, because the Open Web is important, and ten years ago, we nearly lost it.</p>
  477. <p>Today, Microsoft looks like a lost wildebeest, wandering the Saharan plains of failed products. But ten years ago, they were poised to own the Web. If you&#39;ve been in this business less than ten years, you might not realize how close we were to a world where the mobile Web would have required using Windows Phone. Don&#39;t believe me? <a href="http://en.wikipedia.org/wiki/United_States_v._Microsoft_Corp.">Microsoft was actually ruled to be a monopoly</a> in the United States, and <a href="http://money.cnn.com/2013/03/06/technology/microsoft-eu-fine/">is still dealing with the aftermath</a>. To this day, we still hear about the need to support Internet Explorer 8, which is the new Internet Explorer 6, a useless, bug-ridden weight that tied down the entire industry for nearly a decade. And the reason we&#39;re largely free of that weight today is the emergence of Firefox and WebKit.</p>
  478. <p>That didn&#39;t happen by accident.</p>
  479. <h2>How You Can Help</h2>
  480. <p>We have the luxury of complaining about “slow” rendering times in the DOM because we can take for granted a browser platform that is <a href="http://www.chromium.org/developers/calendar">improving faster than</a> <a href="https://hg.mozilla.org/releases/mozilla-release">we can even make use of the new features</a>. This includes <a href="http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome">major rendering improvements</a>. We don&#39;t need more workarounds; what we need is more investment in making the platform we have, whose very existence is a near-miracle, better. And you don&#39;t have to know C or iOS internals to be a part of that. All you have to do is make use of the platform.</p>
  481. <p>That&#39;s right. Just by using new innovations like Web components, instead of work-arounds like React, you&#39;re contributing to the success of the Open Web. You&#39;re voting with your code. With adoption comes community, and with community comes an ecosystem. In two years, we could have a Tower of Babel of recruiting-campaigns-posing-as-frameworks, or we could have an <a href="http://component.kitchen/components">ecosystem of reusable Web components</a>.</p>
  482. <p>The best part is that you don&#39;t have to compromise to get the benefits of Web components. Because they&#39;re actually a much better abstraction for building human-computer interfaces than anything React or Angular have to offer. What a lot of people don&#39;t realize is that components were implicit in MVC <a href="http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf">when it was first introduced</a>. They&#39;re also the basis of pretty much every other HCI platform ever, including iOS and Android. So it&#39;s not like we&#39;re talking about limiting ourselves by using Web components. Quite the contrary, Web components represent a far superior option.</p>
  483. <h2>React, Bad; Web Components, Good</h2>
  484. <p>A good framework supports separation of concerns. Web components do not impose a way of representing views or attaching event handlers or rendering to the DOM. A bad framework couples those things together so that you can&#39;t use one without the others. That&#39;s what React does.</p>
  485. <p>Sure, you can use JSX if you want, but that&#39;s the worst part of React anyway. JSX wants you to couple your view with the model and controller. It&#39;s a bad idea. Don&#39;t do that. Virtual DOM is great, if you need it, but you probably don&#39;t. And it was <a href="https://github.com/Matt-Esch/virtual-dom">thankfully FTFYd anyway</a>. React is not a good framework. And Web components aren&#39;t even a framework really, so much as <strong><em>how browsers work now</em></strong>. More generally, components are how pretty everything but the Web has worked for decades.</p>
  486. <p>The solution to the problems on the Web is never, ever going to be to tightly couple presentation, behavior, and data. Your Web apps will ultimately become unmaintainable hair balls of unreadable code. The solutions will come in the form of better Web browsers, and reusable components that <em>reduce</em> coupling instead of increasing it. In other words, they&#39;ll be based on best practices that have survived decades of evolution in the software industry. In the meantime, your best bet is typically going to be to use what works and focus on the problems you can do something about, without trying to reinvent the browser from inside the browser.</p>
  487. </article>
  488. </section>
  489. <nav id="jumpto">
  490. <p>
  491. <a href="/david/blog/">Accueil du blog</a> |
  492. <a href="https://www.pandastrike.com/posts/20150311-react-bad-idea">Source originale</a> |
  493. <a href="/david/stream/2019/">Accueil du flux</a>
  494. </p>
  495. </nav>
  496. <footer>
  497. <div>
  498. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  499. <p>
  500. Bonjour/Hi!
  501. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  502. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  503. </p>
  504. <p>
  505. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  506. </p>
  507. <p>
  508. Voici quelques articles choisis :
  509. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  510. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  511. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  512. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  513. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  514. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  515. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  516. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  517. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  518. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  519. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  520. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  521. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  522. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  523. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  524. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  525. </p>
  526. <p>
  527. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  528. </p>
  529. <p>
  530. Je ne traque pas ta navigation mais mon
  531. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  532. conserve des logs d’accès.
  533. </p>
  534. </div>
  535. </footer>
  536. <script type="text/javascript">
  537. ;(_ => {
  538. const jumper = document.getElementById('jumper')
  539. jumper.addEventListener('click', e => {
  540. e.preventDefault()
  541. const anchor = e.target.getAttribute('href')
  542. const targetEl = document.getElementById(anchor.substring(1))
  543. targetEl.scrollIntoView({behavior: 'smooth'})
  544. })
  545. })()
  546. </script>