2023년 12월 19일 화요일

새롭지만 잘 알려지지 않은 JavaScript API 및 기능

 .groupBy()

const inventory = [
{ name: "asparagus", type: "vegetables", quantity: 5 },
{ name: "bananas", type: "fruit", quantity: 0 },
{ name: "goat", type: "meat", quantity: 23 },
{ name: "cherries", type: "fruit", quantity: 5 },
{ name: "fish", type: "meat", quantity: 22 },
];


const result = Object.groupBy(inventory, ({ type }) => type);

/* Result is:
{
vegetables: [
{ name: 'asparagus', type: 'vegetables', quantity: 5 },
],
fruit: [
{ name: "bananas", type: "fruit", quantity: 0 },
{ name: "cherries", type: "fruit", quantity: 5 }
],
meat: [
{ name: "goat", type: "meat", quantity: 23 },
{ name: "fish", type: "meat", quantity: 22 }
]
}
*/


.toSorted()

The method of instances is the copying version of the method. It returns a new array with the elements sorted in ascending order.toSorted()Arraysort()

const months = ["Mar", "Jan", "Feb", "Dec"];
const sortedMonths = months.toSorted();
console.log(sortedMonths); // ['Dec', 'Feb', 'Jan', 'Mar']
console.log(months); // ['Mar', 'Jan', 'Feb', 'Dec']

const values = [1, 10, 21, 2];
const sortedValues = values.toSorted((a, b) => a - b);
console.log(sortedValues); // [1, 2, 10, 21]
console.log(values); // [1, 10, 21, 2]


<dialog>: The Dialog element

The The HTML element represents a modal or non-modal dialog box or another interactive component, such as a dismissible alert, inspector, or subwindow.<dialog>


The HTML element is used to create both modal and non-modal dialog boxes. Modal dialog boxes interrupt interaction with the rest of the page being inert, while non-modal dialog boxes allow interaction with the rest of the page.<dialog>


JavaScript should be used to display the element. Use the method to display a modal dialog and the method to display a non-modal dialog. The dialog box can be closed using the method or using the method when submitting a that is nested within the element. Modal dialogs can also be closed by pressing the Esc key.<dialog>.showModal().show().close()dialog<form><dialog>


<dialog open>
<p>Greetings, one and all!</p>
<form method="dialog">
<button>OK</button>
</form>
</dialog>
const dialog = document.querySelector("dialog");
const showButton = document.querySelector("dialog + button");
const closeButton = document.querySelector("dialog button");

// "Show the dialog" button opens the dialog modally
showButton.addEventListener("click", () => {
dialog.showModal();
});

// "Close" button closes the dialog
closeButton.addEventListener("click", () => {
dialog.close();
});


<search>: The generic search element

The HTML element is a container representing the parts of the document or application with form controls or other content related to performing a search or filtering operation. The element semantically identifies the purpose of the element's contents as having search or filtering capabilities. The search or filtering functionality can be for the website or application, the current web page or document, or the entire Internet or subsection thereof.<search><search>

<search>
<label>
Find and filter your query
<input type="search" id="query" />
</label>
<label>
<input type="checkbox" id="exact-only" />
Exact matches only
</label>

<section>
<h3>Results:</h3>
<ul id="results">
<!-- search result content -->
</ul>
<output id="no-results">
<!-- no results content -->
</output>
</section>
</search>

This example demonstrates potential DOM content when dynamically including JavaScript search functionality in a web application. When search functionality is implemented entirely with JavaScript, if no form is submitted, neither a element nor a submit is required. For semantics, the element is included to contain the search and filtering capabilities.<form><button><search>


.findLast()

The method of instances iterates the array in reverse order and returns the value of the first element that satisfies the provided testing function. If no elements satisfy the testing function, is returned.findLast()Arrayundefined

const array1 = [5, 12, 50, 130, 44];

const found = array1.findLast((element) => element > 45);

console.log(found);
// Expected output: 130


.with()

The method of instances is the copying version of using the bracket notation to change the value of a given index. It returns a new array with the element at the given index replaced with the given value.with()Array


Creating a new array with a single changed element

