first commit
This commit is contained in:
38
concepts/01-event-loop.md
Normal file
38
concepts/01-event-loop.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# The Event Loop
|
||||
|
||||
The event loop is how javascript code is being run in the browser.
|
||||
|
||||
The call stack is the order of code. JavaScript is a single-threaded language, which means that only one thing can be run at the time.
|
||||
|
||||
The queue is the order of which the code gets run.
|
||||
|
||||
Macrotasks and Microtasks.
|
||||
|
||||
You can block the single call stack by looping the callstack and then freeze the renders of the UI.
|
||||
|
||||
Using Microtasks(I.E Promises), you can kind of stop the blocking, but not entirely. You can flood the microtaskqueue with many concurrent microtask promises. Microtasks is also called the VIP queue.
|
||||
|
||||
When yielding to the event loop you will mix the callstack, microtask and macrotask and kind of trick javascript to render more frequent. Making it a smoother UI experience. This is great for handling hard computational data, large datasets, formatting code or processing datastreams.
|
||||
|
||||
Yielding can be done by wrapping your promises in a setTimeout(function, 0) inside the concurrenct async loop. This will add to the macrotask loop which clears the queue regularly and lets the UI render.
|
||||
|
||||
By using setTimeout you add a MacroTask in between the microtasks queue before adding a new to the macrotask(vip) queue. This opens the callstack for a render.
|
||||
|
||||
The best way to create a yielding function in modern JavaScript
|
||||
|
||||
```javascript
|
||||
// A helper function you can paste into your utils
|
||||
const yieldToMain = () => new Promise(resolve => setTimeout(resolve, 0));
|
||||
|
||||
// Usage inside your heavy AI loop
|
||||
async function processLargeData() {
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
doHeavyMath(i); // Example function
|
||||
|
||||
// Yield every 50 iterations to keep UI buttery smooth (60fps)
|
||||
if (i % 50 === 0) {
|
||||
await yieldToMain();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
33
concepts/02-generators.md
Normal file
33
concepts/02-generators.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Generators
|
||||
|
||||
Generator functions can be used to yield and use the event loop to your liking.
|
||||
|
||||
Meaning that when having to do with heavy functions or large datasets, we can open the event loop by yielding in the loop. This makes the UI i.e render between heavy functions. Combine it with setTimeout(function, 0) for great use. To unblock the UI we await a MacroTask (useTimeout()). This forces the execution out of the call stack and allows the browser to paint before continuing.
|
||||
|
||||
Generator functions are great for use when streaming data from a source. This could be token response from an AI.
|
||||
|
||||
Great for handling large datasets i.e a 10gb csv file where we can yield each line, which opens up the thread and the event loop. This is called ```Lazy Evaluation```, which means we only keep one line open in memory at a time instead of loading all of the 10gb. This is great for performance.
|
||||
|
||||
Frontend wise, it can be used in pagination or when fetching from many URLs with numbered params for example. This could allow for smooth animations when fetching as well.
|
||||
|
||||
Below is an example of mocking and processing a datastream using a generator function.
|
||||
|
||||
```typescript
|
||||
export async function* mockAIStream() {
|
||||
|
||||
const response = "this is a mock response and a lot of text text text, and a lot of text text text,and a lot of text text text,and a lot of text text text,and a lot of text text text,and a lot of text text text,and a lot of text text text lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,lot of text text text,and a lot of text text text,and a lot of text text text,,";
|
||||
const tokens = response.split(" ");
|
||||
|
||||
for (const token of tokens) {
|
||||
// Simulate the delay. Netowrk latency or anything. Process time
|
||||
const delay = Math.floor(Math.random() * 300) + 100; // Random delay between 100ms and 400ms
|
||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||
|
||||
// Yield the token. Pass it to the caller.
|
||||
yield token + " ";
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
70
concepts/03-react-vs-svelte.md
Normal file
70
concepts/03-react-vs-svelte.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 2025-12-22
|
||||
|
||||
Today we are playing around with Svelte and React.
|
||||
|
||||
Comparing the runtime and performance.
|
||||
|
||||
React and Svelte are both JavaScript frontend-frameworks for building user interfaces. Although they do the same things, they do things very differently.
|
||||
|
||||
React uses the Virtual DOM to update the UI. The Virtual DOM is something that React creates and compares to the real DOM. It then changes the real DOM based on the differences it found.
|
||||
This approach takes some extra computing/browser power because it causes a lot of renders of the DOM.
|
||||
This is not necessarily a bad thing, because the React framework is optimized to do it and can handle complex UIs very well.
|
||||
|
||||
Svelte is a little bit different. Svelte is a compiler that compiles your code to optimized JavaScript at build time. This means that there is no Virtual DOM and no extra renders. All functions and logic in the script tags are compiled to be optimized JavaScript that directly manipulates the DOM. Just like Vanilla JavaScript. This makes Svelte faster, causes fewer renders, and uses less browser power.
|
||||
This is especially beneficial for smaller applications or applications that need to run on low-power devices.
|
||||
But bigger applications can become a bit more complex to manage because of the lack of a Virtual DOM and the management of state can become tricky.
|
||||
|
||||
One isn't better that the other, but it is good to know the differences and knowing that there are multiple ways to achieve the same goal.
|
||||
|
||||
Know when to use the right framework.
|
||||
|
||||
This is an example of Svelte code.
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
console.log("Svelte Script Ran");
|
||||
// Standard Variables
|
||||
let count = 0;
|
||||
// Reactive Declarations
|
||||
$: doubleCount = count * 2;
|
||||
const increment = () => {
|
||||
count += 1;
|
||||
};
|
||||
</script>
|
||||
|
||||
<div>
|
||||
count is {count}
|
||||
Double count is {doubleCount}
|
||||
|
||||
<button onclick={increment}> Count </button>
|
||||
</div>
|
||||
|
||||
|
||||
```
|
||||
|
||||
This is an example of React code.
|
||||
|
||||
```jsx
|
||||
import React from "react";
|
||||
import "./App.css";
|
||||
|
||||
function App() {
|
||||
const [count, setCount] = React.useState(0);
|
||||
//Derived Variable
|
||||
const doubleCount = count * 2;
|
||||
|
||||
console.log("App Rendered");
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<h1>React Double Count</h1>
|
||||
<p>Count: {count}</p>
|
||||
<p>Double Count: {doubleCount}</p>
|
||||
<button onClick={() => setCount(count + 1)}>Increment Count</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
```
|
||||
99
daily-log.md
Normal file
99
daily-log.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Daily Logs
|
||||
|
||||
## 2026-01-09 () - Nand2Tetris Unit 1
|
||||
|
||||
**Task:** Finalize the last logic gate implementations for project 1.
|
||||
**Blocker:** They were hard to understand at first. The logic is not quite there for me. Hope that it later will make more sense.
|
||||
**Discovery:** A little bit of a realization of how the logic gates work together. Still a bit fuzzy. dMux4Way and all that.
|
||||
**Lesson:** HDL. Trial and error.
|
||||
**Fix:** I got it at last, and the the dMux8Way was just copy paste from dMux4Way with some adjustments.
|
||||
**Tomorrow:** Probably read up on Unit 1 again. Otherwise start Unit 2.
|
||||
**Time Spent:** 90m
|
||||
|
||||
## 2026-01-08 () - Nand2Tetris Unit 1
|
||||
|
||||
**Task:** Implementation of the HDL logic gates.
|
||||
**Blocker:** The logic behind it. The coding mindset. Need to change the mindset a bit to be more systems hardwiring. It's okay. It's a process.
|
||||
**Discovery:** Learned about a web tool that helps build the logic implementation. It clicked a little bit with the gates and creating valves instead of doing if statements in my head.
|
||||
**Lesson:** Building the logic gates. It's kind of cool.
|
||||
**Fix:** Just playing around with it. Visualizing it. Drawing the diagrams before trying to code it.
|
||||
**Tomorrow:** Finish the last Logic Gates.
|
||||
**Time Spent:** 90m
|
||||
|
||||
## 2026-01-07 () - Nand2Tetris Unit 1
|
||||
|
||||
**Task:** Getting started with the project 1 implementation.
|
||||
**Blocker:** Struggling a little bit with HDL and getting started.
|
||||
**Discovery:** That the first building blocks of gates are used on top of each other. Not, And and Or gates all build on top of each other.
|
||||
**Lesson:** HDL scriping/coding. Built And, Or and Xor gates. Wrote them i guess. Had a hard time understanding and planning the implementations. Had to look some of them up on Wiki. Not the HDL solution. Only the diagram.
|
||||
**Fix:** Researching the HDL language.
|
||||
**Tomorrow:** Continue with the Project 1 implementation. The next gates.
|
||||
**Time Spent:** 90m
|
||||
|
||||
## 2026-01-06 () - Nand2Tetris Unit 1
|
||||
|
||||
**Task:** Basically just reading and understanding the first unit of Nand2Tetris.
|
||||
**Blocker:** Understanding the logic gates and how they work together. Did not block too much. Read some sections twice.
|
||||
**Discovery:** Logic gates and how they can be combined to make more complex components. HDL.
|
||||
**Lesson:** Same as above. Reading through the material helped a lot.
|
||||
**Fix:** Nothing.
|
||||
**Tomorrow:** Starting on the first project of Unit 1. Implementation section of the first project.
|
||||
**Time Spent:** 90m.
|
||||
|
||||
## 2026-01-05 () - Nand2Tetris Start
|
||||
|
||||
**Task:** Getting started with Nand2Tetris.
|
||||
**Blocker:** Not really anything.
|
||||
**Discovery:** Read about what the project really entails.
|
||||
**Lesson:** Not much yet. Played around with their online IDE.
|
||||
**Fix:**
|
||||
**Tomorrow:** Starting Chapter 1.
|
||||
**Time Spent:** 90m.
|
||||
|
||||
## 2025-12-18 () - Svelte Mostly
|
||||
|
||||
**Task:** Play around with Svelte and get used to it.
|
||||
**Blocker:** Not really knowing the syntax.
|
||||
**Discovery:** $state, $derived, general file structure syntax.
|
||||
**Lesson:** Playing around teaches you.
|
||||
**Fix:** ...
|
||||
**Tomorrow:** Clean up and reflect on the week.
|
||||
**Time Spent:** 90m.
|
||||
|
||||
## 2025-12-17 () - Svelte, Generators
|
||||
|
||||
**Task:** Generator functions and yielding a mock stream of data.
|
||||
**Blocker:** Not being very comfortable with Vim & Svelte. Meaning slow movement.
|
||||
**Discovery:** Generator functions are pretty sweet. Helps open the call stack.
|
||||
**Lesson:** Generators, Svelte and some Vim.
|
||||
**Fix:** Not a lot.
|
||||
**Tomorrow:** Play around with Svelte and finish the UI. Learn more about Svelte.
|
||||
**Time Spent:** 90m.
|
||||
|
||||
## 2025-12-16 () - WebLLM
|
||||
|
||||
**Task:** Read up on the WebLLM and play around with it.
|
||||
**Blocker:** Had some problems with the WebGPU in the browser.
|
||||
**Discovery:** Found out that it's new technology and some browsers blacklist the use of the GPU in the browser.
|
||||
**Lesson:** Learned about about:config in Firefox and how to enable different configs and blocked things.
|
||||
**Fix:** Above lesson. Allowed it and removed the blacklist. WebLLM ran in the browser and i was ready to test it out.
|
||||
**Tomorrow:** I will create a fake stream of data in the UI and yield the results with a generator function. All in Svelte.
|
||||
**Time Spent:** 45m.
|
||||
|
||||
## 2025-12-15 (Mon) - Event Loop
|
||||
|
||||
**Task:** Play around with Event Loop and Svelte.
|
||||
**Blocker:** Understanding the Event Loop & Being new to svelte.
|
||||
**Discovery:** Svelte Setup & Syntax. Event loop yielding & Tasks.
|
||||
**Lesson:** How to yield promises. Understanding the Event Loop somewhat. Svelte syntax a little bit. Playing around with functions and loops that can crash your browser.
|
||||
**Fix:** Yielding will make hard to compute functions easier to manage for the browser and eyes.
|
||||
**Tomorrow:** WebLLM.
|
||||
|
||||
## 2025-12-11 (Tue) - Event Loop
|
||||
|
||||
**Task:** Learn and understand the Event Loop.
|
||||
**Blocker:** Needed to understand the event loop properly.
|
||||
**Discovery:** How the call stack works. Performance checking Firefox.
|
||||
**Lesson:** SvelteKit init/quick crash course. Difference between Call stack, microtask & macrotask. Also which order they're being called.
|
||||
**Fix:** Run SvelteKit app & play around with the Event Loop. /lab in the app.
|
||||
**Tomorrow:** Play around more with the Event Loop in the browser to understand properly.
|
||||
138
retrospective/week-01-retrospective.md
Normal file
138
retrospective/week-01-retrospective.md
Normal file
@@ -0,0 +1,138 @@
|
||||
2025-12-21
|
||||
|
||||
# Week 1 Retrospective
|
||||
|
||||
JavaScript is single threaded language. This means that only one task can run at a time. This is often referred to as the call stack. This means that some processes will freeze if some ongoing process will take time. I.E fetching data while rendering data in the DOM. This is not good for performance and for the experience of the end user.
|
||||
|
||||
Introducing the Event Loop, Microtasks & Macrotasks.
|
||||
|
||||
It wont make JS a multithreaded language but you can utilize some of the web-apis to delegate tasks to make it seem more multithreaded. This is cool.
|
||||
|
||||
An example is a classic for loop or for each. If heavy tasks are being run on the client while also telling the browser to paint in the DOM, it will freeze at some point.
|
||||
|
||||
Utilizing micro and macrotasks you will free up the call stack and let the DOM paint regularly while still keeping the web app smooth and functioning.
|
||||
|
||||
The order of which, things get run is.
|
||||
|
||||
1. Call stack (Synchronous code)
|
||||
2. Microtasks (Also called the VIP queue)
|
||||
3. Macrotasks
|
||||
|
||||
The call stack is the code that gets run one by one.
|
||||
Variable assignments. Math. Painting to the dom etc.
|
||||
|
||||
Macrotasks are some of the web-apis.
|
||||
In this case it's setTimeout, setInterval and so on.
|
||||
|
||||
Microtasks is the VIP queue which gets first priority.
|
||||
In this case it's the Promise api.
|
||||
|
||||
If you were to write a huge for loop of promises, you would freeze the ui until it's done. That is not good when fetching streams of data. I.E AI response.
|
||||
|
||||
Here are some examples of code that freeze the AI and some that use genereator functions to yield the response. This is mock data.
|
||||
|
||||
```JavaScript
|
||||
// 1. THE BAD WAY (Synchronous Blocking)
|
||||
// This simulates a heavy task running entirely on the Call Stack.
|
||||
function runHeavyTaskSync() {
|
||||
status = "Blocking the Main Thread...";
|
||||
|
||||
// Simulate 3 seconds of heavy CPU work
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < 3000) {
|
||||
// The CPU is stuck in this loop.
|
||||
// It CANNOT update the UI, run CSS animations, or handle clicks.
|
||||
count++;
|
||||
}
|
||||
|
||||
status = "Done (Sync)!";
|
||||
}
|
||||
|
||||
// 2. THE TRAP (Microtask Blocking)
|
||||
// Many devs think "Promises make it non-blocking." Let's test that lie.
|
||||
async function runMicrotaskTrap() {
|
||||
status = "Flooding Microtask Queue...";
|
||||
|
||||
// Imagine we have 10,000 tiny tasks
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
// Promise.resolve() puts the task in the VIP Queue (Microtask)
|
||||
await Promise.resolve();
|
||||
count++;
|
||||
}
|
||||
|
||||
status = "Done (Microtask)!";
|
||||
}
|
||||
|
||||
// 3. THE FIX (Macrotask Yielding)
|
||||
// We force the Event Loop to take a breath.
|
||||
async function runFixedTask() {
|
||||
status = "Running Smoothly (Yielding)...";
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
// Run a small chunk of work
|
||||
heavyMathChunk();
|
||||
|
||||
// THE MAGIC: setTimeout(..., 0) puts this in the Macrotask Queue (Regular Line)
|
||||
// This lets the Browser paint the screen before coming back.
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
}
|
||||
|
||||
status = "Done (Fixed)!";
|
||||
}
|
||||
|
||||
// 1. THE BAD WAY (Synchronous Blocking)
|
||||
// This simulates a heavy task running entirely on the Call Stack.
|
||||
function runHeavyTaskSync() {
|
||||
status = "Blocking the Main Thread...";
|
||||
|
||||
// Simulate 3 seconds of heavy CPU work
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < 3000) {
|
||||
// The CPU is stuck in this loop.
|
||||
// It CANNOT update the UI, run CSS animations, or handle clicks.
|
||||
count++;
|
||||
}
|
||||
|
||||
status = "Done (Sync)!";
|
||||
}
|
||||
|
||||
// 2. THE TRAP (Microtask Blocking)
|
||||
// Many devs think "Promises make it non-blocking." Let's test that lie.
|
||||
async function runMicrotaskTrap() {
|
||||
status = "Flooding Microtask Queue...";
|
||||
|
||||
// Imagine we have 10,000 tiny tasks
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
// Promise.resolve() puts the task in the VIP Queue (Microtask)
|
||||
await Promise.resolve();
|
||||
count++;
|
||||
}
|
||||
|
||||
status = "Done (Microtask)!";
|
||||
}
|
||||
|
||||
// 3. THE FIX (Macrotask Yielding)
|
||||
// We force the Event Loop to take a breath.
|
||||
async function runFixedTask() {
|
||||
status = "Running Smoothly (Yielding)...";
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
// Run a small chunk of work
|
||||
heavyMathChunk();
|
||||
|
||||
// THE MAGIC: setTimeout(..., 0) puts this in the Macrotask Queue (Regular Line)
|
||||
// This lets the Browser paint the screen before coming back.
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
}
|
||||
|
||||
status = "Done (Fixed)!";
|
||||
}
|
||||
```
|
||||
|
||||
By using microtasks(Promise) & macrotasks(setTimout) combined in loops we can open the event loop and let the browser 'breathe'.
|
||||
|
||||
This is the same as using the generator functions.
|
||||
|
||||
I have written about generators here['../concepts/02-generators.md']
|
||||
|
||||
I have been using Svelte this week, which i do not have a lot of experience with. I have learned a lot of the syntax and next week will be about the differences about React & Svelte.
|
||||
Reference in New Issue
Block a user