Skip to content

Instantly share code, notes, and snippets.

View romgrk's full-sized avatar
♥️
hey

Rom Grk romgrk

♥️
hey
View GitHub Profile
COLORS = [
'#3366CC'
, '#DC3912'
, '#FF9900'
, '#109618'
, '#990099'
, '#575acb'
, '#ebdb0c'
, '#ed2467'
, '#66AA00'
V8
{
'react:equal:monomorphic': { average: 1206.33, stddev: 59.63406930792349 },
'react:unequal:monomorphic': { average: 1198.67, stddev: 41.51572660517404 },
'hughsk/shallow-equals:equal:monomorphic': { average: 595.33, stddev: 33.47967874530592 },
'hughsk/shallow-equals:unequal:monomorphic': { average: 559.33, stddev: 1.699673171197595 },
'romgrk-fastCompareUnsafe:equal:monomorphic': { average: 510.33, stddev: 1.247219128924647 },
'romgrk-fastCompareUnsafe:unequal:monomorphic': { average: 447.67, stddev: 2.0548046676563256 },
'romgrk-fastCompareStrict:equal:monomorphic': { average: 881.33, stddev: 1.699673171197595 },
'romgrk-fastCompareStrict:unequal:monomorphic': { average: 775.33, stddev: 0.9428090415820634 },
@romgrk
romgrk / event-base-reactivity.ts
Last active March 12, 2024 14:12
DataGrid event-based reactivity
//
// Event-based reactivity with events corresponding 1:1 with state properties
// I use "path" and "event" interchangeably.
//
// Example state model
type State = {
virtualization: {
offsetTop: number,
renderContext: {
/*
* Skipping over internal reactivity but this would be the gist of how to build a component that doesn't
* use react but still allows customization via user-supplied react-based render functions.
*
* Why? Because react is way to slow for use-cases like virtualization+scrolling. The whole cycle (state-update
* then re-render then vdom diffing then dom update) has too many unavoidable costs. Being able to go from
* state-update to dom-update directly is unbeatable.
*
* It uses react portals, so even though it manages its own HTML structure, it contains inside itself parts that
* are rendered & managed by react. And portals ensure there is full react compatibility, including the Context API,
@romgrk
romgrk / avoiding-nullable-types.md
Last active October 5, 2023 06:20
Avoiding nullable types

I've been seeing this pattern quite a bit:

// inside a component
const dimensions = useRef<DOMRect | null>(null)

useEffect(() => {
  dimensions.current = someRef.current.getBoundingClientRect()
}, []);
body {
--sk_primary_background: 38,38,38 !important;
}
.c-wysiwyg_container--theme_dark,
.c-wysiwyg_container__formatting,
.then {
background-color: #212121 !important;
}
@romgrk
romgrk / github-notifications.user.js
Last active September 20, 2023 10:53
Tampermonkey/UserJS&CSS script to enhance github notifications
// ==UserScript==
// @name github-notifications
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://github.com/notifications
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// ==/UserScript==
@romgrk
romgrk / wrapping-hooks.md
Last active September 14, 2023 01:01
romgrk ranting about react hooks

I usually like to wrap React useEffect calls inside other functions, such as useOnMount, useOnChange, useOnceTrue, etc. I've often had pushback on that, and the argument is usually "it's another abstraction layer to learn", which is a fair point. I thought I'd summarize why I think this layer of abstraction is beneficial.

Semantic clarity

One of the reasons why we use Array methods like .filter, .map or .reduce instead of using a generic for (...) loop despite their lesser performance is that they provide a higher level of expressiveness, and they make the underlying logical operation much more semantically apparent.

For example, the two following snippets perform the same operation, but the second one makes it abundantly clear with just a glance that there is a filtering operation happening.

const newItems = []
@romgrk
romgrk / fastObjectShallowCompare.ts
Last active June 2, 2023 12:08
Fastest shallow compare
const is = Object.is;
export function fastObjectShallowCompare<T extends Record<string, any> | null>(a: T, b: T) {
if (a === b) {
return true;
}
if (!(a instanceof Object) || !(b instanceof Object)) {
return false;
}
@romgrk
romgrk / store.tsx
Last active September 18, 2023 20:07
Minimal react store with selector
/*
* Usage:
*
* const abContext = Store.createContext()
*
* function Parent(props: { a: number, b: number }) {
* return (
* <Store.Provider context={abContext} value={props}>
* <ChildrenA>
* <ChildrenB>