<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Bertrand Junqua on Medium]]></title>
        <description><![CDATA[Stories by Bertrand Junqua on Medium]]></description>
        <link>https://medium.com/@bertrandjun?source=rss-3be153bb0ca6------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*eZSGNKrBwo-A9xuK.</url>
            <title>Stories by Bertrand Junqua on Medium</title>
            <link>https://medium.com/@bertrandjun?source=rss-3be153bb0ca6------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 22 May 2026 13:31:35 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@bertrandjun/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Over-eager loading of Webpack’s async chunks for performant, seamless bundle splitting]]></title>
            <link>https://medium.com/@bertrandjun/over-eager-loading-of-webpacks-async-chunks-for-performant-seamless-bundle-splitting-422380b1357?source=rss-3be153bb0ca6------2</link>
            <guid isPermaLink="false">https://medium.com/p/422380b1357</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[web-performance]]></category>
            <category><![CDATA[code-splitting]]></category>
            <category><![CDATA[lazy-loading]]></category>
            <category><![CDATA[webpack]]></category>
            <dc:creator><![CDATA[Bertrand Junqua]]></dc:creator>
            <pubDate>Mon, 12 Mar 2018 16:05:51 GMT</pubDate>
            <atom:updated>2018-03-12T16:10:51.758Z</atom:updated>
            <content:encoded><![CDATA[<p>Webpack is a fantastic build tool. One of the reasons for that is its code splitting abilities and the magic that comes with it: import() some code and <em>voilà</em>, it gets separated from our main bundle and loaded only on demand.</p><p>This is very nice and allows us, after some hair-pulling time spent configuring and fine tuning the entry points and the common chunks, to greatly improve the Time To Interactive (TTI) of our app.</p><p>The problem is that those separate chunks are by default lazy-loaded, meaning that the client will only fetch them when absolutely necessary. And that has a big drawback, because now we have to handle loading times we did not have before. We reduced the TTI, but significantly increased the time necessary to jump from one section to another.</p><p>Enter <em>over-eager loading,</em> which is basically the idea of loading resources before the user actually asks for them/needs them by anticipating his needs. Loading our async chunks in an <em>over-eager</em> fashion will mean to quietly load them in the background after our app is interactive so that they’re ready for when the user actually needs them.</p><p>Let’s look at how to implement that.</p><p>Let’s create a class named AsyncChunks that will be in charge of generating our webpack split points.</p><pre>import Loadable from &#39;react-loadable&#39;;<br>import LoadingPage from &#39;./LoadingPage&#39;;</pre><pre>class AsyncChunks {<br>  generateChunk = (<em>loader</em>) =&gt; {<br>    return Loadable({ loader, loading: LoadingPage });<br>  }<br>}</pre><pre>export default new AsyncChunks();</pre><p>We threw in the handy react-loadable util that handles displaying a loading placeholder in case we try to access our chunk before it has actually loaded, plus a couple of other edge cases.</p><p>Now, in our app’s code, replace our simple imports with something like this:</p><pre>AsyncChunks.generateChunk(() =&gt; import(&#39;./MyComponent&#39;));</pre><p>So far so good, we got ourselves a basic implementation of bundles lazy-loading. Let’s now sprinkle some magic on top of this to make it more interesting.</p><p>First, we’ll register all of these chunks to a queue:</p><pre>class AsyncChunks {<br>  chunksQueue = [];<br>  <br>  appendToQueue = <em>chunk</em> =&gt; <em>this</em>.chunksQueue.push(chunk)<br>  <br>  generateChunk = (<em>loader</em>) =&gt; {<br>    <em>this</em>.appendToQueue(loader);<br>    return Loadable({ loader, loading: LoadingPage });<br>  }<br>}</pre><p>Now, as soon as our app loads, all the async chunks are going to register to the chunksQueue array, waiting for our command. Let’s add a loadChunks method to our class to allow us to trigger the eager loading of those chunks when we see fit:</p><pre>class AsyncChunks {<br>  chunksQueue = [];<br>  <br>  appendToQueue = <em>chunk</em> =&gt; <em>this</em>.chunksQueue.push(chunk)<br>  <br>  generateChunk = (<em>loader</em>) =&gt; {<br>    <em>this</em>.appendToQueue(loader);<br>    return Loadable({ loader, loading: LoadingPage });<br>  }</pre><pre>  loadChunks = () =&gt; {<br>    <em>this</em>.chunksQueue.forEach(<em>loader</em> =&gt; loader());<br>    <em>this</em>.chunksQueue = [];<br>  }<br>}</pre><p>Now, we only have to call this loadChunks method when appropriate. And what better time that right after our app is done mounting?</p><p>In our App.jsx, we add:</p><pre>componentDidMount = () =&gt; {<br>  setTimeout(AsyncChunks.loadChunks, 2 * 1000);<br>}</pre><p>Here, we wait for two seconds (to avoid cluttering the bandwidth while most of the HTTP calls made by the app upon boot are still running), and then start loading all our chunks.</p><p>And that’s it!</p><p>One final touch though: to have a smarter over-eager loading, we should improve our AsyncChunks class to allow us to specify chunks that do not need to be preloaded:</p><pre>class AsyncChunks {<br>  chunksQueue = [];<br>  <br>  appendToQueue = <em>chunk</em> =&gt; <em>this</em>.chunksQueue.push(chunk)<br>  <br>  generateChunk = (<em>loader</em>, <em>register</em> = true) =&gt; {<br>    if (register) <em>this</em>.appendToQueue(loader);<br>    return Loadable({ loader, loading: LoadingPage });<br>  }</pre><pre>  loadChunks = () =&gt; {<br>    <em>this</em>.chunksQueue.forEach(<em>loader</em> =&gt; loader());<br>    <em>this</em>.chunksQueue = [];<br>  }<br>}</pre><p>Now we can still register our likely-to-be-needed chunks just like before, and the no-so-necessary ones like so:</p><pre>AsyncChunks.generateChunk(() =&gt; import(‘./MyComponent’), false);</pre><p>Those registered like this will load on-demand, in a default Webpack way.</p><p>To recap, we achieved to remove the delay created by Webpack’s code splitting when the client needs a new chunk while keeping all of the advantages of code splitting: minimal initial bundle and thus reduced Time To Interactive 🎉</p><p>Our last optimisation even allowed us to avoid wasting bandwidth by only pre-loading important bundles 😎</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=422380b1357" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Functional programming and immutable data structures in Javascript]]></title>
            <link>https://medium.com/@bertrandjun/refactoring-javascript-code-with-functional-programming-and-moris-immutable-data-structures-ee3d05efe015?source=rss-3be153bb0ca6------2</link>
            <guid isPermaLink="false">https://medium.com/p/ee3d05efe015</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[clojurescript]]></category>
            <category><![CDATA[data-processing]]></category>
            <dc:creator><![CDATA[Bertrand Junqua]]></dc:creator>
            <pubDate>Sun, 11 Mar 2018 13:24:16 GMT</pubDate>
            <atom:updated>2018-05-16T10:47:27.786Z</atom:updated>
            <content:encoded><![CDATA[<p>A few months ago, I stumbled upon <a href="https://www.youtube.com/watch?v=Wo0qiGPSV-s">this conference</a> by Anjana Vakil, explaining immutable data structures and pointing to two libraries enabling us to use those in Javascript.<br>The first one was the very famous <a href="https://facebook.github.io/immutable-js/">Immutable.js</a> by Facebook, and the second one was <a href="http://swannodette.github.io/mori/">Mori</a>, a port of ClojureScript’s data structures, that had better performance and a 100% functional API.</p><p>A few months later, I found myself having to refactor a very CPU-heavy Node.js service handling huge amounts of data and transforming them in various ways.</p><p>This is when I remembered Anjana Vakil’s conference and decided to dig further into using immutable data structures. My first step was to experiment with a JSPerf test:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*r3W_LviMNq0gfCin86IEAw.png" /><figcaption>Native JS array filtering VS filtering on a mori list</figcaption></figure><p>As you can see, the results were quite spectacular.</p><p>The above test is comparing using JS’ filter method on a native array against using Mori’s filter function on a Mori list. While the former re-creates an array from scratch with the values satisfying the isAboveFifty predicate, the latter leverages immutable data structures to create a new list <em>referencing</em> the old one, only different in that it discarded the values we don’t want to keep.</p><p>Rejoiced by those results, I decided to start using Mori to refactor my Node.js service. And this is where it gets interesting, because I had been blending in functional programming principles in my daily JS code for some time now, but Mori actually enabled me (or should I say <em>forced</em> me) to refactor all of the data manipulation code to adopt a strict FP style.</p><p>Consider the following snippet of code:</p><pre>const rows = [<br>  { a: &#39;foo&#39;, b: &#39;bar&#39; },<br>  { a: &#39;baz&#39;, b: &#39;qux&#39; },<br>];</pre><pre>const processRows = (rows, flag) =&gt; {<br>  if (flag) {<br>    rows.forEach((row) =&gt; {<br>      row.a = &#39;test&#39;;<br>    }<br>  }<br>  ... more processing<br>};</pre><pre>processRows(rows, true);</pre><p>Now, while this works, it has the disadvantage of mutating directly the input data, and that comes with many risks. So let’s try and avoid that by refactoring this function in a slightly more functional style:</p><pre>const processRows = (rows, flag) =&gt; {<br>  let newRows = rows;<br>  if (flag) {<br>    newsRows = rows.map(row =&gt; ({ ...row, a: &#39;test&#39; }));<br>  }<br>  ... more processing<br>  return newRows;<br>};</pre><pre>const result = processRows(rows, true);</pre><p>Now we are not mutating the input data anymore, but we got ourselves a couple of issues: first of all, we’re assigning and re-assigning a variable, which is not something you want to do when writing functional code (plus it’s ugly), but most importantly we are re-creating a full array with all of our rows on every map, and that is wasting a lot of resources.</p><p>Let’s start with the first issue, and extract that conditional processing to a separate function:</p><pre>const replaceA = (rows, flag) =&gt; (<br>  flag<br>    ? rows.map(row =&gt; ({ ...row, a: &#39;test&#39; }))<br>    : rows<br>);</pre><pre>const processRows = (rows, flag) =&gt; {<br>  const newRows = replaceA(rows, flag);<br>  ... more processing<br>  return finalRows;<br>};</pre><pre>const result = processRows(rows, true);</pre><p>Now, because we have extracted the conditional processing to a separate function, we do not need to re-assign any variable: we are always creating a new one, that we’re going to use for the subsequent processing. Each step of the processing is going to, in the same fashion, return a new variable until we have our finalRows that we can return.</p><p>But now, we just created ourselves a new problem: say we have 3 functions we need to apply to our data, our main function is going to look like this:</p><pre>const processRows = (rows) =&gt; {<br>  const stepA = applyStepA(rows);<br>  const stepB = applyStepB(stepA);<br>  const stepC = applyStepC(stepB);<br>  return stepC;<br>};</pre><p>Those are a lot of variable assignments, this code is way too verbose and is becoming hard to maintain: each function has to use the data from the previous step, or it will be inadvertently discarding one step of the processing.</p><p>Let’s tackle this with a simple pipeline util function:</p><pre>const pipeline = (...fns) =&gt; seed =&gt; (<br>  fns.reduce((acc, fn) =&gt; fn(acc), seed)<br>);</pre><pre>const processRows = rows =&gt; (<br>  pipeline(<br>    stepA,<br>    stepB,<br>    stepC,<br>  )(rows)<br>);</pre><p>We can even go further and write it “point-free style”:</p><pre>const processRows = pipeline(stepA, stepB, stepC);</pre><p>Now we got ourselves some clean, terse, functional JS code, but we’re still copying our rows multiple times ; time to bring in the big guns!</p><p>Let’s go back to our initial example, and see how it would look like after applying those FP patterns and Mori immutable data structures:</p><pre>import mori from &#39;mori&#39;;</pre><pre>const replaceA = (flag, rows) =&gt; (<br>  flag<br>    ? mori.map(row =&gt; ({ ...row, a: &#39;test&#39; }), rows)<br>    : rows<br>);</pre><pre>const processRows = flag =&gt; pipeline(<br>  mori.partial(replaceA, flag),<br>  ... more functions<br>);</pre><pre>const result = processRows(true)(rows);</pre><p>Here is what’s happening: first of all, processRows now takes only one argument, the flag boolean, and returns a function, our pipeline, that itself also takes one argument, the rows of data.<br>Inside that pipeline, we’re discovering an interesting case where a step takes several arguments. To tackle this, we reversed the order of the arguments replaceA takes so that the data it expects comes last (this is a very common pattern in functional programming). Then we partially apply the function using a handy partial util provided by Mori, so that it expects only one last argument: the data to operate on.</p><p>Lastly, we replaced the native map with Mori’s, that also happen to expects data as its last argument (see? 😄).</p><p>And boom! We’re not duplicating the input rows anymore! (We’re still duplicating the objects it contains though, and we could avoid that with Mori too, but that’s beyond the scope of this article).</p><p>Using functional programming principles and immutable data structures, we were able to break down our code into smaller, more easily testable functions. But most importantly, we are no longer mutating the original array, while avoiding the performance drawbacks of constantly duplicating our input array like the native Javascript array methods like map or filter inevitably do.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ee3d05efe015" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>