Introduction

Recently, I came across an article on the front-end community on Facebook: Understanding React useEffect 02, which discusses the usage of useEffect. There was also some discussion in the comments section.

Initially, I found the usage in the article a bit strange, but I could somewhat understand why it was written that way. However, I still found it odd. I wanted to leave a comment, but then I thought, “Maybe I’m the one who’s mistaken,” so I decided to think about it some more. After careful consideration, I realized that I was the one who was mistaken.

Therefore, in this post, I will share my thoughts. If there are any mistakes, please feel free to leave a comment below or discuss it with me in the front-end community. Before continuing to read, I recommend reading the original article and the discussion below it to better understand the context.

Read More

Introduction

If you want to store something in the front-end of a website, which means storing it in the browser, there are basically a few options:

  1. Cookie
  2. LocalStorage
  3. SessionStorage
  4. IndexedDB
  5. Web SQL

The last two are rarely used, and the last one, Web SQL, was declared deprecated a few years ago. Therefore, when it comes to storing data, most people mention the first three, with the first two being the most commonly used.

After all, when storing data in the front-end, most data is expected to be stored for a period of time, and cookies and localStorage are designed for this purpose. However, sessionStorage is not, as it is only suitable for storing very short-term data.

I don’t know if your understanding of sessionStorage is the same as mine, so let me explain my understanding:

The biggest difference between sessionStorage and localStorage is that the former only exists in one tab. When you close the tab, the data is cleared, so a new tab will have a new sessionStorage, and different tabs will not share the same sessionStorage. However, if it is the same website, the same localStorage can be shared.

But let me ask you this: Is it possible that in a certain scenario, I store something in sessionStorage in tab A, and then a new tab B can also read the sessionStorage in tab A?

You might think it’s impossible, and I used to think so too, as did my colleagues.

But it turns out that it is possible.

Read More

Introduction

Have you ever heard of vite? With a name starting with “v”, you might guess that it’s related to Vue. Yes, it’s another tool developed by the creator of Vue, Evan You. Originally intended for use with VuePress, it has proven to be much more versatile.

On the GitHub page for Vite, there are only two sentences:

Native-ESM powered web dev build tool. It’s fast.

If you’ve tried it, you’ll know that it really is fast. Vite is a combination of a build tool and a dev server. In this article, we’ll briefly introduce how to use Vite, then talk about ES modules, and finally explore the magic of Vite.

Read More

Introduction

While making some performance adjustments at work, I accidentally discovered a strange phenomenon. After investigating further, I found a bug that seemed to have gone unnoticed by anyone, and I found the cause quite interesting. So I thought I’d write a post to share it with everyone.

This post is not very technical, so you can read it with a story-telling mindset, which will make it more interesting.

The Beginning of the Story

The origin of the story is that I was making some adjustments to a website at work, trying to improve its loading speed. When it comes to performance optimization, there are many things that can be done. For example, with regard to the server, the following are more relevant:

  1. Use HTTP/2
  2. Use gzip or brotli for compression
  3. Use Cache (to speed up revisits)
  4. Use CDN
  5. Reduce TTFB time

However, all of the above require assistance from the backend or SRE, and are not very relevant to the frontend. With regard to the frontend, there are many aspects to consider. For example, from the perspective of “reducing resources,” the following can be done:

  1. Image format adjustment (compression + webp or other formats)
  2. JS size (ugligy, code splitting, dynamic import)
  3. CSS size (minify, remove unnecessary CSS)

From the perspective of “accelerating the loading of important resources,” preload or preconnect hints can be added to indicate to the browser which things should be loaded first.

You can also look at it from the perspective of “reducing JS execution time.” For example, if you are writing React, you can use shouldComponentUpdate, PureComponent, or memo to reduce unnecessary re-renders.

Since the title of this post is “styled components,” the main topic is, of course, centered around CSS.

Read More

Introduction

To learn something new, it’s not very useful to just read about it. The best way is to get your hands dirty and start doing it. Since React hooks had just come out when I was about to leave my previous job, I had never written hooks before, only seen some basic tutorials. But after starting my new job, I finally started writing function components + hooks.

Although I initially missed the class syntax, I found hooks to be quite good after writing them for a while. In the process of using hooks, I also encountered some common problems that people who are new to them often face. After careful study, I found that the case I want to discuss in this article is quite good. If you can understand this case, you should be able to grasp the fundamental differences between class and function components. Therefore, I wrote this article to record my experience.

By the way, if you have been writing function components for a while, are quite used to hooks, and have read the official documentation and Dan Abramov’s articles carefully, you probably won’t gain any new knowledge from this article. This article is suitable for those who have just switched to function components and are not sure what the differences are between them and class components.

