A place to cache linked articles (think custom and personal wayback machine)
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

index.html 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  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>Three takeaways for web developers after two weeks of painfully slow internet (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://medium.com/@zengabor/three-takeaways-for-web-developers-after-two-weeks-of-painfully-slow-internet-9e7f6d47726e">
  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. Three takeaways for web developers after two weeks of painfully slow internet (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://medium.com/@zengabor/three-takeaways-for-web-developers-after-two-weeks-of-painfully-slow-internet-9e7f6d47726e">Source originale du contenu</a></h3>
  445. <p name="c4c9" id="c4c9" class="graf--p graf--first">When we went to Hungary during the Christmas period last year I bought a 1GB data plan on a prepaid card. However, soon after I went online with my laptop the entire data allowance was used up. Strangely, I wasn’t able to add another data package. Instead, T-Mobile limited my internet access to 32kbps till the end of the month.</p>
  446. <p name="e4b7" id="e4b7" class="graf--p">Since there was no easy way to fix it and I had nothing critical to do I decided to embrace the situation as an opportunity to understand how it feels to be on a slow network most of the time. I had already started reading the book <a href="http://www.abookapart.com/products/responsible-responsive-design" data-href="http://www.abookapart.com/products/responsible-responsive-design" class="markup--anchor markup--p-anchor" rel="nofollow">Responsible Responsive Design</a> at that time anyway so I was curious.</p>
  447. <p name="5f24" id="5f24" class="graf--p">I learned a lot from this first-hand experience. I was mostly using the Twitter client <a href="http://tapbots.com/software/tweetbot/" data-href="http://tapbots.com/software/tweetbot/" class="markup--anchor markup--p-anchor" rel="nofollow">TweetBot</a> and its embedded browser for online reading. I had to be really patient. I learned to make up my mind whether I tap a link or a button, as it was quite expensive: I had to spend the next 1–2 minutes waiting for the web page to load. The psychology of limited internet would be a good topic for another story. Here let’s just concentrate on the key takeaways for makers of web sites, like me.</p>
  448. <p name="343f" id="343f" class="graf--p">Here’s the three most important things that I became aware of during this time as a web developer:</p>
  449. <p name="74ef" id="74ef" class="graf--p graf--empty"><br/></p>
  450. <h3 name="9910" id="9910" class="graf--h3">1. Some sites never loaded</h3>
  451. <p name="dfc5" id="dfc5" class="graf--p graf--empty"><br/></p>
  452. <p name="b0a2" id="b0a2" class="graf--p">While most sites worked slowly but otherwise okay, there were some pages that simply never loaded. I couldn’t believe it so I tried many times and left the phone loading for several minutes but all in vain. Nothing appeared on those pages. Unfortunately, I don’t remember which ones but I can’t help thinking that those were single-page JavaScript apps whose loading script wasn’t prepared for these conditions and timed out before the browser could receive something to display. (Good thing I could still use <a href="http://getpocket.com" data-href="http://getpocket.com" class="markup--anchor markup--p-anchor" rel="nofollow">Pocket</a> to store the URL if the topic sounded interesting.)</p>
  453. <h4 name="0378" id="0378" class="graf--h4">Takeaway 1: Develop in extra slow emulated mode</h4>
  454. <p name="010e" id="010e" class="graf--p graf--empty"><br/></p>
  455. <p name="c625" id="c625" class="graf--p">It’s critical to test the sites I am making on a very slow network from the beginning. Chrome has an amazing feature for that. If I open the web developer tools (⌥⌘I on a Mac, F12 on Windows) and make sure that “device mode” is turned on (the small phone icon is blue) then I can select the network speed:</p>
  456. <figure name="b31f" id="b31f" class="graf--figure"><div class="aspectRatioPlaceholder is-locked"><p class="aspect-ratio-fill"/><img class="graf-image" data-image-id="1*E7rmbWJbDkFUC1VoaSMriA.png" data-width="1082" data-height="436" data-action="zoom" data-action-value="1*E7rmbWJbDkFUC1VoaSMriA.png" src="https://medium2.global.ssl.fastly.net/max/800/1*E7rmbWJbDkFUC1VoaSMriA.png"/></div><figcaption class="imageCaption">Chrome Developer Tools Network emulation, including throughoutput and Round-Trip-Time</figcaption></figure>
  457. <p name="c3df" id="c3df" class="graf--p">I always keep this mode turned on for the site I am working on. <strong class="markup--strong markup--p-strong">I need to feel the pain as soon as possible</strong> so that I immediately notice the changes that are bad for performance. Additionally, I like that I can easily disable the cache under the “Network” panel (see screenshot above) without having to purge the browser cache.</p>
  458. <p name="57c9" id="57c9" class="graf--p graf--empty"><br/></p>
  459. <h3 name="be99" id="be99" class="graf--h3">2. On some sites the text was invisible for a frustratingly long time</h3>
  460. <p name="19a4" id="19a4" class="graf--p graf--empty"><br/></p>
  461. <p name="3a6c" id="3a6c" class="graf--p">This was annoying. The text was already there but I couldn’t see it until the relevant fonts were downloaded. This problem only occurs on WebKit-based browsers, which means iOS and old Android browsers. WebKit is overly polite and just waits and waits, prudishly hiding the text until the font is downloaded. In contrast, Internet Explorer is so rude it will show the site immediately with the fallback font, exposing me to the flash of unformatted text (<a href="http://www.paulirish.com/2009/fighting-the-font-face-fout/" data-href="http://www.paulirish.com/2009/fighting-the-font-face-fout/" class="markup--anchor markup--p-anchor" rel="nofollow">FOUT</a>) when the fonts are applied. The pragmatic solution is Chrome, both desktop and Android (as well as Opera which uses the same rendering engine): they hide the text to avoid FOUT but only for a maximum of 3 seconds. It’s a smart trade-off between the two extremes. Fortunately, these browsers cover the majority of the browser population. But there are still users out there with old Androids and iPhones, like me, who are sometimes on a very slow network and don’t have the fonts cached.</p>
  462. <h4 name="9471" id="9471" class="graf--h4">Takeaway 2: Web font loading must be controlled</h4>
  463. <p name="0445" id="0445" class="graf--p graf--empty"><br/></p>
  464. <p name="9cb4" id="9cb4" class="graf--p">After I’ve done everything <a href="http://bit.ly/1gTDZ1G" data-href="http://bit.ly/1gTDZ1G" class="markup--anchor markup--p-anchor" rel="nofollow">Ilya Grigorik says about loading web fonts</a> I created a tiny script called <a href="https://github.com/gaborlenard/zenfonts/" data-href="https://github.com/gaborlenard/zenfonts/" class="markup--anchor markup--p-anchor" rel="nofollow"><strong class="markup--strong markup--p-strong">Zenfonts</strong></a><strong class="markup--strong markup--p-strong"> </strong>to fix both the “invisible text” problem and the FOUT, without changing the browers’ loading mechanism.</p>
  465. <p name="7455" id="7455" class="graf--p graf--empty"><br/></p>
  466. <h3 name="e1df" id="e1df" class="graf--h3">3. Well-designed apps worked wonderfully</h3>
  467. <p name="bdb4" id="bdb4" class="graf--p graf--empty"><br/></p>
  468. <p name="3bb2" id="3bb2" class="graf--p">I am very grateful for those apps that worked flawlessly under such conditions. The three most prominent being Apple’s own Mail client, <a href="http://reederapp.com/ios/" data-href="http://reederapp.com/ios/" class="markup--anchor markup--p-anchor" rel="nofollow">Reeder</a> and <a href="http://getpocket.com" data-href="http://getpocket.com" class="markup--anchor markup--p-anchor" rel="nofollow">Pocket</a>. All of them downloaded and stored their items when the network was available and I could access those items even offline. When I marked something as read or starred, all three apps queued these requests until they could send them to the server. I was especially fond of Pocket’s sharing extension which worked lightning fast, even if everything else was unbearable. These three apps never complained that the network timed out. They just worked.</p>
  469. <p name="b57a" id="b57a" class="graf--p">In comparison, <a href="http://blog.fastmail.com/2014/11/12/fastmail-app-for-ios-and-android-now-available/" data-href="http://blog.fastmail.com/2014/11/12/fastmail-app-for-ios-and-android-now-available/" class="markup--anchor markup--p-anchor" rel="nofollow">FastMail’s app</a> was unusable. I tried it several times but my Inbox never loaded. Their app is probably just a wrapper for the web app. Much easier for the developer but much less value for the user.</p>
  470. <h4 name="86d2" id="86d2" class="graf--h4">Takeaway 3: Design apps for offline &amp; async usage</h4>
  471. <p name="7c51" id="7c51" class="graf--p graf--empty"><br/></p>
  472. <p name="ee59" id="ee59" class="graf--p"><a href="http://alistapart.com/article/offline-first" data-href="http://alistapart.com/article/offline-first" class="markup--anchor markup--p-anchor" rel="nofollow"><strong class="markup--strong markup--p-strong">Design offline-first apps</strong></a> (both native and web apps). When you make a web app, make it offline-first. When you make a native app, don’t settle for a mindless wrapper. Cache content. Queue up outgoing data and actions without blocking the user. Handle conflicts. This makes a huge difference in the usability of the app and can literally open up new markets.</p>
  473. <p name="cd83" id="cd83" class="graf--p graf--empty"><br/></p>
  474. <p name="438c" id="438c" class="graf--p graf--last">I am so glad this happened. There are different levels of understanding our users, especially those with special requirements. Nothing beats becoming them for a longer period of time.</p>
  475. </article>
  476. </section>
  477. <nav id="jumpto">
  478. <p>
  479. <a href="/david/blog/">Accueil du blog</a> |
  480. <a href="https://medium.com/@zengabor/three-takeaways-for-web-developers-after-two-weeks-of-painfully-slow-internet-9e7f6d47726e">Source originale</a> |
  481. <a href="/david/stream/2019/">Accueil du flux</a>
  482. </p>
  483. </nav>
  484. <footer>
  485. <div>
  486. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  487. <p>
  488. Bonjour/Hi!
  489. 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>
  490. 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>).
  491. </p>
  492. <p>
  493. 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>.
  494. </p>
  495. <p>
  496. Voici quelques articles choisis :
  497. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  498. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  499. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  500. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  501. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  502. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  503. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  504. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  505. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  506. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  507. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  508. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  509. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  510. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  511. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  512. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  513. </p>
  514. <p>
  515. 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>.
  516. </p>
  517. <p>
  518. Je ne traque pas ta navigation mais mon
  519. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  520. conserve des logs d’accès.
  521. </p>
  522. </div>
  523. </footer>
  524. <script type="text/javascript">
  525. ;(_ => {
  526. const jumper = document.getElementById('jumper')
  527. jumper.addEventListener('click', e => {
  528. e.preventDefault()
  529. const anchor = e.target.getAttribute('href')
  530. const targetEl = document.getElementById(anchor.substring(1))
  531. targetEl.scrollIntoView({behavior: 'smooth'})
  532. })
  533. })()
  534. </script>