const arr = [1, 2, 3, 4, 5];
console.log(arr.with(2, 6)); // [1, 2, 6, 4, 5]
console.log(arr); // [1, 2, 3, 4, 5]

With the method, you can update a single element in an array and then apply other array methods.with()

const arr = [1, 2, 3, 4, 5];
console.log(arr.with(2, 6).map((x) => x ** 2)); // [1, 4, 36, 16, 25]

The method creates and returns a new array. It reads the property of and then accesses each property whose key is a nonnegative integer less than . As each property of is accessed, the array element having an index equal to the key of the property is set to the value of the property. Finally, the array value at is set to .with() length this length this index value

const arrayLike = {
length: 3,
unrelated: "foo",
0: 5,
2: 4,
3: 3, // ignored by with() since length is 3
};
console.log(Array.prototype.with.call(arrayLike, 0, 1));
// [ 1, undefined, 4 ]


Use “await” at the top level of a module

from mdnThe await operator is used to wait for a Promise and get its fulfillment value.

const getUserInfo = () => {
return new Promise((rs) => {
setTimeout(() => {
rs({
name: 'fatfish'
})
}, 2000)
})
}
// If you want to use await, you must use the async function.
const fetch = async () => {
const userInfo = await getUserInfo()
console.log('userInfo', userInfo)
}

fetch()
// SyntaxError: await is only valid in async functions
const userInfo = await getUserInfo()
console.log('userInfo', userInfo)

In fact, after ES13, we can use await at the top level of a module, which is a really happy new feature for developers. That’s great.

const getUserInfo = () => {
return new Promise((rs) => {
setTimeout(() => {
rs({
name: 'fatfish'
})
}, 2000)
})
}

const userInfo = await getUserInfo()
console.log('userInfo', userInfo)

Use “#” to declare private properties

In the past, we used "_" To represent private properties, but it is not secure and may still be modified externally.

class Person {
constructor (name) {
this._money = 1
this.name = name
}

get money () {
return this._money
}
set money (money) {
this._money = money
}
showMoney () {
console.log(this._money)
}
}

const p1 = new Person('fatfish')

console.log(p1.money) // 1
console.log(p1._money) // 1
p1._money = 2 // Modify private property _money from outside
console.log(p1.money) // 2
console.log(p1._money) // 2

We can use “#” to implement truly secure private properties

class Person {
#money=1
constructor (name) {
this.name = name
}
get money () {
return this.#money
}
set money (money) {
this.#money = money
}
showMoney () {
console.log(this.#money)
}
}
const p1 = new Person('fatfish')
console.log(p1.money) // 1
// p1.#money = 2 // We cannot modify #money in this way
p1.money = 2
console.log(p1.money) // 2
// Uncaught SyntaxError: Private field '#money' must be declared
// in an enclosing classconsole.log(p1.#money)


Easier to set member variables for classes

class Person {
constructor () {
this.age = 1000
this.name = 'fatfish'
}

showInfo (key) {
console.log(this[ key ])
}
}
const p1 = new Person()
p1.showInfo('name') // fatfish
p1.showInfo('age') // 1000

Now you can use the following way, which is really more convenient to use.

class Person {
age = 1000
name = 'fatfish'
showInfo (key) {
console.log(this[ key ])
}
}

const p1 = new Person()
p1.showInfo('name') // fatfish
p1.showInfo('age') // 1000


FileReader API

https://12daysofweb.dev/2023/filereader-api/



2023년 8월 7일 월요일

Create a Screen Recorder with Simple JavaScript

 Create a Screen Recorder with Simple JavaScript | by Anirudh Munipalli | Jun, 2023 | Medium

Image Optimization Tricks

1. Image Formats

a. WebP

<!-- 👇 Set image sources with different formats in the `srcSet` 
the attribute in order of preference -->

<!-- 👇 Fallback image source for browsers that don't
support srcSet in `src` attribute -->

<img
srcset="car.webp, car.jpg"
src="car.jpg"
alt="Car"
/>

b. JPEG 2000

<img
srcset="car.jp2, car.jpg"
src="car.jpg"
alt="Car"
/>

c. AVIF

<img
srcset="car.avif, car.jpg"
src="car.jpg"
alt="Car"
/>

2. Responsive Images

<img src="small.jpg"
srcset="medium.jpg 800w,
large.jpg 1200w,
xlarge.jpg 1600w"

sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
33vw"

alt="Responsive Image">

3. Lazy Loading

<img src="image.jpg" alt="Image" loading="lazy">

4. Preloading and Caching

<link rel="preload" href="image.jpg" as="image">


// Service worker code (sw.js)
self.addEventListener('install', event => {
event.waitUntil(
caches.open('images-cache').then(cache => {
return cache.addAll([
'image.jpg',
'other-image.jpg',
// Add more images to the cache here
]);
})
);
});

self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});