Read More

Introduction

Recently, I came across a great tutorial on Regular Expressions for Regular Folk, which is well-written and beautifully designed. Since Regular Expressions are commonly used in development, but not covered in my course, I decided to write a simple article on this topic.

This article is intended for beginners who have no idea what Regular Expressions are. Therefore, the explanations will be relatively simple, and the examples will be relatively easy to understand. The patterns will also be relatively fixed, with fewer boundary conditions to consider, making it easier to learn.

Alright, let’s get started!

Read More

Introduction

If you have written functions in other programming languages that are not first-class, you may experience some pain when writing JavaScript and wonder what you are doing - at least that’s how I feel.

When I first discovered that functions can be passed around as parameters, I had to think hard about more complex code, and other behaviors of functions also confused me, such as the fact that functions are also objects, and what exactly is this.

This article mainly wants to share some interesting aspects of functions. However, it is too boring to start talking about a lot of knowledge directly. I hope to arouse everyone’s curiosity about this knowledge. The best way to arouse curiosity is to provide a “question that you will also be interested in”. You will have the motivation to continue reading.

Therefore, the following uses a few small questions as the opening. Although they are in the form of questions, it doesn’t matter if you can’t answer them. If you are interested in the answers to these questions, please continue reading. If you are not interested, just go straight ahead and turn left at the end.

By the way, the title of this article was originally intended to be called “How much do you know about JavaScript functions” or “Interesting JavaScript functions”, but these titles are too boring, so I thought of this light novel-style (?) title.

Read More

Preface

I wrote this article because I believe that many people have encountered this problem. In summary, when using console.log to print an object, the printed value is different from what you expected. Let’s take a look at the code below:

Read More

Introduction

First, let’s briefly introduce what an Online Judge (OJ) system is. Simply put, it is a system like LeetCode that allows you to submit code for problem-solving and then lets the system check it and give you the final result. Below is a screenshot of LeetCode:

LeetCode interface

Before LeetCode became popular, the most well-known OJ was probably UVa Online Judge, also known as ACM. In Taiwan, ZeroJudge is more famous.

If you happen to have a need and want to build your own OJ, what should you do?

Read More

Introduction

In two of my previous articles, I Know You Understand Hoisting, But Do You Really Understand It? and All Functions Are Closures: Discussing Scope and Closure in JS, I talked about the differences between the scopes of let and var.

The scope of let is block, while var is function. This is a classic example:

for(var i=1; i<=10; i++) {
  setTimeout(function() {
    console.log(i)
  })
}

It was originally expected to output 1 to 10 in order, but unexpectedly output 10 11s. The reason behind this is that the i on the third line always has only one, which is the var i declared in the for loop, and it is the same variable from beginning to end.

The classic solution is also very simple, just change var to let:

for(let i=1; i<=10; i++) {
  setTimeout(function() {
    console.log(i)
  })
}

The reason why this works is that the above code can be seen as the following form:

{
 let i=1
 setTimeout(function() {
    console.log(i)
  })
}

{
 let i=2
 setTimeout(function() {
    console.log(i)
  })
}

...

{
 let i=10
 setTimeout(function() {
    console.log(i)
  })
}

Since the scope of let is block, there is actually a new i in each round of the loop, so there are 10 different i after the loop runs 10 times, and of course, 10 different numbers are output in the end.

Therefore, the biggest difference between var and let in this example is the number of variables, the former has only one, while the latter has 10.

Okay, now that you know the difference between let and var, let’s take a look at the main issue of this article.

In fact, this issue comes from a question raised by @getify, the author of YDKJS (You Don’t Know JS), on his Twitter:

question for JS engines devs…
is there an optimization in place for this kind of code?

for (let i = 0; i < 10; i++) {
  // no closure
}

IOW, where the behavior of creating a new i per iteration is not needed nor observable… does JS skip doing it?

If you didn’t understand it very well, you can continue to read the other tweet:

here’s a variation on the question… will JS engines exhibit much performance difference between these two loops?

for (var i = 0; i < 100000000; i++) {
   // do some stuff, but not closure
}

for (let i = 0; i < 100000000; i++) {
   // do the same stuff (no closure)
}

Simply put, when we usually use let with loops, isn’t it like we said above, there will be a new i in each round? If so, then there should be a performance difference between var and let, because let must new a new variable in each round, so let will be slower.

If the loop does not need a new i in each round, will the JS engine optimize it? This issue is mainly to explore whether the JS engine will optimize this behavior.

So how do we know? Either you are a JS engine developer, or you can look at the JS bytecode, but both of these difficulties are a bit too high. But don’t worry, there is a third way: look at the JS bytecode.

Read More