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 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  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>Progressive Web Applications (PWA): A primer (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://tech.people-doc.com/progressive-web-applications-primer.html">
  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. Progressive Web Applications (PWA): A primer (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://tech.people-doc.com/progressive-web-applications-primer.html">Source originale du contenu</a></h3>
  445. <h3>Wanna Feel Old?</h3>
  446. <p>Back in the days some developers created static websites, and I meant static as in table layout and pixel-perfect design. This were the good ol’ times… Well not really, and since then the web did move a lot!</p>
  447. <p>First, we get rid of those damn table layout, flex a bit to continue by adding some interactivity to website using GIF, <a href="https://www.wikiwand.com/en/Dynamic_HTML">DHTML</a>, and <a href="https://www.wikiwand.com/en/Ajax_(programming)">AJAX</a>. Then, we decided to challenge the screen size <em>statu quo</em> and go to the infinity of handheld devices form-factors.</p>
  448. <p>That’s when Responsive Web Design (RWD) emerged has a good idea to avoid duplicating what we did. A side-effect of RWD has been to highlight the multiple way and devices people were using to browse the web, thus benefiting accessibility and those who need it (i.e. everyone).</p>
  449. <p>With the development of the smartphone market, web development was taken over by native mobile technologies (Android, IOS, etc). So, it was time to get back to our basic, and work on real tooling to move our ecosystem forward. Hence, the birth of Node/NPM that changed the game, introducing frameworks and libraries to the daily process of web developers (grunt, gulp, webpack, rollup, etc). We were now developing web app more often than website and web developers’ role evolve to become Software Engineer one!</p>
  450. <p>With these new powers, came new responsibilities. Now, more than before, we have to ensure our products quality, maintainability, performance and reachability. Indeed, in this age, users access content on various type of devices (desktop, smart- vs. dumb-phone) and uneven connection speed (office, home, commute). Once again, we were caught up with what accessibility has been trying to fix for years.</p>
  451. <p>Ok, but that was back in 2015…</p>
  452. <h3>What is a Progressive Web App?</h3>
  453. <p>Since 2017, web browser are trying to reclaim market shares from the native apps using Progressive Web App (PWA):</p>
  454. <blockquote>
  455. <p>A website which looks and behaves exactly like a native mobile app, which means that it can be <strong>added to the home screen</strong> on a smartphone, send <strong>push notifications</strong>, access the <strong>device’s hardware</strong> and - most importantly - <strong>work offline</strong>.
  456. — <a href="https://webagility.com/posts/how-progressive-web-apps-make-the-web-great-again">webagility.com/posts/how-progressive-web-apps-make-the-web-great-again</a>.</p>
  457. </blockquote>
  458. <p>If you never used a PWA before, you might want to reconsider your statement after visiting at <a href="about:serviceworkers-internals">about:serviceworkers-internals</a> on Firefox and <a href="chrome://serviceworker-internals/">chrome://serviceworker-internals/</a> on Chrome.</p>
  459. <p><img src="https://tech.people-doc.com/images/progressive-web-app-primer/pwa_1.png" alt="Examples of th satstuspage of a browser" width="50%" style="position:relative;left:25%"></p>
  460. <p>What are those pages, you might ask? They list the service workers, the part of the PWA that manages cache and let the application work even when there is no more connectivity.</p>
  461. <p>Understanding PWA will be easier if you are familiar with modern web framework that hook into a page to load the app and navigates other content from it. In PWA parlance they call this the application shell pattern and it aims at making the app <a href="https://developers.google.com/web/updates/2015/11/app-shell#first_load_and_loading_other_pages">load fast, be cached, dynamically display content</a>.</p>
  462. <p><img src="https://tech.people-doc.com/images/progressive-web-app-primer/pwa_2.jpg" alt="What is the AppShell?" width="50%" style="position:relative;left:25%"></p>
  463. <p>In order to get a fast TTI (Time To Interactive), you should design your homepage carefully to hold what should be on screen immediately and inline it (CSS and images mainly) or fake it (use CSS or text placeholder).</p>
  464. <p>But first things first, what are the benefits of developing and using PWA?</p>
  465. <h3>Business Incentives</h3>
  466. <p>The paramount benefit is to make your users happier with an application that will be <a href="https://developers.google.com/web/progressive-web-apps/">faster to install, more reliable to use and provide engaging content</a>. And happier users stay longer, and come back to your app. Behind this claim, are facts and numbers to support it.</p>
  467. <p>First, the bounce rate is extremely dependant on how fast your app serves content but above all how fast it becomes interactive so the app can handle user input. This metric is called <a href="https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive">Time to Interactive</a> and if it goes above 3s expect to lose half of your users.</p>
  468. <p><img src="https://tech.people-doc.com/images/progressive-web-app-primer/pwa_3.png" alt="Time To Interactive" width="50%" style="position:relative;left:25%"></p>
  469. <p>Using PWA will reduce network consumption as you reduce the amount of data to transfer to only the data themselves, the application code can be cached and persist even after tab or browser has been closed. If your company pays for its bandwidth, you know how this is important.</p>
  470. <p>As you are distributing your app yourself, you mobile app is the same as your web app so this means less code to maintain and less dependencies to 3rd parties such as Play Store and their review processes.</p>
  471. <p>Due to being web content with light payload you can reach emerging market at the same cost for you and reduced cost for your users (remember not every country has cheap 100 Go/month like we have in France).</p>
  472. <p>Google developers platform has a lot of <a href="https://developers.google.com/web/showcase/">showcases you can explore</a> to see other benefit, categorized by regions or industries.</p>
  473. <h3>User benefits</h3>
  474. <h4>Lighter</h4>
  475. <p>In comparison to native apps, PWA are a lighter as most of the heavy-lifting is done by the browser so you can focus on coding and shipping code related to your business.</p>
  476. <p>As the app mostly exchanges data even across browser sessions, your user will consume less from their data plans and they will love you for this as they will be able to consume more of your content.</p>
  477. <p>Once again a lighter app means more people can access it, in different context and with different connectivity. Indeed, why would you cut off potential customer from Africa or a remote mountainous areas in France?</p>
  478. <h4>Faster to install</h4>
  479. <p>Being lighter mean faster to download and install, that means faster access to content and more time on the app.</p>
  480. <blockquote>
  481. <p>In a mobile app <strong>every step you make a user perform</strong> before they get value out of your app will <strong>cost you 20% of users</strong>.
  482. — Gabor Csele, a Product Manager in Google</p>
  483. </blockquote>
  484. <p><img src="https://tech.people-doc.com/images/progressive-web-app-primer/pwa_4.png" alt="From Discovery to Install charts, comparing apps VS PWAs" width="50%" style="position:relative;left:25%"></p>
  485. <h4>Familiar Behavior</h4>
  486. <p>One goal of PWA is to fill the gap between web experience and native experience using only web technologies. Despite being an active area of development, mobile web browser and OS offer some features to make you feel like your are using a native app. For instance, installing a PWA you will:</p>
  487. <ul>
  488. <li>Get your app icon on the homescreen and the app listing,</li>
  489. <li>View your app as another native app while hitting windows listing button</li>
  490. <li>Manage it like native app (removal)</li>
  491. </ul>
  492. <h3>Installing</h3>
  493. <p>To install a progressive web app it’s better to get yourself a smartphone and open your browser of choice. In Firefox, <a href="https://developer.mozilla.org/en-US/Apps/Progressive/Add_to_home_screen">look for the house icon</a>, it’s official name is <em>Add to Home screen</em> (A2HS), with a plus in the URL bar, on Chrome <a href="https://developers.google.com/web/fundamentals/app-install-banners/">head to the menu and look for Add to Homescreen</a>.</p>
  494. <h3>What Can Web Do Today?</h3>
  495. <p>You might think that the web can compete with native app API, that’s probably because you forgot about <a href="http://whatwebcando.today">What Can Web Do Today?</a> website:</p>
  496. <blockquote>
  497. <p>bluetooth, geolocation, speech recognition and even local notifications and push messages work well in a lot of major and modern browsers...
  498. — <a href="http://progressivewebapps.net/">Progressivewebapps.net</a></p>
  499. </blockquote>
  500. <p><img src="https://tech.people-doc.com/images/progressive-web-app-primer/pwa_5.png" alt="Screenshot of the website 'What can web do today?'" width="50%" style="position:relative;left:25%"></p>
  501. <h3>Conclusion - Going even further</h3>
  502. <p>If you are looking for performance on the web, you should be looking at <a href="https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts">Web Assembly</a>. It’s coming pretty fast and it’s back by… well, <a href="https://arstechnica.com/information-technology/2015/06/the-web-is-getting-its-bytecode-webassembly/">every major actor of web technologies</a>: Mozilla Foundation, Google, Microsoft, Apple and W3C.</p>
  503. <p>We hope this introduction to Progressive Web Applications made you want to
  504. implement it on your own projects. And at least we certainly think you should :)</p>
  505. <p>Last but not least: <a href="https://boards.greenhouse.io/peopledoc/jobs/613268#.WoL7SFPOV0s">we're hiring Frontend developers</a> to join the team to work on PWAs and more.</p>
  506. <p>— Édouard</p>
  507. </article>
  508. </section>
  509. <nav id="jumpto">
  510. <p>
  511. <a href="/david/blog/">Accueil du blog</a> |
  512. <a href="https://tech.people-doc.com/progressive-web-applications-primer.html">Source originale</a> |
  513. <a href="/david/stream/2019/">Accueil du flux</a>
  514. </p>
  515. </nav>
  516. <footer>
  517. <div>
  518. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  519. <p>
  520. Bonjour/Hi!
  521. 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>
  522. 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>).
  523. </p>
  524. <p>
  525. 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>.
  526. </p>
  527. <p>
  528. Voici quelques articles choisis :
  529. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  530. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  531. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  532. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  533. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  534. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  535. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  536. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  537. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  538. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  539. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  540. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  541. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  542. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  543. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  544. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  545. </p>
  546. <p>
  547. 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>.
  548. </p>
  549. <p>
  550. Je ne traque pas ta navigation mais mon
  551. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  552. conserve des logs d’accès.
  553. </p>
  554. </div>
  555. </footer>
  556. <script type="text/javascript">
  557. ;(_ => {
  558. const jumper = document.getElementById('jumper')
  559. jumper.addEventListener('click', e => {
  560. e.preventDefault()
  561. const anchor = e.target.getAttribute('href')
  562. const targetEl = document.getElementById(anchor.substring(1))
  563. targetEl.scrollIntoView({behavior: 'smooth'})
  564. })
  565. })()
  566. </script>