6 ms·
Here's one I did as an assignment for a job interview: https://github.com/ivancuric/hn-scroll https://github.com/ivancuric/hn-scroll You can see it in action h
by baxuz 7y ago
Here's one I did as an assignment for a job interview:
https://github.com/ivancuric/hn-scroll https://github.com/ivancuric/hn-scroll
You can see it in action here:
https://hn-scroll.netlify.com/ https://hn-scroll.netlify.com/
The task was to build an offline capable site which displayed the latest Hacker News posts, and loaded more lazily when scrolling.
I had to use the official HN API, and I couldn't have any middleware or caching. Everything had to be done client-side.
The app ended up being 1.4kb in total, with support for practically streaming in the items, batching them by network response times and render frames, while keeping the order.
You can see the batched items in this version: https://codesandbox.io/s/hardcore-stonebraker-8m8fx https://codesandbox.io/s/hardcore-stonebraker-8m8fx
- mjfisher 7y agoThat's a nice, clean, simple approach - I learned about `createContextualFragment()`, so thanks! I wanted to ask, did the company you were interviewing for tell you what they wanted to get out of the assignment on their end - specifically what they were assessing you on?
- baxuz 7y agoThanks! I really appreciate that! I think I can post the evaluation criteria: 1) App performance. We will be looking at the wait times for reader to see the content — the shorter, the better. 2) We will evaluate your code’s quality. Does your code have good modular design and testability? Is it easy to read? 3) We prefer the project to be lightweight, and all dependencies should be well justified. I was focusing on #1 and #3. As for #2, they found it too tightly coupled and hard to read. I thought that the app is simple enough to not warrant extracting modules in the main app logic. The coupling was also there for performance / filesize reasons.
- abraae 7y agoYour comment makes me imagine a more nuanced technical interview process - i.e you get to provide feedback to criticisms from the interviewer, you get to escalate/request review from someone else at the employer if you disagree with the interviewer. A platform ensures that the protocols are abided by by both employer and candidate. These sorts of interactions sound pretty far out now, but a few years ago who would have thought that people would be typing code into a web page in real time as part of a job interview process?
- baxuz 7y agoIt wasn't real time, but a home assingment. Sadly, I didn't get a chance to provide feedback to the criticisms. At least not in an impactful way — the decision has been made.
- spuz 7y agoSo were you hired or not?
- baxuz 7y agoNope
- mnsc 7y agoCan you estimate how much time you put into the assignment? Did you get paid?
- baxuz 7y agoProbably a bit more than 12h, and I have to give it to the company, the project was compensated. This was the only time I've experienced that.
- bovermyer 7y agoI distrust any interview that includes something like this. It's an arbitrary construct that is not indicative of what form the work will take. Only the first three months of working with someone will give any real indication of what'll be like to work with them for another three+ years.
- shams93 7y agoYeah we created a test for our interview but we give it onsite I think requiring people to do work even if its compensated is wrong, its not that hard to put together a small exam based on the source for your projects to analyze whether a candidate can handle the work.
- wackget 7y agoToo tightly coupled? Fuck me. I'd have given them a single .js file. There's a point where decoupling everything is just a complete waste of time. Sounds like the company was run by idealistic developers who have never had to work under real-world deadlines.
- baxuz 7y agoInitially it was a single TS file. I did this since one of the requirements was for it to be modular and testable.
- roebk 7y agoI just wanted to say I learned a few things reading through the source. Great work :)
- baxuz 7y agoThanks! Really means a lot to me.
- Blaiz0r 7y agoThis runs nice and fast. Out of interest, why did you use display: flex; on the li's and add the list number inside div's?
- baxuz 7y agoThey could also have been articles, probably also better for a11y. The browser's implementation of numbering ol's is to align them to the right and render them hanging. They don't impact the layout, much like position: absolute, and they grow to the left. The default ol/ul behaviour leaves some space to the left where the bullets/numbers should fit. This means you need to take into account the maximum width of the number. I had no idea how much is the limit of the API, could have been thousands of items, and I didn't want to leave space for four digits until you scroll down to item #1234 I could also have implemented this using CSS `counter-increment` and `content`, but this was a better approach for debugging if the articles were rendering in the right order, while the CSS approach only takes into consideration the amount of DOM nodes.
- Blaiz0r 7y agoYes, that's a good consideration, large numbers may have become unwieldy. I think I would have preferred other html elements over the div even with flexbox css, but it's good to hear your reasoning over this.
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- erikbye 7y agoHeads up: I'm using Firefox, and the posts do not appear until I move the mouse cursor.
- baxuz 7y agoWorks here on Firefox Dev. Try refreshing, there was a bug I missed with the api returning 200 for a post, but the content was `null`. Fixed it, but you still might have the old cached JS due to the service workers.
- deleted 7y ago[deleted]
- tekkk 7y agoThat's nice. I myself did try out one too, as a hobby project to serve as an alternative frontend for a local gym https://varjosport.net/ https://varjosport.net/ There's a small flicker as the app generates the HTML which still annoys me but I couldn't bother to write a Lambda to server-side render the HTML every time the data is refreshed. One thing I noticed though was that creating HTML fragments is a major pain in the ass, which I see you've solved with .createContextualFragment Interesting, I might have to try that one out too. I myself quite immediately after starting to parse my JSON payload and turning it into dynamic HTML elements turned to Preact, which I guess as a lesser version of React is an acceptable choice. One thing which still was left to irk me were the CSS classes. I'm not a big fan of writing them anymore, with BEM syntax or not. Styled Components in my opinion is the future of writing modular React/web components. But since I vowed to myself to keep this simple, I stuck with CSS. But it's indeed an interesting project to create a minimal modern website without the massive toolings/libraries you normally take for granted with React etc. There's a lesson there to be learnt in how sometimes that complexity is unnecessary, but sadly it's often not in the scope of a project to start optimizing such things. And I can't blame them, since when things get complicated you much rather have your app already written in React than having to rewrite it from custom JS/TS mess.
- dsego 7y agoWith styles in components, can you support skinnable components? If so, do you have to accept parameters in the component and modify the component every time you want to change some style to make it fit with your page look and feel?
- e12e 7y agoI recently came across this, you might find the approach interesting (even if not using the CodyHouse framework as such): https://codyhouse.co/blog/post/css-custom-properties-vs-sass-variables https://codyhouse.co/blog/post/css-custom-properties-vs-sass...
- tekkk 7y agoIf you mean theming components, then yes. Skinnable components is not a term I've encountered before but theming is something SC enables and is part of its core functionality. You can either use something like a global theme variable to set styles, which each component can depend on or just the regular props for different styles eg <Button intent="success /> I myself have mostly just remained with a one default theme, although adding a dark-theme has crossed my mind several times. It's just that UI features like this are rarely on top of the to-do list.
- wackget 7y agoThere's an irony about posting in a topic about simple, vanilla, no-framework scripting and then linking to a repository with the following unnecessary ancillary files: .gitignore .prettierrc README.md REQUIREMENTS.md manifest.webmanifest package.json tsconfig.json yarn.lock Plus the actual source code is spread over four TypeScript files, JavaScript, CSS, and HTML. This isn't meant as criticism of your code specifically but of "modern" web development which hypocritically espouses simplicity but actually increases complexity of development. My point is your app could have been a single HTML file (or HTML, JavaScript, and CSS if you want to split hairs). Instead there's 15+ files because that's the state of modern development.
- wilsonrocks 7y agoA lot of people think a README file is important.
- apazzolini 7y agoRight, OP totally should have included the interview question requirements as a commented block at the top of index.html instead of separating it out. It's way too complex as is. And definitely, .gitignore is well known to be responsible for the "complexity of web development." Maybe we should include .gitignore in index.html too?
- anarchodev 7y agoGitIgnore.jsx IMO
- StreamBright 7y agoThese files are supposed to be in every single folder nowadays.
- cc81 7y ago>.prettierrc Just to take that example. Prettier made the state of modern web development so much better.
- dentemple 7y ago
- fortran90 7y agoI want to understand how this works completely client-side without any server side support. Normally, I would expect that when I am visiting hn-scroll.netlify.com, any API calls to hacker-news.firebaseio.com would get blocked by the browser to prevent cross-origin request. But your app does work fine and the source code at https://github.com/ivancuric/hn-scroll/blob/master/src/sw.js https://github.com/ivancuric/hn-scroll/blob/master/src/sw.js also seems to be working fine. How is this app able to make cross-origin request? Can someone explain the security principles behind this to me?