<?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 Jongleberry on Medium]]></title>
        <description><![CDATA[Stories by Jongleberry on Medium]]></description>
        <link>https://medium.com/@jongleberry?source=rss-f2bc6cc73b9c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*PJpNLgmYYbeBnj1i.png</url>
            <title>Stories by Jongleberry on Medium</title>
            <link>https://medium.com/@jongleberry?source=rss-f2bc6cc73b9c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 18 Jun 2026 06:00:19 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@jongleberry/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[Dedicated tech debt and learning days are smells for your engineering organization]]></title>
            <link>https://jongleberry.medium.com/dedicated-tech-debt-and-learning-days-are-smells-for-your-engineering-organization-18cf80994bb7?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/18cf80994bb7</guid>
            <category><![CDATA[technical-debt]]></category>
            <category><![CDATA[project-management]]></category>
            <category><![CDATA[product-engineering]]></category>
            <category><![CDATA[roadmaps]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Tue, 19 Sep 2023 06:26:02 GMT</pubDate>
            <atom:updated>2023-09-19T06:26:02.005Z</atom:updated>
            <content:encoded><![CDATA[<h4>And better ways to handle tech debt and mastery in your engineering organization</h4><p>My two most recent employers each had a day of the month dedicated to either learning or tackling tech debt. In both instances, I did not enforce them within my organization as they demonstrate problems in the broader engineering organization. If a company has these, you can smell problems from a mile away.</p><p>So why are these dedicated days for learning or tackling tech debt smells and what are better solutions to problems they’re trying to solve?</p><h3>Smells</h3><h4>Contrast from normal work</h4><p>Dedicated days imply a disparity from normal work. A day dedicated to tech debt implies you aren’t tackling tech debt otherwise. A day dedicated to learning implies you aren’t learning otherwise. These statements may not necessarily be true, but you generally do not create dedicated days unless this was historically the case.</p><h4>Inability to collaborate with product managers</h4><p>Generally, engineers are unable to tackle tech debt, and instead of trying to negotiate the roadmap with product managers, engineers instead negotiate time, e.g. 1 day a month where product managers have no say. The reason could be engineers’ inability to convey the impact of tech debt or the company being a feature factory.</p><h4>Patronizing other teams</h4><p>Perhaps a team, e.g. a platform team that works as a dependency of other teams, perceives another team as chaotic. To help them, they help champion a tech debt day since they assume that’s the cause for all the post-mortems.</p><h4>Lack of engineering excellence</h4><p>Dedicated learning days generally mean the engineering team is not learning new technologies or architecture. In the past, this was because work was very operational with engineers writing migrations or updating configurations instead of building self-serve tools. Other times, work was pure business logic and there was no architecture involved, specifically in a monolithic Rails application, so there was not much learning to be had.</p><h3>Ineffectiveness of Dedicated Days</h3><p>Not only are these dedicated learning or tech debt days smells, but they are also ineffective for many reasons:</p><ul><li>People tend to schedule meetings on these days anyway, making them less useful. The only way to avoid this is to block calendars organizationally which generally does not work.</li><li>One day a month is generally not enough to learn anything meaningful or tackle any meaningful tech debt.</li><li>Learning days are generally self-directed, meaning people learn by themselves, which is not as effective as having a mentor or having a business purpose.</li></ul><h3>Alternatives to Dedicated Days</h3><p>Here are some better alternatives to having dedicated days:</p><h4>Improve Product and Engineering Collaboration</h4><p>As an engineering lead, it’s imperative to collaborate closely with product managers. You are responsible for teaching them what the product is; a product manager is not just about rolling out features. You need to teach them about technical debt and the architectural short-term and long-term trade-offs for shortcuts. It’s important to align through something like OKR goal-setting.</p><h4>Match Projects to Engineers</h4><p>As an engineering manager, it’s important to match projects to engineers. If an engineer does not feel fulfilled by their current work, find work that will fulfill them lest they leave. One-off projects or loaning them to other teams may work.</p><h4>Allocate Capacity Towards Learning &amp; Tech Debt</h4><p>Aside from aligning the product and engineering roadmaps, you could tactically tackle tech debt by allotting a percentage of your engineering capacity to platform initiatives. This is usually my go-to strategy as it allows us to actually measure and plan platform initiatives and I have never gotten push back from product managers as long as they understand the initiative. For example, dedicating 10% of frontend engineers and 20% of backend engineers to platform initiatives per quarter may be sufficient for your company. You can extend this from team level project planning to organization-level roadmap planning.</p><h4>Cross-pollination via Code or Architecture Reviews</h4><p>Avoid having any engineering team working in silos and encourage code and architecture reviews across teams. Have teams create and share docs and invite the entire organization to comment. Taking into account more perspectives helps avoid clear deficiencies in your code or architecture.</p><h4>Rotation or Exchange Programs</h4><p>Instead of spending a day a month learning something, spend two weeks a year embedded in another team that could help you learn the ins-and-outs of their domain. For example, you could have engineers rotate with an SRE or infrastructure team to better improve your platform.</p><h4>Planning Learning and Innovation</h4><p>Plan, say, 5–10% of your work with learning and innovation that have some sort of business impact. Having business impact will convince stakeholders to prioritize it and many stakeholders believe in dedicating time towards innovation. These projects could be stretch, research projects with a very low chance of success. Examples are 3D printing, automating something with Alexa/Siri/etc. or with IFFFT.</p><h3>Learn and Tackle Tech Debt Every Day</h3><p>Serving the business and building a healthy engineering organization is not dichotomous. Mastery through learning every day and especially learning how to not add tech debt to a system is key intrinsic motivator for keeping and growing engineers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=18cf80994bb7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Mistakes H-1B candidates make on their software engineering resumes for U.S. companies]]></title>
            <link>https://jongleberry.medium.com/mistakes-h-1b-candidates-make-on-their-software-engineering-resumes-for-u-s-companies-f9fe1bc15dfd?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/f9fe1bc15dfd</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[resume-writing]]></category>
            <category><![CDATA[job-hunting]]></category>
            <category><![CDATA[resume]]></category>
            <category><![CDATA[h1b]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Fri, 14 Jan 2022 06:05:51 GMT</pubDate>
            <atom:updated>2022-01-14T06:05:51.840Z</atom:updated>
            <content:encoded><![CDATA[<h4>How to tailor your software engineering resume for the U.S. market</h4><p>When scanning through applicants’ resumes, it’s pretty easy to spot H-1B candidates just by reading the top third of the resume’s first page. This could pose a problem for many of these candidates as hiring managers and recruiters may find these resumes difficult to understand. Here are some tips on making your resume look more like U.S.-based candidates’ as well as have a better resume overall, even if you aren’t an H-1B candidate.</p><h3>Reverse Chronological Order</h3><p>The first thing a hiring manager wants to see on your resume is your current or latest position. Don’t make this difficult to find—it should be on the top third of your resume. Continue to list your experience in reverse chronological order with the most recent experience first since the more recent experience is more relevant. The only exception to this is to have a separate “Education” section <strong>below</strong> your professional experience which would otherwise be interlaced with your professional experience.</p><h4>Education Doesn’t Matter</h4><p>Unless you are a new graduate, your education does not matter. Your last professional experience is a much better signal than the university you attended. For the most part, all software engineering bachelor’s and master’s degrees from accredited universities in the U.S. are treated equivalently.</p><h4>Internships &gt; Education</h4><p>Again, education does not matter, especially if you have internship experience, which counts as professional experience. An internship at a well-known company is a better signal than the university you attended. The best signal is if you have two back-to-back summer internships at the same company — clearly you are great employee!</p><h3>1–2 Pages</h3><p>In the U.S. tech industries, we want a resume, not a curriculum vitae. CVs tend to be long and descriptive; they are more suited for other industries like academia, not the tech industry. A resume should be at most two pages with a reasonably sized font (between 10–12px).</p><h4>A Summary is a Few Sentences, Max</h4><p>Keep your summary, blurb, or cover letter short. Only provide necessary details such as dealbreakers (e.g. remote work only) and what you want to work on (e.g. React and GraphQL). List character references you may have at the company as well as people you’ve met through recruiting.</p><h4>Conciseness is a Skill</h4><p>A short resume demonstrates a very valuable skill in engineering: conciseness. Are you able to describe a problem in a few words? Are you able to solve a problem with minimal code? Do you value the audience’s time by making your communication brief? It may be difficult to write a concise resume, but avoid a long one—a long resume demonstrates a lack of both conciseness and empathy for the reader.</p><h3>Minimal Personal Details</h3><p>Don’t add information about your marital status, family, personal hobbies, or passions unless they are relevant to your career. For one, it elongates your resume by adding irrelevant information. However, the biggest reason is that, in the U.S., employers’ asking about certain personal information opens up the employer to discrimination lawsuits, so it’s best for both parties to avoid this by not adding personal details to your resume at all.</p><h4>No Headshots</h4><p>Don’t put your headshots in your resume as your looks is not an indicator of your performance as a software engineer. Many cultures tend to put headshots in their resume, but they usually aren’t as diverse and sensitive to diversity as the U.S. Adding your headshot to your resume may make hiring managers discriminate for or against your looks, both of which could be a liability for the company.</p><h4>Details to Exclude</h4><p>Personal information should remain personal; only put enough personal information for potential employers to know that you are hire-able. Some don’ts are:</p><ul><li>Your religion, sex, gender, sexual orientation, and date of birth are generally not relevant</li><li>Just put your current city; employers don’t need your full address until you’re being hired</li><li>If you think your name may be open to discrimination by hiring managers, abbreviate your first or last name and make sure your LinkedIn profile matches!</li></ul><h3>Formatting</h3><h4>PDFs, not Microsoft Word</h4><p>Many software engineers and engineering hiring managers do not have Microsoft Word as many use Google Apps instead. Word documents will be incorrectly reformatted by Google Apps or Apple Pages, messing them up entirely. Send your resume as a PDF, which is a standardized file format, so that the recipient can read your resume as intended.</p><h4>Avoid Large Skill Word-Clouds</h4><p>These tend to be useless, especially if they are large. Think about what you want to convey to the hiring manager and recruiter and just summarize those such as, “Full-stack React and Express.js Engineer”. As a hiring manager, I primarily care about what you’ve worked on and what you want to work on and I look into your recent experience for this, not the word cloud.</p><p>Additionally, many candidates tend to list skills that they haven’t used in years in the word cloud and thus are no longer relevant. It’s better to embed your skills into your experience so that your skills are described within context—when you used and developed these skills and what role and position you were in.</p><h4>List Your Work Authorization</h4><p>At the bottom of your resume, list your work authorization status such as “requires H-1B sponsorship”. Even I list “U.S. Citizen” at the bottom of my resume because recruiters often ask whether I need visa sponsorship. This will help weed out companies who would not sponsor your visa at all. Of course, this depends on the type of companies you apply to. Many companies either do (e.g. large tech companies) or don’t (e.g. defense companies) sponsor visas, but some companies (e.g. early stage start-ups) may sponsor your visa if you stand out or if they have sufficient VC backing.</p><h3>Summary</h3><p>Hopefully this helps you understand the U.S. tech industry better, which strives to be a progressive meritocracy, but sometimes falls short. Have any questions? Feel free to ask me questions on <a href="https://www.linkedin.com/in/jongleberry/">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9fe1bc15dfd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Technical & Organizational Benefits of Storybook Snapshot Testing]]></title>
            <link>https://jongleberry.medium.com/technical-organizational-benefits-of-storybook-snapshot-testing-937d4428db6d?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/937d4428db6d</guid>
            <category><![CDATA[continuous-integration]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[jest]]></category>
            <category><![CDATA[snapshot-testing]]></category>
            <category><![CDATA[storybook]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Wed, 22 Sep 2021 04:39:46 GMT</pubDate>
            <atom:updated>2021-09-22T04:44:47.655Z</atom:updated>
            <content:encoded><![CDATA[<h4>Keep updating those snapshots, don’t bother looking at them, and stop complaining about them</h4><p>I’ve heard many complaints about <a href="https://www.npmjs.com/package/@storybook/addon-storyshots">Storybook StoryShots</a> and <a href="https://jestjs.io/docs/en/snapshot-testing">Jest snapshot testing</a> at work, online, and various Slack groups. Some of the complaints I’ve heard are:</p><ul><li>It’s annoying because you always have to update the snapshots</li><li>It makes the git diff very large</li><li>It doesn’t actually guarantee anything</li><li>It creates a false sense of security</li></ul><p>Some of the points above are just irrelevant—you should never have to worry about large git text diffs as this is what git is optimized for. Others simply miss the organizational, technical, and other benefits of having StoryShots and snapshot testing, which is more important to me as an engineering manager. By always updating snapshots locally, you’ll reap many benefits with the minimal cost of running tests.</p><h4>StoryShots and snapshot testing do not assert correctness</h4><p>A snapshot simply stores some states in a moment in time or git history. A changed snapshot means that something has changed, but does not necessarily mean that the functionality is now broken or incorrect like a failing test otherwise would. Thus, I wouldn’t even call it a “test” — it’s more like a validation step. A snapshot “test” failed because the output change and an engineer needs to manually validate it.</p><h4>StoryShots and snapshot testing is more like static checking</h4><p><a href="https://kentcdodds.com/blog/write-tests">Write tests. Not too many. Mostly integration.</a></p><p>Many people see snapshot testing as a less useful form of unit testing, but a better way too see snapshot testing is as a more useful form of static checking and linting. Linting tools check that your code is valid without executing it whereas snapshot testing checks that your code is valid by executing it; both do not check for correctness. The fact that snapshot testing actually runs your code allows you to find bugs that linting would not be able to find. There are plenty of typos, bad imports, or bad dependencies that I’ve caught with no effort with StoryShots.</p><h4>StoryShots encourages you to build view components</h4><p>If you’ve built a complex component with data fetching and rendering, you’ve probably struggled with StoryShots as your component is dynamic and nondeterministic. For example, if your component depends on the current date, your snapshots will start failing the day after you merge your code. StoryShots and snapshot testing encourages making deterministic view components and to pass nondeterministic parameters as props. It encourages building separate data loading components or containers whose functionality can be unit tested separately.</p><h4>StoryShots is a step towards visual regression testing</h4><p><a href="https://storybook.js.org/docs/react/workflows/visual-testing">Visual Testing with Storybook</a></p><p>With only deterministic view components as stories, your team will be able to rely on visual testing to find visual regressions. With visual regression testing, your HTML DOM structure snapshots will matter much less—just manually validate the visual changes. The organizational benefit with visual regression testing is that you can visually show the changes to non-technical stakeholders like designers and product managers and catch issues sooner.</p><h4>Snapshot testing encourages engineers to run tests locally</h4><p>A failed snapshot test means the engineer did not run the test locally (i.e. did not intervene manually), which they should be doing whenever possible. The fact that PRs are failing because snapshots weren’t updated means that the engineer probably didn’t run the tests locally.</p><h4>Snapshot testing helps you understand the dependency tree</h4><p>Sometimes you will, in fact, run tests just for your component locally, but in CI, where the entire test suite is ran, you’ll find that your change also affected another component’s snapshots. These snapshot tests are a way to understand the dependency tree and know who are impacted by your changes or whose changes impact you.</p><h4>Snapshot history is a paper trail for debugging issues</h4><p>Snapshot histories provide a way for you to debug and issues in your code base. Snapshots allow you to know which PRs changes the structure of certain components, allowing you to more quickly find a culprit for an issue via git during an outage.</p><h4>StoryShots allows engineers to skip writing their own snapshots</h4><p>I hear people complaining about StoryShots, but then write their own snapshot tests for their component. This is just adding work on their plate and additional maintenance for the team. When you write a story and add StoryShot testing, you have snapshot testing for free. Of course, StoryShots only handles snapshots for views — non-view snapshots will still need to be done manually (such as tests for a component’s state machine).</p><h4>How to make snapshot testing better</h4><p>To avoid complaints in your organization while achieving the marginal benefits of StoryShots, I recommend these changes:</p><ul><li>Use shallow rendering to avoid large snapshots that are prone to breakage</li><li>Run StoryShots tests separate from your other tests</li><li>Always run StoryShots with -u locally</li><li>Create a CI job that automatically updates snapshots when necessary</li><li>If any stories or storyshots get annoying, fix it or delete it</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=937d4428db6d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[redux-thunk is bad architecture for organizations]]></title>
            <link>https://jongleberry.medium.com/redux-thunk-is-bad-architecture-for-organizations-8205a792e5fe?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8205a792e5fe</guid>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[redux-thunk]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[redux]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Wed, 15 Sep 2021 19:23:58 GMT</pubDate>
            <atom:updated>2021-09-15T19:23:58.919Z</atom:updated>
            <content:encoded><![CDATA[<h4>Don’t use redux-thunk, especially in the 2020s</h4><p>When starting with <a href="https://reactjs.org">React</a>, many people being using <a href="https://redux.js.org">redux</a> with <a href="https://github.com/reduxjs/redux-thunk">redux-thunk</a>. After first seeing it many years ago, I quickly smelled many anti-patterns and tried to move teams off of it. Nowadays, with <a href="https://www.apollographql.com">Apollo GraphQL</a>, <a href="https://reactjs.org/docs/context.html">React Context</a>, and <a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a> among other features, there’s less reason to use it anyways.</p><p><a href="https://github.com/reduxjs/redux-thunk">GitHub - reduxjs/redux-thunk: Thunk middleware for Redux</a></p><p>The anti-patterns became much more apparent when working on larger teams. It doesn’t matter which frameworks you use on your personal TODO app, but when it comes to organizations, frameworks matters a lot. As a corollary to <a href="https://en.wikipedia.org/wiki/Conway%27s_law">Conway’s Law</a>, poorly architected code can lead to poorly architected organizations and vice versa; frameworks help decide your architecture. I’ve seen the effects of poorly architected code first-hand with redux-thunk.</p><h4>Middleware is a smell</h4><p>Not all middleware is bad, especially if it’s logic that must be executed with every function call. However, it is a layer of abstraction that makes your code more difficult to understand. As a maintainer of Koa and previously Express, I felt the pain of middleware — engineers requested various middleware that handle everything for them. For example, engineers may think they want middleware to access req.currentUser on every request. However, instead of middleware, what engineers really want is a method like const currentUser = await req.getCurrentUser() which retrieves the current user only when requested. Unfortunately, for most pre-async function, callback-based frameworks like Express, this would’ve been a pain.</p><p>In fact, this has been my perspective on the complexity of the JavaScript ecosystem: so many frameworks, so many opinions, and so many libraries were created because people found JavaScript’s asynchrony complex and tedious. People’s pain with callbacks motivated them to create frameworks to halve the number of lines of codes they had to write. Most of these solutions involved “middleware”, but with the advent of async functions, there is less need for middleware.</p><p>Middleware should be using sparingly and generally for two reasons: logging and debugging. Middleware should generally not be used for business logic; any middleware that adds business logic to your system will make your system inflexible and obtuse. Although redux-thunk middleware does not contain business logic, it pushes business logic execution to the middleware, hidden from engineers who don’t know what they’re looking for. As an organization matures, this has many effects such as a decreasing velocity, a decreasing inability to innovate, and an increasing propensity to solve problems through poorly architected microservices just to escape their current trap of poorly architected middleware.</p><h4>getState() obscures data’s and action’s dependencies</h4><p>As mentioned in the <a href="https://blog.isquaredsoftware.com/2017/01/idiomatic-redux-thoughts-on-thunks-sagas-abstraction-and-reusability/#francois-ward-using-getstate-breaks-1-way-data-flow-and-obscures-actions">Idiomatic Redux Series</a>, getState() breaks <a href="https://blog.isquaredsoftware.com/2017/01/idiomatic-redux-thoughts-on-thunks-sagas-abstraction-and-reusability/#francois-ward-using-getstate-breaks-1-way-data-flow-and-obscures-actions">one-way data flow</a>. A more practical perspective of this anti-pattern is that it obscures what the data flow is—it obscures how data and actions are dependent on each other by creating implicit dependencies on the current state. Writing logic with getState() will be very easy at the beginning, but once you try to untangle and understand your thunks, especially when migrating to a new framework, you’ll realize that you just created a ball of mud.</p><p>This dependency spaghetti will make migration and innovation more difficult. You may try to migrate a page to use Apollo GraphQL using React Hooks, but you won’t realize that another page relies on data generated from your thunks until someone reports that broken page. This is especially true when your organization also has messy team dependencies where all the teams are working on the same repository without any clear delineation of ownership, which I’ve never found to be not the case. Organizational dependencies are difficult problems to solve, but code dependency problems are entirely under engineering’s control.</p><h4>thunks can cause infinite recursions</h4><p>Perhaps the most painful experience with redux-thunk is when it causes an infinite recursion. Because data and action dependencies are not explicit, a developer error could cause an infinite recursion (e.g. a thunk inadvertently calls itself later), causing pages to hang. This is especially true when you scale your organization and have multiple teams working on the same codebase—one team may inadvertently cause an infinite recursion because they didn’t know how their code affected other teams’ code. As a corollary to Conway’s Law, this specifically happens when there’s coupling: two teams and their code depend on each other.</p><p>I’ve actually dealt with this in production multiple times. The worst aspect of this error is that it’s purely client-side, so a simple deployment won’t fix it—you’ll have to tell your users to force exit their browser and clear their cache. It’s also pretty difficult to debug—you’re digging through multiple thunks that interact with each other without any explicit dependencies. It’s like trying to understand the <a href="https://www.reddit.com/r/DarK/comments/7j897c/heres_a_detailed_character_map_and_timeline_chart/">Dark timeline</a> (spoilers) while a gun is pointed at your head.</p><p>Figuring out how to split teams without coupling them or their services is a difficult problem to solve as splitting teams involves much more than just technical considerations. However, you shouldn’t make this a more difficult problem by relying on frameworks that make code coupling easier.</p><h4>Don’t use redux-thunk</h4><p>There isn’t a good reason to use redux-thunk. It’s fine for small projects, but if you have to scale technically or organizationally, you’ll run into architectural problems. It’s best to avoid it from the beginning by not depending on it at all.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8205a792e5fe" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to spot bootcamp grad resumes]]></title>
            <link>https://jongleberry.medium.com/how-to-spot-bootcamp-grad-resumes-14df5dde2da6?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/14df5dde2da6</guid>
            <category><![CDATA[job-hunting]]></category>
            <category><![CDATA[bootcamp]]></category>
            <category><![CDATA[hiring]]></category>
            <category><![CDATA[coding-bootcamp-students]]></category>
            <category><![CDATA[junior-developer]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Tue, 14 Sep 2021 18:43:11 GMT</pubDate>
            <atom:updated>2022-01-09T20:40:58.782Z</atom:updated>
            <content:encoded><![CDATA[<h4>As an engineering hiring manager, learn how to spot them so that you can hire them at the appropriate level.</h4><p>When I first became a manager, my boss told me, “We just interviewed this person and they were great. We’re going to hire them under you”. I was pretty excited at first, but after I looked at their resume, I realized that they didn’t actually have any professional engineering experience. The lack of experience wasn’t the problem—the problem was that they were paid more than they should, especially compared to their peers. Thus, I’ve written down some heuristics on how to spot bootcamp grad resumes so that hiring managers and recruiters can hire them at the correct level.</p><h4>Is their last experience an open source “project”?</h4><p>If you click on the candidate’s “experience”, does it link to a project or a site that is open source, but is built to look like a company? Do you see a GitHub icon at the top or bottom of the page? Very few companies’ core products are open source , and the ones that are, you’ve probably heard of. The fact that the candidate’s latest experience is open source is a smell that this experience is not professional. Look deeper and look at whether the project is hiring, the about us, whether it has a Wikipedia, Crunchbase, or similar article written about it to see whether this experience was professional.</p><p>Contributing to open source projects is a great way to build skills and resumes, but as a hiring manager, you want to be able to discern whether a candidate’s experience is professional. Many bootcamp projects are resume builders designed to look like companies. Be wary of projects listed in the experience section as they may not always be professional experience.</p><p>Note that this heuristic doesn’t apply to projects outside of “experience”. Projects listed elsewhere such as a “projects” section generally convey non-professional, passion projects.</p><h4>Is their last experience a devtool?</h4><p>Recently, bootcamp candidates’ team projects tend to be devtools—is the above company an open-source devtool? As my bootcamp graduate friend told me, instead of building a useless beer or wine app, the bootcamp grads would at least have dove deep into a technology such as React, Storybook, or HTTP request testing when working on a devtool. I personally don’t buy this argument since you don’t need deep understanding of the technologies you are using to be a great product engineer.</p><h4>Does their last experience list contributors?</h4><p>Another heuristic that the experience is a bootcamp project is that you’ll usually see a list of contributors on the project site. I personally don’t see the point of this—since this project is usually open source, you can go to the GitHub project and see the list of contributors through GitHub’s UI. Even for my open source projects and contributions, I don’t care much about the list of contributors as the list becomes insanely long and many people are anonymous. For professional companies, you almost never see a list of contributors.</p><h4>Is there last experience at a bootcamp?</h4><p>Many bootcamps have fellowship programs where if a candidate can’t find a job or doesn’t want to find a job, they’ll work for a bootcamp, usually the one they graduated from. Here, there will be significant title inflation—engineers will often have “Senior” or “Fellow” titles, which do not map at all to industry standards. A bootcamp’s “Senior” is going to be an industry standard “Junior”—three months is simply not enough time to reach Senior.</p><h4>Do they have a “Projects” section?</h4><p>As mentioned above, most bootcamps have team projects, which grads then add to their resume. Both bootcamp graduates and junior engineers tend to have a “Projects” section, but many bootcamp graduates tend to not show their bootcamp experience as many feel there is bias against them. Take a look at these projects and see whether it’s a solo or group project.</p><p>Showing the projects is totally fine if you have no other experience, but it doesn’t make sense if you have professional experience. Side projects are generally frowned upon at companies (e.g. they want you working at their company only) and may cause legal problems (e.g. potential conflict of interest). If you have professional experience, I don’t recommend adding any side projects unless it’s revenue-generating, VC funded, or has decent traction (e.g. has a bunch of GitHub stars).</p><p>If you’re a bootcamp graduate or junior engineer, I don’t recommend adding projects to your resume unless you add tests and the project is actually live. I’ve never seen a bootcamp grad whose projects have tests, which would immediately move them to the top of my list. I also want to see what you’ve created, but I am not going to pull your repository locally, so please host your creation. GitHub Pages is free!</p><h4>Training a Discerning Eye</h4><p>Hopefully these heuristics help you spot a bootcamp graduate and allow you to hire them at the appropriate level. This doesn’t mean that their worse candidates or that they should be avoided—I’ve hired and worked with many bootcamp graduates that were great software engineers. Instead, the only problem I’ve experienced is when bootcamp graduates aren’t properly placed in a hiring pipeline.</p><p>NOTE: This article has had many revisions as many phrases sounded anti-bootcamp graduate. Please contact me on Twitter if you have any constructive criticisms as this is not the case!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=14df5dde2da6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Speed up your CI and DX with node_modules/.cache]]></title>
            <link>https://jongleberry.medium.com/speed-up-your-ci-and-dx-with-node-modules-cache-ac8df82b7bb0?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/ac8df82b7bb0</guid>
            <category><![CDATA[github-actions]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[continuous-integration]]></category>
            <category><![CDATA[npm]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Tue, 07 Sep 2021 03:48:09 GMT</pubDate>
            <atom:updated>2021-09-07T03:51:39.529Z</atom:updated>
            <content:encoded><![CDATA[<h4>You may not need to cache your entire node_modules</h4><p>node_modules/.cache is a <a href="https://github.com/avajs/find-cache-dir">community-standard cache folder</a> for storing files. Many projects such as ava, nyc, storybook, and many webpack loaders and plugins use this folder by default. With some configuration, you can speed up your CI and developer experience by pointing other caches to this folder and persisting it across builds.</p><h4>GitHub Actions Setup</h4><p><a href="https://github.com/jonathanong/github-actions-workflow-templates/blob/master/node-server/.github/workflows/node.js.yml#L44-L55">github-actions-workflow-templates/node.js.yml at master · jonathanong/github-actions-workflow-templates</a></p><p>Here’s an <a href="https://github.com/jonathanong/github-actions-workflow-templates/blob/master/node-server/.github/workflows/node.js.yml#L44-L55">example GitHub Action</a> that caches node_modules/.cache, creating a new cache value after every run with the suffix -run-id-${{ github.run_id }}. This is in contrast to the node_modules cache that relies strictly on the hash of the manifest files. In other words, the node_modules cache should only change when the manifest changes, but the node_modules/.cache cache should be constantly updated.</p><h4>Use node_modules/.cache for your commands</h4><p>Here are some commonly used modules and how to set up their cache directories:</p><ul><li><a href="https://jestjs.io/docs/configuration#cachedirectory-string">jest</a>: set cacheDirectory: &#39;node_modules/.cache/jest&#39; in your config</li><li><a href="https://stylelint.io/user-guide/usage/cli#example-e---caching">stylelint</a>: run with --cache --cache-location=node_modules/.cache/stylelint</li><li><a href="https://eslint.org/docs/user-guide/command-line-interface#caching">eslint</a>: run with --cache --cache-location=node_modules/.cache/eslint</li><li><a href="https://webpack.js.org/loaders/babel-loader/#options">babel-loader</a>: set cacheDirectory: &#39;node_modules/.cache/babel-loader in your config</li></ul><p>With these cache directories set up, I have experienced subsequent test and lint runs take a fraction of the time, both locally and on CI. I’ve been able to eliminate a lot of workarounds with this performance gain such as hooks that only lints changed files.</p><h4>Consider caching node_modules/.cache instead of node_modules</h4><p>When set up properly, you may only need to set up caching on the .cache folder, especially if your npm ci runs very fast.</p><p>Some reasons you may not want to cache your entire node_modules folder are:</p><ul><li>On a self-hosted runner, you can rely on npm&#39;s <a href="https://docs.npmjs.com/cli/v7/commands/npm-cache#details">caching</a> mechanism, which already caches package tarballs on the runner (actions do not run in isolation, so they will have access to this folder)</li><li>Self-hosted runners will probably have a weaker connection to the cache store, making the cache slower</li><li>node_modules tends to become large and each GitHub repository has a cache limit (<a href="https://github.com/actions/cache#cache-limits">currently 5GB</a>), so caching your node_modules may evict your other caches sooner</li></ul><p>Here are some cases you may still want to cache your node_modules:</p><ul><li>Your node_modules folder is very large and caching is significantly faster than running npm ci</li><li>You have a lot of postinstall build scripts, e.g. binaries that need to be compiled</li></ul><p>My recommendation is to start with just caching node_modules/.cache, then check whether caching node_modules as well will speed up your CI.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ac8df82b7bb0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Allocating sprint capacity across features, platform, bugs, and ops]]></title>
            <link>https://jongleberry.medium.com/allocating-sprint-capacity-across-features-platform-bugs-and-ops-9e82105098f0?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/9e82105098f0</guid>
            <category><![CDATA[tech-lead]]></category>
            <category><![CDATA[engineering-mangement]]></category>
            <category><![CDATA[project-management]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[scrum]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Thu, 22 Jul 2021 11:20:19 GMT</pubDate>
            <atom:updated>2021-07-22T14:01:26.605Z</atom:updated>
            <content:encoded><![CDATA[<h4>A strategy to plan a healthy balance of product &amp; engineering work for your teams</h4><p>Every company I’ve worked at/with has struggled to prioritize engineering work against product work. Most of them have tried to solve this by dedicating a percentage of their engineering capacity on engineering work. If done right, allocating capacity across categories provides a feedback loop that can provide insight into your team’s work and will help steer your team towards healthy collaboration with product. The goal is to align on product-engineering roadmap, which may or may not end up using a framework like this.</p><h3>Categories</h3><p>First, let’s define a few categories of work.</p><h4>Innovation</h4><p>Work categorized as innovation are high-risk, high-reward and have a low chance of success. Innovation is necessary to avoid the <a href="https://52weeksofux.com/post/694598769/the-local-maximum">local maxima problem</a>, otherwise you may just be adding diminishing marginal gains to your product. This category is a privilege; the ability to innovate demonstrates the level of your product’s maturity.</p><h4>Feature</h4><p>A feature is generally any work requested by a product manager or stakeholder.</p><h4>Platform</h4><p>Platform work is either:</p><ul><li>Creating capabilities to enable Features and create Innovation</li><li>Reducing Operational overhead</li></ul><p>Platform work is an investment into the product to make it more flexible, adaptable, maintainable, scalable, etc. Although it is engineering-driven, it provides opaque benefits to the end user and to the business. It is the responsibility of engineering to clarify these benefits to stakeholders.</p><h4>Operations</h4><p>Operations work is necessary toil to keep the business running. Generally, operations work should either not exist or be automated. Examples include:</p><ul><li>Bugs</li><li>Engineering Operations such as manual migrations</li><li>DevOps such as manual deployments and manual QA</li><li>Outages and Incident Management</li><li>Business Operations such as business logic changes</li></ul><p>These operational tasks are mutually exclusive from the other categories. Some of these operational items are intentional (e.g. MVP-launch of a product that has not been automated yet). Others may be caused by a lack of user stories (e.g. from features) or from incorrectly implemented services. Operations is not owned by either product or engineering—it is a common enemy of both.</p><h4>Innovation/Features/Platform Categories are not Mutually Exclusive</h4><p>Don’t struggle to categorize work—categorization is just a framework to discuss how to plan work. Deliberating on the correct category for a work item is not going to improve the output of the work item. Create some simple heuristics to quickly categorize work. For example, if it’s product-driven, define it as a feature; if it’s engineering-driven, define it as platform work. Feel free to create new categories and break categories up.</p><h4>Define an Ideal Allocation</h4><p>Work with your product managers to define the ideal allocation of work depending on the maturity of your product. Here’s an example of an ideal allocation:</p><ul><li>Innovation: 10%</li><li>Feature: 60%</li><li>Platform: 30%</li><li>Ops: 0%</li></ul><p>You will never reach the ideal allocation, but it’s important to align on the goals such as: create a healthy product, increase velocity, and minimize operational overhead.</p><h3>Create a Feedback Loop</h3><p>Once you’ve align on the goals, it’s time to create a feedback loop.</p><h4>Measure</h4><p>After every planning period (e.g. quarterly), measure the work allocation. In JIRA, you can export your team’s completed tasks for the last few sprints to a Google spreadsheet, then categorize and visualize within the spreadsheet.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2DEj-vLSMjwhS7EiHC2Anw.png" /><figcaption>A pie chart for work allocation for one of my teams. Note that we split up the “Ops” category—“Ops” in this chart means business operations. “Data &amp; Analytics” is a subset of features as we needed more analytics tracking.</figcaption></figure><h4>Reflect</h4><p>Reflect on the work allocation in your last planning period. Here are some questions you may ask your team:</p><ul><li>What was surprising about the work this period?</li><li>What can product and engineering agree on for the next planning period?</li><li>What do we need to automate to improve velocity?</li><li>How does this work allocation affect morale? Was there too much toil?</li></ul><h4>Adjust</h4><p>After reflecting, agree on some action items for your teams. Some action items could be:</p><ul><li>Have product and engineering collaborate for causes of the bugs</li><li>Prioritize and limit the intake of operational requests from stakeholders</li><li>Add some platform initiatives to reduce engineering operations</li><li>Advocate for increased engineering capacity</li></ul><h4>Plan</h4><p>When planning for the next period, only cap how much of each category you’ll dedicate. For example, if your team completes 100 story points every period, only plan up to 60 story points for features, 30 for platform, and leave the remaining 10 for potential operational tasks.</p><h4>Repeat</h4><p>As you repeat this cycle, you’ll hopefully reach product-engineering alignment.</p><h3>The Process is for the Goal</h3><p>Remember that this process only exists to reach the goal of product-engineering alignment. If you already have alignment, then you probably don’t need this framework at all (although the graphs would be a nice visualization regardless). For example, one of my teams is working on a PHP to React microfrontend migration, which we don’t even categorize as platform or feature—instead, we try to minimize unrelated feature and operational work.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9e82105098f0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Accessing GitHub Actions Secrets for Dependabot Pull Requests on Private Repositories]]></title>
            <link>https://jongleberry.medium.com/accessing-github-actions-secrets-for-dependabot-pull-requests-on-private-repositories-b0dd6995f21b?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/b0dd6995f21b</guid>
            <category><![CDATA[dependabot]]></category>
            <category><![CDATA[github-actions]]></category>
            <category><![CDATA[github]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Tue, 22 Jun 2021 05:04:13 GMT</pubDate>
            <atom:updated>2021-06-22T05:04:13.597Z</atom:updated>
            <content:encoded><![CDATA[<h4>Recent changes in GitHub made Dependabot a pain in the ass. Here’s a potential solution for your organization.</h4><p>Recently, a bunch of <a href="https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates">Dependabot</a> PRs that required GitHub Action Secrets began to fail, which brought me to this article from GitHub:</p><p><a href="https://github.blog/changelog/2021-02-19-github-actions-workflows-triggered-by-dependabot-prs-will-run-with-read-only-permissions/">GitHub Actions: Workflows triggered by Dependabot PRs will run with read-only permissions | GitHub Changelog</a></p><p>Which lead to this article about preventing pwn requests:</p><p><a href="https://securitylab.github.com/research/github-actions-preventing-pwn-requests/">Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests</a></p><p>By no longer having access to repository secrets, Dependabot PRs in my organizations began to fail because they relied on a personal access token secret for fetching private GitHub Packages, which is currently the only authentication method for accessing private GitHub Packages outside of the current repository. I read these articles multiple times and still didn’t understand how to fix Dependabot PRs. Scouring the internet, I found a significant amount of frustration and a lot of complicated work arounds.</p><p>After a few days, I realized that there was a simple solution for my organizations.</p><h4>Disable Forking of Private Repositories</h4><p>In the <a href="https://securitylab.github.com/research/github-actions-preventing-pwn-requests/">Preventing pwn requests</a> article, the main attack vector GitHub is trying to defend against is malicious authors, but if your organization only has private repositories that do not allow forks, all your authors should be trusted (otherwise they shouldn’t be in your organization).</p><p>With proper branch protection in each repository, there isn’t a good reason to allow members of your organization to fork private repositories. Forking makes perfect sense in public, open-source projects, but not for private repositories. Thus, don’t allow forking of private repositories:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ommMCGp2F8Nax8CqFkprhw.png" /><figcaption>Disable forking of private repositories in your organization settings under “Member privileges”</figcaption></figure><h4>Only Enable Secrets for Private Repositories</h4><p>Next, don’t share secrets in any of your public repositories. Your public repositories should not need any and, if they do, you can set different secrets for them. Note that “private repositories” is the default option, so you are probably already doing this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ngFO1WdHT2B-FX4N5UX44Q.png" /><figcaption>For sensitive secrets, only grant private and internal repositories access</figcaption></figure><h4>Send Secrets to Workflows from Fork Pull Requests</h4><p>Since Dependabot PRs are treated as fork PRs, just allow sending secrets to fork PRs, but don’t allow forks in your organization. This will enable secrets just for Dependabot (that I am aware of).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fhelSPvKYVo0hIGmcG5gUA.png" /><figcaption>Enable workflows and secrets for fork pull requests in your organization settings under “Actions &gt; General”</figcaption></figure><p>It’s like GitHub never made a change!</p><h4>Things to keep in mind</h4><p>These settings just circumvent the protections GitHub is trying to provide you. To minimize the vulnerabilities, you should:</p><ul><li>Use lockfiles so that GitHub Dependabot can keep track of any vulnerabilities in your entire dependency tree</li><li>Only use trusted dependencies and consider gating which third party dependencies you allow in your applications</li><li>Try to only use personal access token secrets with read-only access (e.g. reading GitHub Packages) whenever possible—avoid creating PATs with write access</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b0dd6995f21b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fixing Performance Issues with Synology NAS w/ macOS]]></title>
            <link>https://jongleberry.medium.com/fixing-performance-issues-with-synology-nas-w-macos-cb512e5c11bd?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/cb512e5c11bd</guid>
            <category><![CDATA[synology-diskstation]]></category>
            <category><![CDATA[homelab]]></category>
            <category><![CDATA[synology]]></category>
            <category><![CDATA[nas]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Mon, 13 Jan 2020 03:19:31 GMT</pubDate>
            <atom:updated>2020-05-26T21:54:01.684Z</atom:updated>
            <content:encoded><![CDATA[<p>Synology is one of the most popular manufacturers of Network-attached Storage systems. I bought my Synology DS416play over three years ago and it never performed how I wanted it to be until recently. Here are the steps and resources I used to get it decently performant.</p><p>May 26th, 2020 Update: I upgraded to 8TB WD Red HDs and the performance increased drastically since these <a href="https://blog.westerndigital.com/wd-red-nas-drives/">higher-capacity drives do not use SMR</a>.</p><h4>Do not use AFP (Apple Filing Protocol)</h4><p>In the beginning, I used <a href="https://en.wikipedia.org/wiki/Apple_Filing_Protocol">AFP</a> because it’s written by Apple and I only use Apple devices, but of course, this is one of Apple’s proprietary formats that is being <a href="https://apple.stackexchange.com/a/285419">deprecated</a>. Instead, use SMB. <a href="https://www.synology.com/en-us/knowledgebase/DSM/help/DSM/AdminCenter/file_winmacnfs_desc">Synology lists the file-sharing protocols that are supported by each OS.</a></p><p><a href="https://apple.stackexchange.com/a/285419">Is AFP slated to be removed from future versions of macOS?</a></p><h4>Set advanced SMB settings</h4><p><a href="https://bobmckay.com/i-t-support-networking/nas-media-servers/solved-slow-transfer-speeds-synology-nas/">Solved: Slow Transfer Speeds on Synology NAS - Bob McKay&#39;s Blog</a></p><p>Bob’s post describes advanced SMB settings for better performance.</p><ul><li>Use at least SMB2</li><li>Disable transport encryption</li><li>Enable opportunistic locking</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*spoZNCJun3lEv2ceDpQ2Ng.png" /><figcaption>Advanced SMB Settings</figcaption></figure><h4>Disable Media &amp; File Indexing</h4><p>Media indexing indexes your files for Video/Audio/Photo Station while file indexing indexes your files for Universal Search. Both index your files whenever they change (e.g. create a file, delete a file, etc.) and could slow down your server for a minute or so. These indexing services quickly become a bottleneck.</p><p>A few downsides of removing indexing are:</p><ul><li>Media indexing: no more thumbnails for your media</li><li>File indexing: universal search is slower</li></ul><p>Both of these downsides were acceptable to me since I do not use Video/Audio/Photo Station.</p><p>To disable Media indexing, go to Control Panel &gt; Indexing Service and remove indexed folders. You probably also want to disable “Enable video conversion for mobile devices” as well.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ov6jN6ewRtAc5ublljYQ3A.png" /><figcaption>Control Panel &gt; Indexing Service</figcaption></figure><p>To disable File indexing, go to Universal Search, click settings (the gear icon), and remove indexed folders.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D0ruQKImKBunu52sOzm9hw.png" /><figcaption>Universal Search &gt; Preferences &gt; File Indexing</figcaption></figure><h4>Your router probably doesn’t support Dynamic Link Aggregation</h4><p>While figuring out why my NAS was so slow, I enabled Dynamic Link Aggregation. Then my NAS got even slower. After reading Synology forums, I learned that most routers don’t support Dynamic Link Aggregation (even <a href="https://www.amazon.com/gp/product/B01N5MPTG1/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B01N5MPTG1&amp;linkCode=as2&amp;tag=jongleberry-20&amp;linkId=af414ed2ecfe7af888085f58e0451737">Synology’s own router!</a>) and enabling without proper support makes your NAS slower. Transferring data between my NAS and my computers would thrash the whole network, slowing everything down. Don’t enable this feature unless your NAS is connected to a router or a switch that supports it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uJuW-VTAhXL5lFmuR-79GA.png" /></figure><h4>Cannot find resource errors</h4><p>After maybe a day, I’m unable to connect to my NAS even though the drive is still mounted. An error pops up saying, “the original item cannot be found”. The fix is to restart your Finder, but someone in the Synology forums created a script to remount your NAS drive automatically.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RS7mtS4C7h_h3lKES2CMpA.png" /></figure><p><a href="https://community.synology.com/enu/forum/7/post/123658">Synology Community</a></p><h4>Avoid huge share folders</h4><p>I had a single share folder of about 8TB, which Plex could not even index. So I decided to split the folder into two shared folders and Plex starting indexing both folders and both folders became faster to search through via Finder. Who would’ve thought this would’ve solved anything!</p><h4>Finally usable</h4><p>After applying the above fixes, my NAS was finally bearable. Browsing my content via Finder didn’t include multiple seconds of lag. Videos played almost instantly. I finally felt like I got the NAS I paid for.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cb512e5c11bd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[80/20 Image Optimization with Imgix]]></title>
            <link>https://jongleberry.medium.com/80-20-image-optimization-with-imgix-7cff8787401e?source=rss-f2bc6cc73b9c------2</link>
            <guid isPermaLink="false">https://medium.com/p/7cff8787401e</guid>
            <category><![CDATA[image-optimization]]></category>
            <category><![CDATA[web-performance]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[imgix]]></category>
            <dc:creator><![CDATA[Jongleberry]]></dc:creator>
            <pubDate>Mon, 06 Jan 2020 04:06:49 GMT</pubDate>
            <atom:updated>2020-01-06T04:06:49.644Z</atom:updated>
            <content:encoded><![CDATA[<h4>Simple basic configurations for using Imgix to optimize and serve your images.</h4><p>There are numerous blog posts on how to optimize images, but none are quite straightforward as I would like. The idea behind this post is to give you quick, direct steps to optimize your images using Imgix, though using other services would be very similar.</p><h4>Only serve your highest quality image as the master asset</h4><p>Your graphic design team shouldn’t be cropping assets themselves anymore — instead, have them upload master assets to your CMS. Have your web and mobile clients crop images themselves. For Imgix, this also lowers your costs as pricing is based on the <a href="https://www.imgix.com/pricing">active master images per month</a>.</p><h4>Only upload JPEGs, PNGs, and SVGs master image assets</h4><p>For compatibility reasons, assets should only be the above types. Do not use WebP images as your source files as <a href="https://caniuse.com/#feat=webp">they aren’t compatible with many browsers</a>. The general rule to follow is: if your image has transparency, upload a PNG, otherwise, upload a high-quality JPEG. Remember, PNG is a lossless format whereas JPEGs are not.</p><h4>Don’t serve your SVGs through Imgix</h4><p>I’ve run into issues where SVGs were served with incorrect headers even though no image transcoding was performed. <a href="https://support.imgix.com/hc/en-us/articles/204280985#svg_s">SVG support in Imgix can be enabled by contacting support</a>, which I never bothered to do.</p><h4>Setup auto=compress and fit=max as defaults</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PM_kgM0OyBXqs8ziuvrkOg.png" /><figcaption>Always compress your images to save bandwidth and increase performance.</figcaption></figure><p><a href="https://docs.imgix.com/apis/url/auto">auto=compress</a> ensures that your images are always compressed. <a href="https://docs.imgix.com/apis/url/size/fit">fit=max</a> ensures that your images are only ever scaled-down when used in conjunction with w= or h=.</p><h4>Set auto=format in every image URL</h4><p>Unfortunately, <a href="https://docs.imgix.com/apis/url/auto">auto=format</a> cannot be set as a default value, so you’ll need to add this query parameter to every single image you set in your code. This is a little tedious–I recommend test automation to ensure that all images on our site have this parameter set. This is a large bulk of image optimization as it serves <a href="https://en.wikipedia.org/wiki/WebP">WebP</a> on <a href="https://caniuse.com/#feat=webp">supported browsers</a>.</p><h4>Set w= or h= to resize images</h4><p><a href="https://docs.imgix.com/apis/url/size/w">w=</a> and <a href="https://docs.imgix.com/apis/url/size/h">h=</a> parameters set the size of an image. Set at least one of these for each image to make sure you’re using an appropriately sized image, especially if your master images are very large. In conjunction with fit=max, images will either be the same size or downsized.</p><h4>Further Reading</h4><p>You can read more at <a href="https://docs.imgix.com/apis/url">Imgix’s API Reference</a>. The only other feature I’ve planned to experiment is fm=pjpg, which should improve perceived load times, but it requires some development work with your CMS as it can only be implemented by images without transparency.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7cff8787401e" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>