In a React app, you can use the package to add the preload link in the HTML head section for critical imagesreact-helmet

import React from 'react';
import { Helmet } from 'react-helmet';
import PreloadImage from './assets/preload-image.png';

const ImageComponent = () => {
return (
<>
<Helmet>
<link rel="preload" href={PreloadImage} as="image" />
</Helmet>
<img src={PreloadImage} alt="Preload image alt" />
</>

);
};

5. Image Sprites

An image sprite sheet is a single image that contains multiple smaller images or icons. It’s used to reduce the number of HTTP requests when rendering numerous small images on a web page. By loading a single sprite sheet, you can display specific images by adjusting the CSS background-position.

Suppose you are building a social media web application and want to display various icons for actions such as liking a post, commenting, and sharing. Each icon is a small image that is typically used in different parts of the application.

Without Image Sprites:

In a traditional approach, you would include each icon as a separate image file in your HTML or CSS, like this:

<!-- Separate images for each icon -->
<img src="like-icon.png" alt="Like">
<img src="comment-icon.png" alt="Comment">
<img src="share-icon.png" alt="Share">
<!-- and so on... -->

With Image Sprites:

Using image sprites, you can combine all these icons into a single sprite sheet, reducing the number of HTTP requests. Here’s an example of how it would look:

/* CSS using image sprites */
.icon {
background-image: url("icons-sprite.png");
background-repeat: no-repeat;
}

.like-icon {
background-position: 0 0;
width: 24px;
height: 24px;
}

.comment-icon {
background-position: -24px 0;
width: 24px;
height: 24px;
}

.share-icon {
background-position: -48px 0;
width: 24px;
height: 24px;
}

/* and so on... */
<div class="icon like-icon"></div>
<div class="icon comment-icon"></div>
<div class="icon share-icon"></div>

In this example, all the icons (like, comment, share, etc.) are combined into a single sprite sheet. The CSS classes (e.g., , , ) use the property to display the correct part of the sprite sheet as the background for each icon.icons-sprite.png.like-icon.comment-icon.share-iconbackground-position

Benefits:

  • Instead of loading multiple image files, the web application now loads just one image (), reducing the number of HTTP requests.icons-sprite.png
  • The sprite sheet is loaded once and can be cached by the browser, improving subsequent page loads.
  • CSS classes control the display of individual icons from the sprite sheet, allowing for seamless hover and rollover effects without additional loading delays.
  • This leads to faster and more efficient user experiences with improved overall page loading times.


6. Use SVG for icons and logos

<!-- logo.svg -->
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>

<!-- index.html -->
<img src="logo.svg" alt="Logo">


7. Image Dimensions

Specifying the image’s dimensions in HTML or CSS is essential to prevent layout shifts and improve page rendering speed. By specifying the image’s dimensions in HTML or CSS, you provide the browser with the necessary information to allocate the correct space for the image during the initial rendering process.

Benefits

  • Prevents Layout Shifts: Specifying the dimensions ensures that the browser knows the image’s exact size before loading it, preventing sudden layout shifts.
  • Faster Page Rendering: With the image dimensions known in advance, the browser can render the layout more efficiently, leading to faster page loading times.
  • Improved User Experience: By eliminating layout shifts, users have a more consistent and pleasant browsing experience.

To specify the image dimensions, you can directly include the and attributes within the tag or apply a specific style by adding a class attribute to the tag in CSS.widthheight<img><img>

<img src="logo.jpg" alt="logo" width="300" height="200" />

<!-- or -->

.logo {
width: 300px;
height: 200px;
}

<img src="logo.jpg" alt="logo" class="logo" />