This content outlines a system design approach for creating reusable front-end components, specifically focusing on a customizable search widget. It details the process from requirement gathering to optimization and accessibility, emphasizing component-level design over traditional API-centric system design.
Mind Map
Click to expand
Click to explore the full interactive mind map • Zoom, pan, and navigate
hi
this is ray and welcome to the five
series of system design series for front
end engineers
and today we are going to look at the
interesting problem which is a very
common stuff on the
facebook interview or amazon interview
when you need to design some not the
product itself or you need to design the
component and the designing of component
is a bit more different than we
did on the previous uh system design videos
videos
because here you need to think not about
the api you
work with on the server and about data
entities you get from the server
uh you need to think about the the
component itself how can we use it
across our application what api we
would like to provide with our component
and so on
so this is quite different approach but
i think this would be useful also to
design it because
uh if you have this on an interview you
will be prepared
okay um as usual we start with our
general plan
and i really like this plan because this
helped us
just to go like point by point
and we see the whole plan of the our
discussion so i've created the
prepared schema of this system design plan
plan
and as the first step we are going to
collect the
requirements for our uh for our system design
design
and then we proceed with the gener so
general requirements is
uh about the like core functionality
we'd like to have for
uh our uh widget and the functional
requirements actually our most specific one
one
it's about the some technical details
of our component what is the cache size
or how can we configure it
and then we proceed to the components architecture
architecture
so the components architecture is the
same as we did uh on the previous interviews
interviews
uh it's like the high level on top of
the our component and the
of course the dependency graph so the
fourth point is the
data entity so for this interview we
won't have any data into this stuff so
i'll simply delete this so and then we
proceed to the
api design so our widget should be
should be used in different places on
our websites such as
likes you can search for people you can search
search
on the like header or you can place the
search in some
form and try to have to complete the
results and so on so
basically uh this is the api design of the
the
widget so how we can how the user can
use it this widget on their applications
then we proceed to the store design so
the store design
uh means that not for the whole
application but for widget itself so the
widget can help
can have its own state and this is about it
it
so then we proceed to optimization and accessibility
accessibility
so let's start with the general
requirements for our
for actually for our widget so the first
and i think the most obvious one is that
um widget widget provides the search
results in the format of item
based on the query which user inputs so
items result based on the query
typed in so this is our
first requirement for the uh our widget
so what is the second requirement so
the widget should be used on uh many
places and we'd like
uh to have the item the look of the item
to be customizable that
this means that the user defines the
look of the item itself so we can search
for some people and display the avatar with
with
text then we can search for some maybe groups
groups
or some uh other stuff and this
results how it should like the user
define it we provide the api for this so
the search results should
should be customizable
and in terms of uh search widget
so we actually saw the widget can work
either with static data or
the asynchronous data and we'd like to
support both so
let's say that the widget can work with
any data format and
also with static or
sync data so what means within any data so
so
we have lots of entities and they looks
very different
and this means that we need to somehow
to provide api to work with any data format
format
and this is so this is my third
requirement for for this
okay what do you what's actually is the
functional requirements so regarding the
functional requirements
i see the first that because user types
a lot
we need to save the traffic we don't
want to like ask the for the server each
type so
uh the second step is that it's actually
refers to the network efficiency so
we need to have uh we won't we
want to cache results inside our search suggestions
suggestions
okay uh where else can we add so the
so this means that we um so this means
that we can
provide with the properties some core configuration
configuration
we can also provide the filter function
so the filter function actually it's
something that
triggers the search when the user types in
in
so and we also would like to have the
item representation
so the user can pass the actually the item
item
we'd like to represent in our search results
results
okay what else can we add so i also see
the parameter like
mean query this means that for example
if we set mean query to 10
then we don't do any filtering until the
string size of the query becomes 10 so
i think this is a quite useful parameter for
for
for our app so we have the cache size
filter function
item representation mean query uh what
else can we
add here um
okay i think we can go like this
but um if we have some additional
properties we'll set this
okay so what is the actually fourth
requirement is we
and do we have it so i'd like to have that
that
widget should work with on wide range of devices
and be accessible
from keyboard and we can also add
okay what is the flight point um
yeah it should be performance optimized
optimized optimized
we added though so we've collected the
whole requirements stuff
and we now can proceed with the actually
the first
and the first step it's a high-level
mock-up design
so let's let's proceed to it so we
place the label and say that it's a components
components architecture
so components architecture and then
we need to create a mock-up with the
search suggestions so i have a schema
for that
so the search suggestions contains just
a simple
input and the result items so the result items
items
showed when the user types in and we
send the query
to the server and we display the results
so this is the very simple schema let's
define the actual
graph of that so this is the dependency tree
tree
so we have the search suggestion
complaint it contains the search input
and suggestion list with the suggestion result
result
i emphasize that suggestion result is green
green
because this template is provided by the user
user
so this thing is highly customizable from
from
from the user side and we do not provide
by default the suggestion result item so
this can be
anything we want to have
so the suggestion list is a simple like
drop down list
which contains all the suggestion
results and this is our
components architecture and we can
straight proceed to the
actual uh api design of the our
components so what is the api design of
the component
so i will call it not an api design but
so property design and let's say that
we need to think about the properties we have
have
uh in our components
so uh i create the typescript notation
here as usual
just to provide the some syntax for
property descriptions so i said that
it's a
type props and we have the typing and i
explain it why i need this
okay first first property we'd like to have
have
is the get results function
so get result function it's it's
actually takes
e it's uh give us the query
string which uh user types and types in
and then we
and then we'll return the promise of the
some type array so why i need
t here so because we'd like to work with
any data
i mean with any type of of the data we
do not depend on any type and we provide
the generic type t
so this is why i use the t notation here
so what else we need here is that uh
so we have the get results and i also
want to have the mean query parameter
which takes
the number and by default this will be
free so
when have three symbols we ask for the
search results
so i also would like to have like max results
results
this is the number and by default it's
10 so this means that
we have the max results and for example
if we set it to 10 and we have like 100
results then we show only 10
um like only 10 results
and if you want to show more than we
scroll down
and we update this item so we only have 10
10
constant dom items in the search suggestions
okay so we have the min query
match results and we also need to have like
like
item ranger item
so the writer ranger item it's a user
defined function
which takes um so which
oh sorry it's not takes an element as a
parameter but
it takes the datum see a single data
piece so there is a parameter and
returns the html element as a result so
the user provides a function so which
builds the html item
based on the datum we passed
to the user function and i also
would like to have like update item function
it takes a html element
and returns nothing so what is the
update for
item function this is the function which
is responsible for the
update of the existing dome element as
remember we'd like to have
10 constant dom elements on our component
component
and we could go with an approach where
we're removing
all elements and inserting dom new ones
but this is not efficient from the performance
performance
side and we reuse our existing
components and just update their data
so all of this is more optimized
from the performance perspective and you
know the user
which can be optional so if your user
can wants to provide this function then
he provided if not then we just
rendering the stuff
um okay so we have the
get results with query max results
render item
um and i feel like actually
we are almost done here we can also say
that we
provide the class name so if the user
wants some custom class name
okay we have the property api for our
uh component and then uh let's
proceed to the uh to the next thing
is the store organization so what is the
store organization it's the front-end
data we store in our application
um so i'll copy this out and
we have compo
state state design
so the same design and for that i also
have a schema so this is our state
so our state contains the result map
so the result map uh is the
sun okay and i think i need to copy the
dependency tree
in order to give the better
representation of what is happening actually
so user types in some text
and this can be like some static data
and this also can be some
and we make this box to ring
and then for example we say that it calls
calls
the server api and
then we're returning the data to the store
store
so exit for example
a user type some text so the query
oh and i forgot one property here
actually we need also
a cache size by default it will be five
okay the user pass some query for
example jack
and then we call the server api and the
server providers
the result on the result data so we
and also we set this data to the
fix it map so results map actually it's
a map where
the key is the query and there is
and the value is the previous result so for
for
query jack will have uh the data array
and the data is the current data which
is actually
was fetched so and why it's a fix-it map
so we
remember we have the cache size equals
to five
this means that when we actually call for
for
api we store these results in the fixed map
map
if the size of the cache is exceeded the
five then we're removing the oldest
caching result on the map and
then place our results so
this can be done with an extension of
the simple
javascript map and that's why i called
it fixed map
it's not hard to implement on the
javascript site
so the data represents the current fetch
data and
also the show data and it can be more
than actually visible data so for
example we fetched
100 results and show only 10 and then
the user clicks
on the page and then we load more so
we also want to have uh
we also want to store actually our uh
space size as a number
so the page size is actually the
our max results max visible results and
we store
this as the page then if the user wants to
to
see the next results then we update it
with the
next page thing and we increase the size of
of
the actual current page
so also we have we store the cache size
and the
inquiry parameter and we store the template
template
and our own query this means that in
this function
we pass with the get results function
so with this our store organization and
how actually this works so
the search results uh pass the data rate
here and then we proceed to the single item
item
with the result datum and then
search suggestion is actually get called
by the template
template functions and the data is taken from
from
the data array from the state
so this is actually how it works if we
for example do not have any server api
then we just define the get results function
function
and this function will so and we have
some static data so static data will be
stored in the closure
and we can filter the static data each
time we pass the query and get the results
results
okay this is the state design and
i think we're ready to finish with that
and with that let's proceed to the actually
actually
uh to the actual uh
optimization points here so what are the
optimization points for a widget
so it consists as usual of the three
main pillars
it's a rendering
so this is a three pillars of the
application performance
and the video performance and let's say that
that
now let's just give it to each
color like network
rendering and the javascript
okay we start with the network
and let's also place label here performance
performance
optimization we start for the
network actually we have limited
capability to
uh optimize the network from the widgets side
side
so the first thing we use because this
is more dependent on the application
side on the user side
so and we as a vg developers uh
should not care about the whole
application network performance this is
more done on the
uh application side but we still
can do some optimization inside our calls
calls
so the first thing to do is actually
bounce the
search the balance the search goal
so when the user types in we don't want to
to
trigger the search for each
letter so we debounce this call and this
will enable us
to search less and more efficient
from the performance side so this is the
first thing to do
so what is the caching caching actually
is the multi-level technique here
and we also use the browser cache
and i'll place this as a i will say that
it's a great color because we do not
control this stuff
and we use our widget cache
so widget cache is described
we store some search results in our
internal state
and also so about widget cache we can
and as you can see here we can also
provide the
cache time as a perhaps
so cache time for example it could be 10
like 10 000 milliseconds so the cache
time defines how
so how much time actually cache leaves
inside our app
and from the network performance uh what
um i
probably think that's all we can do from the
the
video side if we talk about the
application side then we can
use uh techniques like rattles uh
or zipping the whole resources but this
is the
the server side regarding the rendering this
this
gets more interesting so our rendering
splits into
several things so like the
dom and
so the drone performance and also these
css i mean css can be also
placed in the door but i'd like to have
it and there's a separate category
or okay let's be just done so regarding
the rendering
so we have the dom performance and what
the first thing we do
is the use virtualization
for uh for our search results
so the virtualization can be done with
the several like patterns
uh like intersection observer where we
maintain the constant number of nodes
and just replace
the denotes data with a new one
so let's say that virtualization we
maintain constant
and what else we do not delete
and insert the nodes
we update it okay this is the
so what what else can we add here
um we have the virtualization we do not
create the
nodes we maintain the constant number and
and
what about the css uh the first thing
i'd like to
consider is that we use
css animation so we don't want to use the
the
javascript animation if we'd like to use
actually for
any animation for our widgets so we use
css animation this increase the
performance because they are more
optimized than
the javascript animation and we
also want to avoid reflows
this means that we
we try to not change the parameters like
width for height of the item
uh too awful in order to not uh render
more and reflow and re-render the whole
widget itself
so we have the css animation also we say
that we want to avoid reflows
and one more point here is that
this can be any like them or i won't be
or for example we can use the css models
that's all fine
but we need to like have
flattened flat and css selectors this
improves the
okay so we have the talked about
rendering and css and also there is one
more point here it's a perception
per reception what is actually the perception
perception
how the user feels our item actually
i could say that we can use the
skeleton and loaders
and placeholders
so scientific research said that if the user
user
with the slow network connection see these
these
loaders uh the feeling of the time is
quite different and it feels like that
our widget loads faster for the user and this
this
improves the whole ux for uh
our user so this is about the
rendering performance what about the
javascript performance so about
this is quite simple enough so for a
javascript performance
you need to do stuff
i think so what this means
uh imagine that we have the static data about
about
1000 elements and we'd like to filter this
this
and if we filter this directly on the
with the just filter function our
application can have a lag
because we block the ui thread and for that
that
we can use the webworkers for
static filtering
okay and web workers will provide us a sync
sync
uh execution of this filter function in
a separate freight and then we get a
result and show it
this the first thing we can do and this is
is
actually the other stuff
and we can use server
filtering for
large data it's more about actually user optimization
optimization
because the widget itself just have the
api and what the user will
take with the do with this api it's on
his side but
for the large static data i think we can
try to
okay i feel like we're
almost done for about the
rendering stuff and the optimization stuff
stuff
let's talk about the accessibility
okay first thing to consider
is that we want to have keyboard navigation
keyboard navigation so the first thing
to provide is the
quick shortcuts to access so
shortcuts for easy access so for example user
user
state on the page and then he quickly
searched with the
like spotlight on the macbook you can
just press the comment space and then
you have the
spotify search we can do the following
for our application
so the second thing is that we want to
have table
terrible items this means that
up back and forward with the
tab key and our elements should be accessible
accessible
we can navigate between the elements
with the keyboard through the tab key
so this is the first second thing
what else can we had
and close the shortcut
close shortcut and the search search is usually
usually
it's an intro so we do not need by default
default
uh set this implicitly because this is
happening on the browser side but this
is enough
okay we said about the keyboard negation
the next thing to consider is
so what is the visual optimization uh
it's actually quite simple
we need we want to enforce
brands in our app so what this means
when the user have custom setting
on the browser site we want the
this uh our widget to adapt to this
custom setting and increase its size
based on the
zoom setting and ramps can provide us
with this capability
and then we can focus on it so okay the
usual optimization
uh i don't feel like we need to provide
some custom themes because this is also
and we can also say that widget can be
screen reader friendly
what about this is that we want to provide
field so when the user types in the search
search
we'd like to announce this field with the
the
with the search query on the screen
reader size so we can use the relay live attribute
attribute
and we also use area attributes
on item
to give a correct item rule
so if the in some cases we do not
go with the semantic of the item we'd
like to provide the correct semantic for
the screen reader
then we use the uh we use role attribute
to provide this
okay i think we're this is done for
accessibility site and this
was pretty fast because i don't see
any other points of the discussion
but let's say we can have additional
stuff here
so accessibility and then like some
other feature here
is npm uh
so we extract our components as npm package
package
and then we integrate or integrate this
in our app
from the npm registry so
this is completely decoupled from the
whole app and we can reuse this
need
okay what else can we add here is
some npm packages to be used uh
we can also consider um
i'm not sure what we can add else um but
yeah i don't know what to add house
let's say we finish in 40 minutes i
think this is fine
thank you for watching this video uh as
usual i provide the schema
of this design with the attachments to
the video
please feel free to comment and give the
suggestion to the video
and together we can improve the content and
and
pass the interview so good luck on your interview
interview
good luck with preparation may the force
be with you
it's a front end engineer and have a
Click on any text or timestamp to jump to that moment in the video
Share:
Most transcripts ready in under 5 seconds
One-Click Copy125+ LanguagesSearch ContentJump to Timestamps
Paste YouTube URL
Enter any YouTube video link to get the full transcript
Transcript Extraction Form
Most transcripts ready in under 5 seconds
Get Our Chrome Extension
Get transcripts instantly without leaving YouTube. Install our Chrome extension for one-click access to any video's transcript directly on the watch page.