Filter
-
Content Type
-
Category
Mobile/Wearable
Visual Display
Digital Appliance
Platform
Mobile/Wearable
Visual Display
Digital Appliance
Platform
Filter
Distribute Galaxy Store
docafter you've published your app in galaxy store, take advantage of opportunities to promote your app and track app data promote your app and track app data you can increase the number of downloads of your app by promoting your app you can submit your app to be featured in the benefits tab, pre-register your app, submit your app to be featured in a galaxy store editorial, issue discounts, promote your app in social media, and use the galaxy store badge you can also track app data using galaxy store statistics and third-party attribution platforms integrated with galaxy store galaxy store benefits tab galaxy store benefits is a rewards program built into galaxy store for galaxy device users in the united states by featuring your app or game in the benefits tab, you can reach an engaged, motivated audience and drive meaningful growth in your installs and daily active users what is the benefits tab? the benefits tab is a dedicated section inside galaxy store where users can participate in sweepstakes for free and earn virtual gems and tickets by completing daily activities such as exploring featured apps and games, checking in, and watching videos users can redeem gems for galaxy store coupons and samsung com digital gift cards, and use tickets for additional entries to the weekly and monthly sweepstakes for a chance to win samsung devices because every activity in the benefits tab is designed to keep users coming back day after day, the program creates a highly engaged audience that is primed to discover, install, and explore apps how it helps your app or game when your app or game is featured in the benefits tab, it is placed in front of users who are actively participating in store activities—not passive browsers these users are highly motivated to install and engage, which translates to higher-quality installs users arrive with intent, not just curiosity increased daily installs benefits tab activities can dramatically increase the number of daily installs for your app or game sustained engagement because the program incentivizes users to return every day, your app benefits from ongoing visibility rather than a one-time spike custom tasks coming soon in the near future, you will be able to define specific in-app actions—such as completing a level, making a purchase, or reaching a playtime or in-game milestone — as tasks that users can complete to earn gems, letting you drive the exact behaviors that matter most to your app's growth availability the benefits tab is currently available to galaxy device users in the united states the galaxy store team reviews and selects apps and games to be featured in the program if you are interested in having your app or game featured or being a selected partner for custom tasks, please submit a 1 1 support request with details about your app or game—including its category, target audience, and any relevant performance metrics—so the galaxy store team can review your submission pre-registration pre-registration is a listing of your game in galaxy store before it's released and appears in the pre-register tab of the games section pre-registration allows you to promote your upcoming release, offer special incentives to customers who pre-register for your game, and automatically downloads the game over wi-fi when it's released galaxy store editorial showcase your app or theme in an editorial in the discover tab of galaxy store, available to users in the u s , the uk, and south korea the discover tab is where discovery meets inspiration, bringing users the best apps, games, themes and original stories in ways that resonate with their daily lives, right to their fingertips providing users with curated recommendations on the latest trends, samsung exclusive benefits, seasonal events, tips, and more, the editorials combine storytelling and visuals to enrich user experience and showcase developer innovation using the app promotion tab in seller portal, app publishers can request that their app be featured in the discover tab in galaxy store discounts for paid apps, you can reduce the price of your app for a set period of time run a limited-time promotion or seasonal discount to attract new customers see discounting app price for more information for in-app items, you can update the prices in seller portal using real-time item management, which allows you to publish price changes without having to go through the seller portal review process unlike discounts for paid apps, you cannot set an expiration date for the discount of an in-app item if you want to run a limited-time promotion, you must manually reset the price in seller portal at the end of the promotion see also management of in-app products for more information galaxy store badge galaxy store badge is an image and a link to your app details page that you can use in your content, making it easy for your customer to download your app through galaxy store the badge image is available in over 30 languages and can be downloaded from seller portal go to promotion > badges, then select download badge third-party attribution platforms if you want to use a third-party attribution platform to track app data, galaxy store is integrated with adjust appsflyer branch kochava singular refer to synchronizing with attribution tool in the seller portal user guide for more information do you use another platform? contact us by submitting a request with more information galaxy store statistics galaxy store statistics gss is a free and exclusive tool that can be used to track and monitor galaxy store app performance and metrics like downloads, conversion, subscription, top seo keywords, and attribution channels gss also provides user acquisition reports that measure user attribution and breaks down the numbers by channel, source, keywords, and featured placement attribution from galaxy store banners or icons information about the gss system can be found in the online user guide must be logged in to seller portal to view galaxy store developer api manage apps, manage in-app items, and check app statistics programmatically use the content publish api to view, modify, submit, and change the status of apps registered in seller portal use the iap apis to view, register, modify, and remove items, view payments and refunds, and cancel, refund, revoke, or check the status of subscription items use the gss metric api to get statistics about apps registered in galaxy store
web
discover and developwith samsung use our tools and services to providean exceptional experience to samsung users around the world. view all products subscribe newsletter what’s new latest updates for developers stay updated with recent news, feature changes, and key announcements that highlight new additions and improvements. samsung wallet in code lab learn to integrate samsung wallet into your apps and websites through hands-on code lab tutorials, from web checkout to secure id verification. one ui 9 is here: update your apps ensure seamless compatibility and deliver optimized performance on the latest galaxy devices running one ui 9. experience the all-new galaxy z series download the galaxy emulator skins for z flip8, z fold8, and z fold8 ultra to give your android studio emulator a galaxy device look. learn learn easily, build confidently visit code lab blog blog managing closed beta testing with the galaxy store developer api galaxy store updated oct 6, 2026 blog samsung wallet brings aliro-based company id to the workplace samsung wallet updated sep 22, 2026 blog integrating revenuecat with samsung in-app purchase for galaxy store applications galaxy store, iap updated aug 13, 2026 blog how to manage buyer comments in galaxy store using the developer api galaxy store updated jul 23, 2026 develop mobile / wearable get set up to use samsung mobile sdks in your apps. mobile / wearable visual display digital appliance platform galaxy gamedev build games for galaxy devices - the world's largest mobile gaming platform galaxy themes with galaxy themes, you can personalize galaxy devices' screens galaxy watch optimize your application performance health create a useful health app on galaxy watch and a smartphone samsung iap sdk make it possible to sell a variety of items in samsung galaxy apps samsung browser web developer guides for samsung browser samsung wallet an all-in-one, single-swipe solution for tickets, boarding passes, coupons, and more galaxy emulator skin app design guide for foldable phones remote test lab build apps to control desktops with smartphones smart tv build apps for samsung smart tvs smart hospitality display enhance guest experiences smart signage transform displays in business family hub make the kitchen the center of your home bixby apply voice to your apps smartthings add smartness to your user’s lives knox secure your devices tizen build apps that connect everything samsung see more mobile docs (15) see more mobile docs (15) galaxy sdk get started create your own applications with a variety of samsung galaxy sdks, services, and tools. galaxy ar emoji sdk create your own avatar in your app galaxy performance sdk optimize your application performance galaxy s pen remote sdk control apps remotely with your s pen galaxy z (foldable) app design guide for foldable phones samsung automation studio develop your apps using samsung automation studio samsung blockchain build blockchain-enabled services for mobile devices samsung dex build apps to control desktops with smartphones samsung ese sdk provides a way for service providers to deploy services using ese on samsung devices samsung teegris a powerful solution to run applications in a trusted execution environment apv codec advanced professional video codec mobile accessories major component placement for galaxy s/z phones samsung app management a solution to manage background applications for better system health samsung log video create professional videos with galaxy camera starting from s25 series samsung wireless fast charge enables samsung mobile devices to be fast-charged with the wireless fast charger design creating the future get in-depth information and resourcesto design high quality apps for samsung’s products and services. design system samsung design system is samsung eco’s design system for consistent and clear communication. one ui design guideline one ui helps you focus on what really matter to you one ui watch galaxy watch provides you new ux components, which allows you to use it to build new user experiences. distribute share with millions bring your apps and games to samsungreach hundreds of millions of galaxy users distribute your apps submit your apps to galaxy store and use key samsung programs to promote your apps. samsung apps tv seller office with demand for video servies constantly growing, now is the perfect opportunity to publish application for samsung smart tvs. redefine your game distribution stream your games on samsung mobile devices using instant plays 2.0, bringing users instant fun and excitement. connect and share more than on your ownsamsung developer forums visit the forums to ask questionsand exchange ideas with other developer. visit forums experts and tools with our support team we're here to help you be successful in the samsung developer ecosystem. learn more about our tools and how to communicate with our support team search faq by keyword and category submit a 1:1 support request and receive a responds explore testing tools and software resources get insights with recommended articles get support for partner samsung developerbusiness account join samsung business account to experience most of the service. add members, measure user engagement, streamline your onboarding process and much more - all at no cost create business account newsletter get monthly digest of the latest highlights from our developer products and programs email address first name last name 뉴스레터 전송을 위한 개인정보 수집∙이용에 동의합니다(필수). detail 광고성 정보 수신에 동의합니다(필수). detail i agree to data processing for sending newsletters. (required) detail i consent to receiving newsletters via email. (required) i consent to receiving newsletters via email. detail subscribe
Develop Samsung Wallet
docdevice compatibility certain digital access features are only available on specific mobile devices digital key registration is restricted to supported models please refer to the list below to check compatible devices for each feature digital key aliro home key samsung galaxy phones ① nfc feature over android 14/u os ② uwb feature over android 16/b os samsung wallet digital key - device support matrix in 2026 uwb feature over android 16/b os nfc feature over android 14/u os model year connectivity region android os z fold 8 ultra/basic 2026 nfc, uwb global z fold7 2025 nfc, uwb global z fold6 2024 nfc, uwb global z fold6 se 2024 nfc, uwb kr z fold5 2023 nfc, uwb global z fold4 2022 nfc, uwb global z fold3 2021 nfc global up to android 15 z flip 8 2026 nfc, uwb *kr global z flip7 fe 2025 nfc global z flip7 2025 nfc global uwb kr only z flip6 2024 nfc global z flip5 2023 nfc global z flip4 2022 nfc global z flip3 2021 nfc global up to android 15 s26 ultra/plus/edge 2026 nfc, uwb global s25 ultra/plus/edge 2025 nfc, uwb global s25 basic nfc global s25 fe nfc global s24 ultra/plus 2024 nfc, uwb global s24 basic nfc global s24 fe nfc global s23 ultra/plus 2023 nfc, uwb global s23 basic nfc global s23 fe nfc us/ca/eu/kr s22 ultra/plus 2022 nfc, uwb global s22 basic nfc global s21 ultra/plus 2021 nfc global up to android 15 s21 basic nfc global up to android 15 s21 fe nfc global up to android 15 a57 5g 2026 nfc us/ca/eu/sea/mea/afr/kr a56 5g 2025 nfc us/ca/eu/sea/mea/afr/kr a55 5g 2023 nfc eu/kr a37 5g 2026 nfc us/ca/eu/sea/mea/afr/kr a36 5g 2025 nfc us/ca/eu/sea/mea/afr/kr a35 5g 2023 nfc hk xcover7 pro 2025 nfc global matter hub smartthings hub smartthings / aeotec / things one v3, v4 smartthings station samsung products tv & home appliances - with hub embedded from 2023 reference https //blog smartthings com/roundups/where-did-smart-home-hubs-go-everywhere/ digital id id card company id employees model year chipset type region aliro nxp desfire hid seos safetrust z fold8 ultra/basic 2026 type a global o o o o z fold7 2025 type a global o o o o z fold6 2024 type a global o o o o z fold special edition 2024 type a kr o x x x z fold5 2023 type a global o o o o z fold4 2022 type a global o o o o z fold3 2021 type a global o o o o fold2 2020 type a global x o o o z flip8 2026 type a global o o o o z flip7 2025 type a global o o o o z flip7 fe 2025 type a global o o o o z flip6 2024 type a global o o o o z flip5 2023 type a global o o o o z flip4 2022 type a global o o o o z flip3 2021 type a global o o o o z flip 5g 2020 type a us/ca/eu/mea/afr/kr x o o o s26 ultra 2026 type a global o o o o s26 plus/basic 2026 type a us o o o o 2026 type b eu/sea/mea/afr/la/cis/swa/kr o o o o s25 ultra/plus/edge 2025 type a global o o o o s25 fe 2025 type a global o o o o s25 2025 type a us o o o o 2025 type b eu/sea/mea/afr/la/cis/swa/kr o o o o s24 ultra 2024 type a global o o o o s24 plus/basic 2024 type a us o o o o 2024 type b eu/sea/mea/afr/la/cis/swa/kr o o o o s24 fe 2024 type a us/ca o o o o 2024 type b eu/sea/mea/afr/la/cis/swa/kr o o o o s23 ultra/plus/basic 2023 type a global o o o o s23 fe 2023 type a us/ca o o o o 2023 type b eu/sea/mea/afr/la/cis/swa/kr o o o o s22 ultra/plus/basic 2022 type a global o o o o s21 ultra/plus/basic/fe 2021 type a global o o o o s20 ultra/plus/basic 2020 type a us/kr x o o o 2020 type b eu/sea/mea/afr/la/cis/swa/kr x o o o s20 fe 2020 type a eur lte x o o o 2020 type b us/ca/kr/eur x o o o note20/note20 5g 2020 type a global x o o o a57 5g 2026 type b us/ca/eu/sea/mea/afr/kr o o △ o a56 5g 2025 type b us/ca/eu/sea/mea/afr/kr o o △ o a55 5g 2023 type b eu/kr o o o o a54 5g 2022 type a us/ca/eu/kr x o o o a53 5g 2021 type a us/ca x o o o 2021 type b eu/kr x o o o a37 5g 2026 type a us/ca/eu/sea/mea/afr/kr o o o o a36 5g 2025 type a us/ca/eu/sea/mea/afr/kr o o o o a35 5g 2023 type a hk o o o o xcover7 pro 2025 type b global o o △ o xcover pro2 2022 type a us/ca/eu x o o o
Connect Samsung Developer Conference
webtech sessions dive into the future of connected customer experiences through tech sessions by developers offering further insight into the innovations introduced in the keynote filter filter filter all reset apply there are no results. sessions contents & service, open innovation 8k visual quality and ecosystem in this session, we will present how the genuine 8k contents correctly displayed on 8k display devices could deliver our customers an immersive picture quality experience. we will start with a summary of the previous studies about user perceptions regarding the 8k visual quality. we then will explain why the full-frequency 8k contents are superior to the lower resolution in producing fine details on the image. we will also discuss some technical challenges we face toward adopting and utilizing 8k contents in a real-world environment and describe how we can overcome these hurdles. specifically, we will discuss technologies such as super-resolution and new image sensors to overcome the full-frequency barrier of 8k content. last, we will introduce the 8k association (8ka), a non-profit organization composed of key technology companies in the consumer and professional 8k ecosystem, and briefly mention 8ka's ongoing effects on the research, standardization, and promotion of 8k visual quality. sessions contents & service, developer program, mobile add samsung pay as your payment method in this session, we will share learnings from our experience developing the samsung pay mobile payment service, revealing insights that can be applied to your own platforms. we will also take a look at the samsung pay development kit and how you can use this for your own service. sessions game, ar, mobile ar emoji: your avatar, your experience the ar emoji feature on samsung devices enables users to create a 3d avatar model that can be used in other applications. similar to avatars currently available in games or in the metaverse, our ar emojis are a chance for users to express themselves, their style and their personality, digitally. but this is only the beginning. in this session, we’ll explore the future of ar emojis and how the ar emoji sdk is opening more opportunities for developers to collaborate with samsung to bring to life new services featuring these avatars and optimize them for the metaverse though our collaboration with unity. sessions ai, iot, smart appliances bixby 2022 what’s new what’s new with bixby in 2022? in this session, you will hear about some of the exciting improvements to the nlu and on-device bixby as well as updates to the bixby developer studio, which introduces a brand new javascript runtime that provides a modern, secure, high-performance environment. we will also take a closer look at the brand new bixby home studio, which allows smart device developers to customize and optimize voice control of smart devices, including allowing a single command to intelligently control multiple smart home devices. sessions contents & service, game creating spectacular galaxy game audio experiences with dolby atmos galaxy smartphones and tablets can produce spectacular game audio with dolby atmos. discover how you can create deeper emotional connections with players, keep them playing for longer, and earn their loyalty by unleashing the full power of samsung galaxy mobile game audio. in this session you will hear from dolby’s partner audiokinetic who will discuss how developers can make dolby atmos games, including a walkthrough of how to use dolby atmos plug-ins in audiokinetic's wwise audio middleware. moong labs – creators of epic cricket one, of india's most popular sports games – will also share how dolby atmos benefitted their game and you will find out how dolby supports game developers and other activities on our website. sessions health, wearable expand health experiences with galaxy watch the galaxy watch’s powerful bioactive sensor, together with the wear os powered by samsung, is transforming mobile health experiences. and now, this technology is even more powerful thanks to the samsung privileged health sdk. find out how the samsung privileged health sdk is allowing developers to retrieve raw or analyzed sensor data for their applications, including bia, ecg, blood oxygen level or sweat loss, and help users’ to accurately monitor their health stats. sessions web flexible and private web experience on samsung internet in this session, you will learn how to enhance and optimize your web experience for foldable devices using device posture api and viewport segment media query. we'll also take a closer look at how samsung internet protects users’ privacy online. sessions mobile, enterprise, developer program google and samsung strengthen enterprise ecosystem together samsung’s global mobile b2b team is working closely with the android enterprise team to build a galaxy ecosystem of partners who are bringing innovation into workplaces. discover how partner solutions create unique experiences on samsung devices and how we plan to work together to help future partners step into the samsung android ecosystem for enterprises and smbs. sessions contents & service, developer program, enterprise hdr10+/salt and automatic hdr video creations for productions hdr10+ is an essential technology for premium hdr viewing experience and it is widely reach to consumer displays including mobile devices. in order to provide hdr content services, it requires changing service provider's infra structure or workflows and video processing technology from sdr to hdr with a lot of engineering efforts. then, hdr10+/salt solutions and partnership program from samsung is designed to build an extremely cost effective automatic solution up for content creators, post production houses and ott service providers even including game developers. the solution package is designed with various standalone applications, reference apps, sdks on various oses and partnership programs to help 3rd parties for creation of hdr contents. hdr10+/salt partnership program provides full compatibility to hdr10+ llc certification program and major studios, ott service providers and tool makers are already partners of the program and samsung provides them the best hdr content quality. sessions developer program, open innovation, health healthcare research hub our open source project provides end-to-end solutions such as sdk, platform, and portal for various use cases from medical research studies to clinician services using wearable devices. medical research does not have to stay complicated. anyone can easily build and customize their own research studies or clinician services using this open source. recently, as the accuracy of sensors installed on wearable devices has improved, interest in healthcare research using wearable health data is increasing. however, it takes a lot of time for researchers to develop research applications and server infrastructure for storing and analyzing data from scratch. sr is developing android sdk and data platform solutions that support healthcare research using health data from our wearable devices (watch 4 and later versions) and provide them as open source in order to solve the pain points of these researchers and establish a digital health care research ecosystem centered on our wearable devices. sessions iot, monetization, smart appliances home connectivity alliance introduction of home connectivity alliance and how appliance manufactures can enable interoperability across brands. hear how hca interoperability can benefit consumers and partners including b2b (home builders, mfu, etc). join the hca and become a leader in innovation within the connected iot ecosystem. sessions ai, ar immersive audio we will demonstrate an audio system with dramatically improved immersive 3d audio experience. hardware will be similar to samsung’s critically acclaimed hw-q990b soundbar, but will include several new technologies that will be found in future samsung products. these technologies automatically correct for room acoustics and the location of the listeners and loudspeakers. visitors will compare the sound of the system before and after the system’s unique automated calibration process. listeners will enjoy improved spatial and timbral performance in stereo, surround and immersive audio formats with both music and cinematic content. sessions security & privacy introducing blockchain wallet with knox vault in this session, we introduce blockchain wallet for samsung smart tv. blockchain wallet allows our smart tv users to manage their blockchain accounts and transfer their cryptocurrency to another blockchain account. it ensures to retain a key for blockchain transactions in a secure way. dapp developers can build their tv dapp with blockchain wallet for blockchain functions such as blockchain connection and transaction signing. knox vault is an enhanced hardware-based security solution to protect sensitive data such as cryptographic keys, passwords and personal data. knox vault provides strong security guarantees against hardware attacks such as physical attack, side-channel attack and fault attack. as a core component of the knox security platform, knox vault is an isolated, tamper-proof, secure subsystem with its own secure processor and memory. sessions developer program, enterprise, android introducing samsung galaxy camera ecosystem discover how advanced camera technologies, based on samsung’s leading hardware and software, can enable developers to create more powerful camera experiences for their users. we will take a look at some of the incredible partnerships samsung has already formed with numerous app developers and reveal how these collaborations enriched users’ camera experiences. sessions mobile, android, productivity intuitive multitasking experience based upon android 12l join us to see how samsung continues to enhance the large screen user experience further with fast app switching and intuitive multitasking capabilities. to maximize the galaxy foldable experience, we're expanding flex mode even further with more apps and partners as well as google's ongoing collaborative effort in android 12l. sessions iot, mobile, uwb joint efforts on standardization toward open ecosystem of uwb services the presentation will introduce samsung's joint efforts with industry partners on the uwb tech/service standardization, which is essential for creating an interoperable open ecosystem of uwb products and services. especially, it will introduce activities at fira consortium, which was established by samsung jointly with industry leaders to provide interoperability specifications as well as certification programs. it may also include target uwb services and relevant standardization status & plan. sessions ar, game, tizen journey to immersive interactive exp in big screen with xr and avatar fw xr framework webapis enable developers to build xr applications on the tizen platform. we will go over features of the webapis, share some demos, and provide information on how to get started. additionally we will show you a sample code of how to capture and handle user's gestures and full body movement. avatar framework for tizen is a unified solution providing high level apis that allow samsung developers to easily include the 3d avatar models and features in their samsung tv applications. we will go over all the cool features and options of our framework in this video. sessions connectivity, android, mobile le audio: the future of wireless sound introducing le audio: a new standard for bluetooth technology on galaxy devices. le audio will enhance the performance of classic bluetooth audio and introduce isochronous communication, creating whole new wireless audio experience on galaxy devices. in this session, we will introduce the technical features of le audio, what it means for the galaxy ux and how you could enhance wireless audio experience of your app with le audio. sessions design, ui/ux one ui design principles in partnership one ui creates a unified experience across our galaxy devices, from phones and tablets to watches and galaxy books. in creating and refining one ui, we've followed four key principles: simplicity, effortlessness, consistency, and authenticity. with one ui, we've also made a commitment to openness, which means some of the best things in one ui come from partnerships. in this session, we'll talk about some of those partnerships and how we aligned them with our four design principles to get great results. sessions ui/ux, design, android one ui: customer centric design one ui starts with a true understanding what our customers want. hear more about what samsung have learned from listening to extensive customer feedback and usage data, and how we have adapted our designs in response. we'll take a look at some real-life examples of how the ux design of the calendar, settings and samsung health app has evolved over time to better meet customer needs. sessions enterprise, data, security & privacy our journey to responsibly handling data at samsung, we place personal data protection as one of our top priorities. learn how we responsibly handle personal data in our applications and platforms. we'll share with you our journey in protecting personal data. we'll talk about what it means to responsibly govern and access data in samsung's enterprise environment. we'll cover specifics on how to classify & protect data as a whole. pick up insights on privacy technologies and design patterns we apply in our data intensive applications today. sessions developer program, tizen, ui/ux prism: the new ux development tool and process in today’s environment of rapid and unpredictable transformation, establishing a creative and increasingly collaborative tech culture is one of the most challenging requirements. in this session, we would like to introduce a new method to revolutionize the tizen platform-based app development process. a new development process named prism automates most of the inefficient overheads from design to implementation of app ui, innovatively improving app development productivity. we will introduce prism-based development process and deliver this innovative app development culture to developers through the sessions. sessions developer program, smart appliances, tizen remote test lab: what’s new in tv development environment the current tizen tv development environment, represented by emulator and tv, is a very limited support method for developers. depending on the version of emulator, the latest features currently supported by the tv may not be available, and various models of physical tvs may be required to verify actual operation. rtl tv tries to overcome the limitations of the current development environment. sessions contents & service, monetization, data samsung tv plus: the advanced ad-tech and partnerships that fund free tv samsung’s free ad-supported tv (fast) service “tv plus” has been a breakout success. although it looks and feels like traditional tv, it is anything but! behind the scenes of this slick tv & mobile experience is high-performance technology, vast amounts of data & algorithms, and a thriving partner ecosystem. join this session to learn more about the mind-boggling world of advertising technology, how it works, and how multiple companies come together to provide free tv to millions of consumers worldwide. sessions android, contents & service samsung wallet, it's convenient, personal and safe as the growth of digital wallets skyrockets, samsung recently announced samsung wallet – a new platform bringing almost all of the cards you’d typically find in a physical wallet, as well as important documents, into one easy-to-use and secure mobile application. as samsung wallet rapidly expands its content set, find out more about the future of digital wallets and how open api’s can allow developers to build integrations for this service. sessions iot, security & privacy smartthings edge: the next level experience discover how samsung is transitioning the smartthings-published groovy dths to edge drivers while maintaining a seamless experience for our users. we’ll walk through the process of onboarding edge-based devices and how to set up an automation with an edge device that runs locally. sessions iot, monetization, smart appliances smartthings energy service introduction of smartthings energy service and how partners (energy companies, smart device mfgs, etc) can integrate to provide a seamless energy management service for their consumers leveraging samsung's smartthings energy ecosystem. sessions iot, contents & service, open innovation smartthings find: find alongside 200+ million users smartthings find is samsung’s fastest growing service, powered by more than 200 million galaxy users. discover some of the new features and functions added over the past year and learn how partners can leverage the service to innovate their own solutions to meet the needs of businesses and consumers alike. sessions iot, contents & service, open innovation smartthings platform enhancements for openness and interoperability the smartthings platform continues to evolve to promote openness and interoperability. in this session, we will share some exciting new updates to the smartthings platform to support matter and thread, and discuss the home connectivity alliance. sessions health, tizen telehealth in samsung devices samsung display device (smart tvs & smart monitors) users will be able to launch telemedicine service within the samsung products. once you pick your physician, you can use one of the approved usb cameras to connect to the tv and jump on a video call with a physician via external service provider's built-in web applications. after a few account setup process on mobile / pc, you can easily start your session any time on tv without any additional complicated inputs. at your session, you can also receive a prescription to be filled in at a mail-in online pharmacy (pc or mobile) to receive prescription drugs at your doorstep. sessions open innovation, enterprise, productivity the next generation samsung retail solutions in a mobile-first world, device convergence, simplification, ergonomically designed accessories, sw solutions and the connected galaxy ecosystem are helping to boost productivity and efficiency in the retail industry. in this session, we will explore how the next generation of retail solutions are shaping the industry’s future and will take a closer look at samsung’s three major retail solutions - data capturing, payment, and push-to-talk. sessions developer program, mobile, android the samsung knox partner program: partner success journey the samsung knox partner program (kpp) equips you with everything you need to build ideas and market your mobile solutions. in this session, we will take a look at some of our partners’ solutions and how collaborating with the samsung kpp has helped enhance their user experience. join us to see why kpp is causing a stir in the business developer community! sessions enterprise, tizen tizen everywhere this session highlighted samsung's direction and goals for the enterprise and b2b markets, focused on taking tizen to the next level on so many platforms. various enterpriser displays based on tizen and solutions suitable for business purposes will always be together. tizen enterprise platform will provide all the technology infrastructure you need, including the samsung developers portal for b2b for developer support and the samsung apps tv seller office for custom application support in your own business. after announcing "tizen open" at sdc in 2019, samsung established licensing system to provide tizen tv os to other tv makers. in order for partners to develop tizen tv products faster, samsung prepared reference tv solution. in europe, australia, türkiye, tizen tvs have been released sequentially through more than 10 tv brands since september 22. sessions wearable, design, android watch face studio's first journey and expectation for next a must-have to create beautiful watch faces! watch face studio (wfs) is now a little over a year old. hear the developers of wsh share the highs and lows of bringing the tool to life and meet the designers responsible for creating the eco watch face. this session is an insight into the year-long journey to create wfs – and the story of where we’re going next. sessions iot, tizen, ui/ux what's new in tizen? are you curious about the direction in which intelligent iot platform “tizen” is developing? this session introduces ui assistant technology and extended 3d ui framework for providing advanced user experience, and explains innovative technologies that make run the tizen platform on top of the android hardware abstraction layer to facilitate securing new hws. and introduce the iot standard 'matter', which will be newly supported on tizen. finally, we provide a guide and tip for cross platform application development. sessions ai, iot, smart appliances what’s new in bixby for smart home bixby brings the smart home experience to life with the power of voice. find out how our new tool, bixby home studio, will enable device manufacturers to build more intelligent, more engaging voice experiences for smartthings-connected devices. sessions mobile, design, ui/ux what’s new in one ui 5 one ui 5 pushes personalization and productivity to the next level. explore new features that enable you to build a galaxy experience that reflects your personal style and help you to get more done on all your devices, wherever or whenever you need to.
success story game, mobile
blogin this first blog of a two part series, maxim kirilenko, chief business development officer at playrix, chats with samsung developer's senior marketing manager, jeanne hsu, about playrix and gardenscapes tm. jeanne hsu (jh): welcome maxim. how did your professional journey lead you to playrix? maxim kirilenko (mk): thank you. i've been in the gaming industry since 2007. i started off at the korean company gravity, working on pc games like ragnarök online and requiem online. i've come a long way in the industry since then—from quality assurance manager to executive director at a game publisher in russia. i also worked as director of business development for an it company doing internet advertising for a while. for three years, i helped the company penetrate foreign markets and launch new services in indonesia, brazil, poland, and thailand, to name a few. i was always fond of games and had played playrix's gardenscapes. while i was working in it, i was recruited by playrix. i realized i had wanted to return back to gaming, my passion. so in 2018, i joined playrix as head of marketing growth. i worked in business development in marketing originally until i combined it with business development in general. now i lead the business development and m&a (merger and acquisition) teams. jh: what's the history of playrix? mk: our team has been developing games since 2004, but the founders of playrix, dmitry and igor bukhman, started making games even earlier, back when they were still in school. by 2010, the company had released several successful pc games. around that time, they started developing social network games. the first facebook game, township, was released in 2012 and immediately made the top 50. it was also the first project to be released as a mobile game later on. the mobile version of fishdom came out in 2015, which is when the company became the leading mobile game developer in eastern europe. jh: i like your strategy. in 2004, your focus was pc games and then you switched to mobile in 2015. mk: in 2016, playrix released gardenscapes, which was the first game in our famous scapes series. the company was actively growing, and in 2018, we came to the conclusion that it was time to build new partnerships. so we started developing our m&a [merger and acquisition] strategy, and over the past four years, 13 studios from armenia, serbia, ukraine, russia, and belarus have joined the playrix group of companies. in 2020, playrix placed in the top three for leading game publishers worldwide according to app annie, and last year we climbed to second place. [app annie has been renamed data.ai] jh: that's amazing! what do you attribute to your success? mk: it was not random. we originally started with pc games, then social and web versions. next we switched to mobile. the switch to mobile really accelerated our rapid growth. growing with the m&a strategy and adding talented people really helped create aaa titles which accounts for our rapid growth. we want to keep focusing on creating more innovative games and new genres. jh: where is playrix located, and where do you live? mk: playrix employees can work remotely from anywhere or from one of our 17 offices located in ireland, ukraine, belarus, russia, serbia, kazakhstan, and armenia. i live in dublin, ireland, playrix's headquarters. jh: how many employees work at playrix? mk: playrix now employs more than 4,000 people, and that number continues to grow. jh: how did covid impact the team? mk: playrix has a hybrid approach that people can work from anywhere—the office, their home, the beach, anywhere in the world. our department had 50% were working remotely in their home offices or in other countries. we wanted to maintain that culture. after covid hit, we maintained the same approach. in dublin only 30% of the staff works in the office, others could be remote. they may decide they didn't want to commute during the winter when it's rainy season here. people could decide to work from home or other remote places and we didn't really have to make many changes to our work environment. we believe people can innovate in whatever space they want. jh: how did your relationship with samsung start? mk: in 2018, we met and befriended the samsung team at a local game dev conference, white nights in st. petersburg. we met the samsung u.s. and korea teams, which has resulted in a fruitful cooperation; five playrix games, including gardenscapes, were released in the galaxy store in december 2020. i'm in touch with a lot of samsung teams from the u.s., korea, and europe. playrix gardenscapes jh: playrix won the best of galaxy store award - best casual game 2021 for gardenscapes. what does it mean to win this award? mk: we were surprised and thrilled to receive this award. it's the result of close collaboration and hard work from both the samsung and playrix teams. it's really a mutual award between playrix and samsung. jh: in what ways have you promoted winning this award? mk: we announced this across our social channels on facebook and instagram, even on austin's page! austin, the butler, has his own page on instagram. he's very social with the players and actively posts about his life. he shared news how his favorite game (gardenscapes) received this award from samsung. players were excited. it increased player loyalty too. internally, we were all excited and congratulated each other. it was really good news for all of us! we also displayed our samsung badges and redesigned our website. we use our website to talk about our company, promote our awards, and recruit others. but we don't promote the award on mobile; we want our players to have the best experience possible, focused on the game. we have one unified loading screen no matter what the country or platform. jh: what drives your team at playrix? mk: our development team is focused on making the highest quality product that brings joy to millions of users around the world. we try to maintain players' interest in the product on a daily basis with additional content like themed events. jh: how did playrix come up with the game gardenscapes? mk: originally gardenscapes was a pc hidden object game—to beat levels, you had to open rooms, and search for items to help austin the butler restore the dilapidated mansion and garden. while developing the mobile version, the visuals of the game changed, but the mechanics stayed the same. the user still had to open rooms and could even change the outfit of the game's main character, austin the butler. during the soft launch, the metrics were alright, but they weren't groundbreaking. around 2014, at our annual company conference playrixcon, one of the teams suggested combining мatch-3 mechanics with the gardenscapes storyline during a creative contest. we decided to test the idea. the first game prototype was named green dream, and it was later soft-launched. the metrics were off the charts! in just six months, the hidden object mechanics were replaced with match-3 levels. the mobile game was later released in its updated form, in july 2016. with more players using their smartphones, we noticed hidden objects were more difficult to find in the condensed space vs. on a large pc display. we realized we could bring in more players by shifting from hidden objects to the match-3 concept. this was a major turning point for us. jh: how did you come up with the character austin the butler? mk: initially, the technical assignment was rather vague: "a butler, colonial style, should appeal to our target audience." the first sketches of austin were rather clichéd, so we started thinking about what would evoke warm feelings in players. we decided to draw inspiration from icons of the 60s and 70s, namely the beatles, to resonate with our target audience's memories of their youth. so that's how austin got his mustache and sideburns and started looking a bit like ringo starr. the suspenders, bow tie, and baldness added to his aristocratic image. but looks aren't the main reason why austin is so popular. he's mostly beloved for his personality—he has his own opinions and desires, he makes mistakes just like everybody else, and he can get nostalgic or crack a joke. jh: that's interesting austin was inspired by the beatles. that would appeal to many gamers. [austin was created 10 years ago by the game design team.] jh: what inspired the scapes series? mk: we wanted to create a game that would bring joy to millions of users around the world and distract them from the monotony of daily routines. it's our idea of a warm and cozy place, where you can relax by tending to the garden and renovating the surrounding area. and i think we achieved our goal. [playrix has gardenscapes, homescapes, farmscapes, and wildscapes as part of the scapes series.] game ideas, discoverability, and reach jh: how many games has playrix published, and how many are in galaxy store? mk: playrix has published seven mobile games in total, five of which are in galaxy store. [gardenscapes, homescapes, fishdom, township, and manor matters] jh: where do you get game ideas? mk: our game producers are open to new ideas that appear in the market—we keep track of new games of various genres, not only casual ones, and we are always ready to experiment. this applies both to game events and mechanics. our strategy is to stay abreast of what's going on in the market, explore the ever-changing preferences of users, and not be afraid to try new things. we have a fairly large game development team, which includes game designers and producers—these are creative people who not only draw ideas from their own imagination, but also closely follow trends and audience interests, and are not afraid to experiment. they could have mini-brainstorms, major brainstorms, thinking about new games. our goal is not to produce as many games as possible, but rather we are focused to create aaa games, games with high quality. that's why we don't focus on brainstorms as much. we also see gardenscapes as not just a match-3 game with decorations and a story line, but as an entertainment platform. for example, within gardenscapes, players can also play other genres as a mini-event; they can play mini-games like mini puzzles, collapse mechanics, merge mechanics. it's an entertainment platform. jh: so people could be online all day! those mini-games increase even more engagement. mk: yes, that's true! people could spend a whole day gaming. about a year ago during the pandemic, we received a lot of thanks from our customers. they appreciated our games. they didn't experience mental problems or depression being in stuck at home and started to get involved with austin's story and his family. it was a mini journey in a fantasy world. they were able to derive a lot of positive energy to overcome the tough lockdowns in the real world. jh: that's a great message, a very positive experience. the growth of gardenscapes and the other scapes games must have exploded. mk: yes, since people were in lockdown, they were looking for other things to do. we had "free to play" games. new customers started to play and joined our established core audience. with the samsung team, we were able to offer gardenscapes, homescapes, and other games at an opportune time via galaxy store. we feel we've brought a very positive input to the whole gaming world. jh: that's excellent. what was your ranking before and during the pandemic? mk: we were in the top 5 before and now we are in the top 2 or 3! one day we hope to be #1. it's definitely going in the right direction. jh: what is the workflow when designing, developing, and publishing a game? mk: our work processes don't differ significantly from those adopted by other companies. when our producers come up with an idea, they pass it on to the development team. they then implement a prototype of the game, which we first test internally to see how interested we are in developing it further. we do "soft launches" to a small external audience to test the games. we also use different marketing tools during internal testing to assess how the user will play the game. if it successfully passes this stage, we create a plan to support and develop the game—we plan new levels, in-game events that can be timed to national and international holidays, and launch the game. jh: what's your criteria for success? how do you determine if a new game will become a aaa game? mk: we measure the basic metrics of the game. we look at retention metrics: at day 1, 7, 14, 30, etc. based on these metrics, we can predict how many will continue playing the game after 30 days after download. we also look at pay metrics: the number of players who will pay in the game, the number of payments, login frequency, etc. plus, we look at the metrics from our established games and compare them to predict the next aaa game. jh: how long does it take to go from concept to published? mk: at playrix, we want to develop very high-quality games that will bring players joy for a long time, which is why we don't set any internal deadlines for development. it all depends on the specific game—we spend as much time on each title as we need to make it a aaa hit. jh: with all the competition for games, what has been your strategy for discoverability (for a new game) within galaxy store? mk: we use in-store support from the samsung team to show a new game will be visible and promote it at the maximum level in galaxy store. we also use promotional activity outside the store using our resources, such as social channels like instagram and some marketing campaigns. jh: how many downloads/users has gardenscapes had? mk: today, gardenscapes is one of our top hit games—more than 50,000 people play it every day on samsung devices, and the number of mau [monthly active users] has reached 250,000 users. jh: on your website, it says playrix is the 2nd successful mobile game developer in terms of revenue. what has been your strategy for generating revenue? mk: when the game you're working on is fun to play, its financial success depends on two factors—operation and marketing. the most amazing game with the perfect narrative won't succeed without good marketing. however, even if you invest a bunch of resources into marketing a bad game, it will still fail, which is why we pay close attention to both aspects. we're constantly looking for new creative concepts and testing marketing hypotheses, and the metrics tell us that our approach works. we also frequently introduce successful mini-game mechanics into our games that were previously only used in advertising. find out more about playrix in part 2 of this series. additional resources on the samsung developers site the samsung developers site has many resources for developers looking to build for and integrate with samsung devices and services. stay in touch with the latest news by creating a free account and subscribing to our monthly newsletter. visit the marketing resources page for information on promoting and distributing your apps. finally, our developer forum is an excellent way to stay up-to-date on all things related to the galaxy ecosystem.
Jeanne Hsu
success story mobile
blogjeanne hsu, senior marketing manager for developer relations at samsung, chatted with yuki he, chairperson, ceo and founder of joyme. jeanne hsu (jh): yuki, what was your professional journey that led you to joyme? yuki he (yh): i entered the internet industry in 2003 and joined tencent in product management when they started their product team. i was doing entertainment and social apps like qq and qq pets. i enjoyed working in this industry and developed a more profound interest in social products. later on in 2013, i started working on overseas products, got familiar with the global internet market, and was responsible for a utility product. at that time, samsung also partnered with us to include our product. i also got a chance to visit samsung's south korean headquarters to discuss other partnership matters. in 2015, i participated in the entrepreneurial process of musical.ly (later became tiktok) as a director. i saw a promising future of combining live video and social interaction. i wanted to use both to connect people virtually and in real time no matter where they were located. i saw the vast opportunities in the u.s. market, so i left and decided to build my own company, joyme. jh: where is joyme located? yh: joyme is in various regions including the los angeles (u.s.), singapore, brazil, and the middle east. jh: how many employees work at joyme? yh: we have 500 people total including 300 employees and 200 contractors. jh: how did the relationship with samsung first start? yh: we published liveme in galaxy store in 2020. we already had a relationship with samsung from my previous work. so this was a natural extension of the partnership. jh: best of galaxy store award – 2021 best entertainment app for joyme's liveme app. what does it mean to win this award? yh: we take this award very seriously and especially thank samsung for the recognition. samsung has many users and is one of the largest store platforms in the world. samsung is a world-renowned company, with a prominent brand name. winning this award also gives us great motivation to continue creating even better products for samsung users. jh: in what ways have you promoted winning the award? yh: we have promoted this fantastic news through the media agency and received positive market feedback. we plan to promote the award-winning news through international media, liveme's social media, and the official website. we believe the recognition from samsung is going to boost our branding and let more samsung users get to know more about us. winning the award gives us great motivation to continue doing what we do best: give our users and the entertainment community the best service. liveme – 2021 best entertainment app jh: what have you noticed about mobile trends and liveme? yh: the mobile phone camera has changed people's lives when they interact with their phones. you can be anywhere in the world to connect online with people, show your talent, expand your circle of friends, and share parts of your life. bringing the community closer together is the original concept of liveme. i felt the video and interactive components were important. people can go online with liveme and feel happier. jh: are there any unique aspects or optimizations to the galaxy store version of liveme? yh: we integrated the payment channel sdk with the samsung iap (in-app purchase) sdk. our base operation is android. galaxy store is very good for the developer so we don't have to do different versions. it saves a lot of time and resources. in the future, we hope to have deeper integration with samsung. jh: how did you come up with the concept for liveme? yh: in 2015, livestream video was not as popular as it is now; people took pics. but the camera performance on mobile phones was becoming more sophisticated and advanced. i found that many users gradually developed taking videos on their mobile phones. video is a richer content carrier than still images or plain text. i could see the future of information transmission trends. then video transmission changed; it was faster and people could send full rich videos instead of choppy/frozen bits of pixels. now instead of just watching a video, people could interact with live video streams. users could respond with comments or emojis in real time. the live-stream video experience further enhanced the connection between people. for example, people can stay at home and make friends all over the world. they use this platform to show off their talents. having this vision of connecting the world was the original idea that inspired me to develop liveme. broadcasters and business model jh: i noticed on facebook that liveme's tagline reads: “create content, meet friends, and make money.” tell me more about liveme and the business model. how do the broadcasters make money? yh: broadcasters earn money by presenting engaging content in their livestream channel. they can build up a global fan base. then viewers can send virtual gifts to show their appreciation. they also encourage people to subscribe to their channel. for example, out of 100k people that enter a broadcaster's room, 20% could give them gifts like flower animations and virtual diamonds. the more gifts they receive from their fans, the better. it shows a very active community. some broadcasters see this as a hobby, but some make it their professional career. we're not talking about famous celebrities who have their own channels but rather the uber driver, bar singer or amateur dancer. they can use liveme as an entertainment channel and make money doing it as a living. we help 300,000 broadcasters earn money in the u.s. globally we have a million broadcasters that are making good money via liveme. it's a very powerful story. not only do they receive gifts from their fans, but they also get benefits from liveme. we also give the broadcasters gifts depending on the volume and activity of their fan base. it helps incent broadcasters to generate new content. every month, we give several millions of u.s. dollars to the broadcasters. what's more, we have an ongoing plan with a $60 million investment to support our broadcasters and creators. we're able to offer jobs to people all over: in the u.s., brazil, japan, and the middle east, just to mention a few. jh: what a strong message. “we believe in you, and are willing to pay you for your creativity attracting a large fan base.” it's an intriguing business model. what else are broadcasters doing to increase their audience? yh: we have talented broadcasters who create content and make friends by livestreaming. they can interact with viewers. fans can also beam in to the “room”, do challenges and play mini games with the broadcasters. there can be up to nine people in a livestreaming room. youtube cannot do that. fans then become part of the action with other community members. and there are more people who are commenting, giving gifts, and cheering these people on. having this very interactive community lends itself to many creative ideas. we can combine games with the livestreaming: in soccer, the broadcaster guards the goalpost and another person kicks the ball, in real-time. people can play casual games together. then the community interacts as they play games, dance or sing. it's very entertaining! app ideas, discoverability and reach jh: how many apps has joyme published, and how many are on galaxy store? yh: liveme and photogrid are the two main apps of joyme. liveme is a live video social app and photogrid is a video and photo editing app. both liveme and photogrid are on galaxy store. jh: where do you get your app ideas? yh: user feedback is important to us. they give us ideas and inspiration. we learn from other apps (funny and creative ideas from games and apps). we'll also run campaigns to celebrate special events like our 6th birthday this past april; fans sent us video birthday cards. we do marketing research to see if there is new technology we could use. for example, new technologies like virtual character ai improves the user creative experience in our apps. jh: what is the work flow when designing, developing and publishing an app? yh: there are six steps for our app development and publishing. first, we need to list out the product project needs. it is necessary to determine the project's overall plan, the timeline, the general framework, the main functions, and the core belief of the app. what are the needs of target users? what kind of value can this app create for the user? once the app has its primary functions defined, we research to understand potential competitors and competitive environment. for example, is it a saturated market or a competitive market? next is the realization of the app function by designing the first draft of ui and ux. after multiple meetings and rendering, we will have the final interface design ready. the product will then enter the research and development stage. while forming the app with programming, we prepare everything in the app store account for release. the next step is to test the app. we test the app thoroughly before release by having internal test users test the first version and extract user feedback to improve and optimize the user experience. finally, it is time to publish the app. we'll use the app store account to release and publish the tested app, and leave three to five days to fix any bugs after the app is released. jh: with all the competition for apps, what has been your strategy for discoverability? yh: we buy ads traditionally from google and meta, etc. every app developer does that. but we have a community of broadcasters who can promote our apps as well. they will share their live-steaming with their fans by cross-promoting from other channels they've cultivated. we can see that more people are making friends and enjoying the interaction with the broadcasters. friends are telling others about broadcasters that appeal to them. there's nothing more compelling than the “tell a friend” concept. we do some pr and marketing events. before covid, we used to do live in-person promotions with iheartradio; one was for the event music house. we hosted parties in la and san francisco with broadcasters, asking them to invite their friends to join in. we found that people share their experiences on social media. it was a fun way to promote the liveme app to their friends. now we hold other online events, building on our platform, so people worldwide can participate. jh: what has been your strategy for generating revenue? yh: liveme generates revenue by iap (in-app purchases) for virtual gifts to support favorite broadcasters or participate in in-app events. to encourage users to be more engaged, we create monthly competitions with different themes, holidays, and unique virtual 3d animation gifts to best express users' distinct support styles. jh: in the last five years, liveme is in 85 countries. how do you attribute your growth and expansion? yh: liveme started with multiple tests and trials in a few countries to build a solid foundation. in the early stages, it is necessary to confirm if the product provides valuable services for users that reflect the actual demand in a pilot before launching a large-scale expansion. the internet industry is getting so competitive that users' needs and requirements change every second. it is truly a great challenge for our developers. our fundamental strategy is making good products and services that genuinely exceed user expectations. joyme has also been exploring and improving under the same principle. jh: what is in the future for joyme / liveme? yh: our mission is to "connect the world and spread happiness." joyme will continue to devote itself to creating exciting pan-entertainment products. in the future, we will also develop immersive meta-universe experience products. everyone is facing different obstacles in life under the influence of the pandemic, so i hope joyme can create products that give more companionship, happiness, and love to bring our global users together. feedback and advice jh: what advice would you give developers looking to bring their apps to galaxy store? yh: for specifics about galaxy store, i recommend the following: become familiar with the policy for galaxy store. if developers ignore this, their apps will soon be off-line. understand how to control the risk of payments. different platforms have varying risks. get good feedback from users and cooperate with samsung. we do activities together with samsung and benefit from their promotions. incent galaxy store users. we give gifts to galaxy store users, such as free coins to buy gifts to send to broadcasters. it encourages users to buy more coins and engage with liveme. jh: why is it important to offer your app on galaxy store? yh: our main market is the u.s. and samsung has a major presence there. marketing jh: what are some of the ways you promote liveme? yh: here are our websites and channels: website - https://www.liveme.com/ facebook - https://www.facebook.com/streamliveme/ twitter - https://twitter.com/streamliveme (@streamlivem) youtube - https://www.youtube.com/c/livemeofficial/featured instagram - https://www.instagram.com/streamliveme/ diversity and inclusion jh: what is joyme doing related to diversity and inclusion? yh: joyme supports multiple languages and is available in many countries, so focusing on content localization based on local culture, trends, and holidays is essential. we are committed to meeting the needs of our diverse users and respecting different cultures and religions. our goal is to create a supportive community that includes all races, religions, and cultures to connect users in the various regions. our management team is 40% to 50% women; some of them have been with me for more than five years, building a good relationship with each other. we also have offices in eight countries with different nationalities and cultures, all working together. jh: i understand you were involved in the women's entrepreneurship day (wed) summit. tell us more about that. yh: yes, thanks for asking. this international annual wed summit empowers women and girls worldwide to alleviate poverty their communities. i spoke to encourage them to become active participants in the economy by becoming leaders, innovators, and entrepreneurs. it gave me an opportunity to share my story with young women from all over the world and highlight how liveme is empowering women to share their talents and follow their passions. fun jh: what do you do for fun outside of work? yh: i enjoy playing different sports and fitness; i am also into singing. i was the singer of the official theme song "song of tencent" for tencent. i participated in many singing competitions during my college years and was pretty good at it. if i didn't become a product manager in the internet industry, i would probably have become a singer. yuki singing in fact, that was one reason i launched liveme. i started out as a broadcaster and gained a lot of fans by singing and dancing. everyone has the opportunity to grow their channel. nobody knew i was the ceo of the company. once they found out, they said “i knew yuki before as a broadcaster.” now, i leave the broadcasting to the other talent. jh: it's great you started as a broadcaster. so you know firsthand how to showcase your singing and dancing talents. kudos to you! thank you so much for this interview yuki. yh: you're very welcome. i am happy to chat with you. additional resources on the samsung developers site the samsung developers site has many resources for developers looking to build for and integrate with samsung devices and services. stay in touch with the latest news by creating a free account and subscribing to our monthly newsletter. visit the marketing resources page for information on promoting and distributing your apps. finally, our developer forum is an excellent way to stay up-to-date on all things related to the galaxy ecosystem.
Jeanne Hsu
Develop Smart Hospitality Display
docweb app html5 memory optimization guide nature of this document this is a best-practice guide it is not intended to mandate compliance or to trigger any action based on compliance — use it as a reference for better app quality and user experience contents why memory matters for tv web apps understanding the memory model of web apps image and graphics memory optimization dom management and list/grid virtualization preventing memory leaks javascript memory and gc management video & media memory management data handling optimization fetch / json / cache canvas / webgl / web audio / worker cautions 1 why memory matters for tv web apps tvs have different memory constraints than smartphones or pcs understanding this difference is the starting point of optimization memory is a shared resource when one app uses too much memory, it isn't only that app that slows down — the whole tv degrades app switching gets slower, other apps in the background get killed, and system animations stutter core principle memory is managed, not borrowed make "allocate when needed, release the moment it's no longer needed" the default for every feature you design 2 understanding the memory model of web apps to optimize, you first need to know where a web app's memory goes unlike native apps, a web app's memory is spread across several layers, much of which is not directly visible to the developer 2 1 major memory-consuming areas area description developer control v8 js heap javascript objects, arrays, closures, functions, etc high dom / render tree dom nodes, render objects, computed style high decoded images not the compressed file, but the bitmap expanded for display high gpu memory textures/layers compositing layers, textures, canvas back buffer medium media buffers video/audio decode buffers, mse sourcebuffer medium network & cache http cache, fetch responses, string buffers medium engine overhead v8/blink internal structures, fonts, parsers, etc low 2 2 "compressed file size" is not "memory usage" this is one of the most important concepts for understanding memory usage even a 100 kb jpeg must be decompressed into a bitmap to be displayed most pixels take 4 bytes rgba so a single 1920×1080 image = about 8 3 mb of decode memory 1920 × 1080 × 4 ≈ 8,294,400 bytes a single 4k 3840×2160 image is about 33 mb "it's a small file, so it's fine" is a misconception the real memory is the number of pixels actually drawn on screen × 4 bytes the same applies to json when you json parse a 200 kb json string, the original string stays in memory while the parsed object tree is created on top of it the parse result can take several times more memory than the original 2 3 the v8 heap and garbage collection gc javascript is a gc language gc only reclaims objects that are no longer reachable their references are cut conversely, if a reference remains anywhere, the object is never reclaimed this is the root cause of web app memory leaks gc isn't free while gc runs, the main thread can briefly pause, which shows up as animation frame drops v8 uses a generational gc newly created objects are reclaimed cheaply in the young generation, so creating and discarding temporary objects in ordinary code is not itself a problem the place to watch is hot paths that run tens to hundreds of times per second animation loops, scroll/input handlers, tight loops creating a new object every time there makes even a cheap gc run frequently, causing frame jank so the fix is not to reduce allocations blindly, but to reuse objects only in hot paths see 6 1 the cause of a leak is not "circular references" per se, but "something is still referencing it, so gc can't reclaim it " javascript's gc reclaims even a cyclic structure a→b, b→a correctly once nothing outside references it; the same is true for cycles involving dom nodes real leaks happen when global variables, long-lived arrays/objects, closures, or unremoved event listeners keep holding an object see section 5 3 image and graphics memory optimization images are the single largest memory consumer in almost every tv web app just following the principles in this section resolves most memory problems avoid animated gifs — they use a lot of memory use css animations for simple ui motion, and if you truly need raster animation, use animated webp instead of gif 3 1 load images at the size you display most important the key is not to download an image larger than the size you display and shrink it on the device don't shrink a large original into a small area putting a 1920×1080 original into a 200×300 thumbnail slot looks small on screen, but you still download that large original and decode it at least once — wasting network, cpu, and peak memory download images resized on the server to the display size thumbnails at thumbnail size, backgrounds at background size don't count on the browser to shrink it for you the browser sometimes downscales an image to the display size, but not always, and the cost of downloading and expanding the large original is incurred regardless the reliable way to save memory is to receive an image that is already at the display size <!-- bad using a 4k original for a thumbnail --> <img src="poster_4k jpg" style="width 200px; height 300px"> <!-- → small on screen, but the 4k original is still downloaded and decoded wasted network / cpu / memory --> <!-- good serve an image sized for display from the server --> <img src="poster_200x300 jpg" width="200" height="300"> 3 2 don't load offscreen images; release them when not visible lazy loading don't load images not yet visible from scrolling load them only as they approach the viewport, via the loading="lazy" attribute or intersectionobserver <img src="poster jpg" loading="lazy" width="200" height="300" alt=" "> actively release images that leave the screen in a long tv grid, reclaim decode memory for images far from the viewport by clearing src or removing the element see section 4 on virtualization // release image memory for a card far from the viewport function releaseimage imgel { imgel removeattribute 'src' ; // or imgel src = ''; imgel removeattribute 'srcset' ; } applying content-visibility auto to large offscreen sections can defer their rendering/layout cost and associated memory offscreen-section { content-visibility auto; contain-intrinsic-size 400px 300px; /* size hint */ } 3 3 treat css background images the same way an image set via background-image also uses bitmap memory once decoded background images of hidden elements can still load, so make large backgrounds load only when shown — by attaching a class at that moment 3 4 control decode timing suddenly attaching a large image to the screen can trigger a synchronous decode on the main thread and cause jank use the decoding="async" attribute or the img decode promise to decode ahead of time, asynchronously, before display const img = new image ; img src = 'poster jpg'; await img decode ; // after decode completes container appendchild img ; // attach without a frame drop 3 5 watch out for web fonts web fonts can be as large a single consumer as images, yet are often overlooked the browser keeps a font's glyphs resident in memory, and receiving a separate file per weight/style multiplies that in particular, languages with thousands to tens of thousands of glyphs, such as cjk chinese, japanese, korean , can have a single full-glyph font file reaching several mb, so take special care first ask whether you even need a web font if the tv platform's built-in fonts are enough, not using a web font at all is the surest saving load only the weights/styles you need limit to regular/bold and don't download unused light, thin, italic, etc use subset fonts building a font file that contains only the characters you actually use greatly reduces resident memory the more glyphs a language has, the bigger the effect unicode-range prevents downloading unused ranges when you split into multiple files, but to reduce resident memory itself, the fundamental approach is to prepare a subset file that contains only the glyphs you need use font-display swap so font loading doesn't block text rendering better perceived performance to reduce transfer size, use the well-compressed woff2 /* apply a subset only the needed glyphs to a specific character range */ @font-face { font-family 'appfont'; src url 'app-latin-subset woff2' format 'woff2' ; unicode-range u+0000-00ff; /* basic latin only */ font-display swap; } 4 dom management and list/grid virtualization after images, the biggest driver of a tv web app's memory is the number of dom nodes tv apps are especially vulnerable because they typically have long grid/carousel structures with hundreds to thousands of content cards 4 1 every dom node is memory each dom element carries a node object, computed style, layout info, and if displayed a render layer if you put thousands of cards into the dom at once, all of them stay resident even when only a few are visible as the dom grows, style recalculation, layout, and compositing costs grow too, hurting performance 4 2 virtualize long lists windowing — do it virtualization is a must for long lists/grids keep only the visible items plus a small buffer actually in the dom, and recycle as the user scrolls key ideas render only the items visible in the viewport + a margin above and below, not the whole list remove from the dom or recycle elements that scroll out of view fake the full scroll height with a spacer element or a transform // conceptual example simple windowing with intersectionobserver const buffer = 5; // extra items above and below function renderwindow startindex, endindex, alldata, container { container textcontent = ''; // remove previous items → reclaim dom nodes & image memory const frag = document createdocumentfragment ; for let i = startindex - buffer; i <= endindex + buffer; i++ { if i < 0 || i >= alldata length continue; frag appendchild createcard alldata[i] ; } container appendchild frag ; } in a tv app, any list with more than ~100 items should almost always consider virtualization during validation, apps that "render thousands of cards as one big dom" are a classic memory-overrun case 4 3 recycle elements — the dom version of the object pool pattern same idea as the object pool 6 2 creating and discarding a card every time increases dom create/destroy and gc load instead, create a fixed number of dom nodes and just swap their content // create only as many card dom nodes as can be visible, then reuse them const pool = []; function getcard { return pool pop || createcard ; } function recycle card { card queryselector 'img' removeattribute 'src' ; // release image memory pool push card ; } 4 4 clean up the previous screen's dom on navigation in an spa, leaving the previous screen's dom in place keeps occupying memory on routing, remove the previous view's dom and release its listeners, timers, and observers together giving each screen component a paired mount and destroy , where destroy undoes everything it created listeners, timers, observers, dom , structurally prevents leaks see section 5 4 5 reduce excessive wrapper / shadow dom unnecessary abstraction layers increase node count cut meaningless <div> nesting and excessive wrapper components, and remove unneeded layers to keep the dom shallow and simple 4 6 beware compositing-layer gpu memory blowup separate from dom node count, the browser promotes some elements to their own compositing layers, managed as gpu textures each layer takes width × height × 4 bytes of gpu memory, by the same principle as a decoded image a single full-screen layer is about 8 mb fhd , so if layers grow to dozens or hundreds, a tv with tight gpu memory hits its limit quickly layers arise mainly from forced-promotion hints like will-change, transform translatez 0 / translate3d 0,0,0 , or from animated elements don't slap translatez 0 on every card on the belief that "promoting to a layer makes it faster " it instead wastes gpu memory and increases compositing cost turn will-change on only right before an animation and remove it when done leaving it on permanently keeps that many layers resident don't stack multiple full-screen layers front overlays, fade layers, etc use the devtools layers panel or the "layer borders" option to check the actual layer count and sizes rule promote layers "only when needed, only on the elements that need it " don't sprinkle hints out of habit 5 preventing memory leaks a memory leak is when an object that is no longer needed can't be reclaimed because something still references it, and it is fatal in long-running tv apps the patterns that cause leaks in web apps are well known 5 1 unremoved event listeners the most common cause a listener registered with addeventlistener keeps holding the target object and the callback and everything its closure captures unless you explicitly remove it in particular, listeners on long-lived objects like window and document stay until the app ends // bad the listener remains after the component is removed, holding the whole object graph window addeventlistener 'resize', this onresize ; // good 1 always remove in a matching pair window removeeventlistener 'resize', this onresize ; // good 2 clean up all at once with abortcontroller const controller = new abortcontroller ; window addeventlistener 'resize', onresize, { signal controller signal } ; element addeventlistener 'keydown', onkey, { signal controller signal } ; // on cleanup controller abort ; // removes every listener registered with this controller at once rule listeners you register when creating a component/screen must all be removed when destroying it making abortcontroller + signal your standard pattern reduces mistakes 5 2 reduce listeners with delegation in a tv grid with hundreds to thousands of cards, attaching a click/keydown listener to each card keeps as many callback closures resident as there are listeners, plus register/unregister cost every time a card is created or discarded instead, attach a single listener to a parent container and use event bubbling with event target to determine which card fired it event delegation the listener count drops to one, cutting both memory and cleanup burden // bad a listener per card → n callback closures resident cards foreach card => card addeventlistener 'click', onclick ; // good delegate to a single container → 1 listener grid addeventlistener 'click', e => { const card = e target closest ' card' ; if !card return; handleselect card dataset id ; } ; it pairs especially well with virtualization 4 2 and element recycling 4 3 even when you swap card dom, the container's listener stays, so you don't have to re-register a listener each time cleanup is also just removing the one container listener, which reduces the listener-leak risk from 5 1 5 3 unremoved timers and callbacks if setinterval, settimeout, or requestanimationframe reference objects in their callbacks, those objects stay alive as long as the timer does in particular, setinterval and a recursive requestanimationframe run forever unless you explicitly stop them const timerid = setinterval update, 1000 ; // cleanup clearinterval timerid ; let rafid = requestanimationframe loop ; // cleanup cancelanimationframe rafid ; always stop animation loops and polling timers when the screen goes to the background or is destroyed you can detect visibility with the visibilitychange event 5 4 detached dom nodes a node removed from the dom but still referenced by a javascript variable is not gc'd this is called "detached dom" and is a classic type of web app leak // bad const cache = {}; const list = document getelementbyid 'list' ; cache oldlist = list; // keeps a reference list remove ; // removed from the dom // removed from the dom, but cache oldlist still holds it, so it isn't reclaimed including all child nodes // good cache oldlist = null; // cut the reference so it can be reclaimed 5 5 global caches/arrays that grow without bound logs, event records, response caches, and so on grow without limit if you keep piling them into global arrays/objects always cap the size e g , lru or clear periodically because map preserves insertion order, deleting and re-inserting an item on each access keeps the "least recently used" item at the front, giving you a simple lru // a simple bounded lru cache const max = 50; const cache = new map ; function get key { if !cache has key return undefined; const value = cache get key ; cache delete key ; // delete, then cache set key, value ; // re-insert → most-recently-used moves to the back return value; } function put key, value { if cache has key cache delete key ; // reset order on update else if cache size >= max { cache delete cache keys next value ; // evict the least-recently-used front } cache set key, value ; } 5 6 large objects held by closures a closure captures variables from its outer scope a single callback can keep a huge data structure alive reference only the values you actually need inside the callback 5 7 use weakmap / weakref when you want to attach extra info to an object without affecting its lifetime, use weakmap when the key object disappears, the related entry is reclaimed automatically const metadata = new weakmap ; metadata set domnode, { lastfocused 0 } ; // when domnode is gc'd, this entry disappears too 5 8 release memory aggressively when backgrounded as seen in section 1, when memory is low the tv kills background apps if your app holds a lot of memory while off-screen the user switched to another app/input , it becomes the first to be killed and reloads from scratch on return, hurting ux so the moment your app becomes invisible, give back memory you don't currently need release offscreen images / decoded bitmaps 3 2 return videos/decoders not currently playing 7 1 clear caches you can rebuild 5 5 stop animation loops / polling timers 5 3 detect show/hide with visibilitychange document hidden release resources the moment the app is hidden, and restore only what's needed when it becomes visible again document addeventlistener 'visibilitychange', => { if document hidden { releaseoffscreenimages ; // release image bitmaps pauseandreleasevideos ; // return videos not currently playing stopanimationloops ; // stop raf / timers trimcaches ; // clear caches you can rebuild } else { restoreonresume ; // on return, re-prepare only what's needed } } ; rule preserve lightweight state such as scroll position and focus, but drop heavy resources bitmaps, buffers, caches in the background and rebuild them on return 5 9 how to diagnose leaks in chrome devtools' memory panel, take two or more heap snapshots and compare them comparison to find objects that keep growing filter by "detached" to directly inspect detached dom nodes open and close the same screen several times, then compare snapshots; objects that keep accumulating even after closing indicate a leak 6 javascript memory and gc management 6 1 suppress memory churn memory churn means creating and discarding many temporary objects in a short time this makes gc run often, leading to animation frame drops and performance degradation watch these places especially inside animation loops requestanimationframe inside scroll handlers and input remote-control key handlers inside frequently running for loops // bad a new object/array every frame function onframe { const pos = { x computex , y computey }; // new object every frame → gc pressure moveto pos ; requestanimationframe onframe ; } // good reuse the object const pos = { x 0, y 0 }; function onframe { pos x = computex ; pos y = computey ; moveto pos ; requestanimationframe onframe ; } to maintain 60 fps, the budget per frame is about 16 ms to stay within it, minimize allocations during the frame 6 2 object pool — use with care returning reusable objects particles, card view-models, etc to a pool instead of discarding them can reduce allocation/gc but a pool has its own management cost, and an oversized pool actually increases resident memory and gc load apply it only where allocation is a real bottleneck hot paths , after measuring 6 3 choose efficient data structures choosing the right data structure for the job saves memory for large numeric data, use a typedarray int32array, float32array, uint8array, etc instead of a plain array [] it stores the values themselves densely in contiguous memory without creating a separate object per element, so the difference is large compared with, for example, an array of {x, y} objects for frequent key-value lookups, map is more suitable and clearer than an object {} ; for membership only, use set when handling large arrays, don't overuse unnecessary copies slice, spread [ arr], concat each copy allocates new memory // bad a million coordinates as an array of objects const points = []; for let i = 0; i < 1_000_000; i++ points push { x 0, y 0 } ; // good a single typedarray x, y interleaved const points = new float32array 1_000_000 * 2 ; 6 4 watch strings when concatenating string fragments many times, collecting them in an array and joining once with join is safer for memory and performance don't keep a huge response string in its original form for long extract only what you need, then cut the reference to the original so it can be reclaimed 6 5 cut references explicitly assign null to a large object you no longer need to cut the reference so gc can reclaim it especially when the variable's scope is wide or long-lived this bigdata = null; // release the large data note to empty a value, obj prop = null is generally better than delete obj prop delete can break the engine's internal object optimizations and hurt performance 6 6 your app code bundle takes memory too so far we've covered data created at runtime images, dom, objects , but your app's javascript/css code itself uses memory v8 parses loaded scripts and keeps them resident, so the bigger the bundle, the higher the baseline footprint from startup the less code you load, the less resident memory don't include unnecessarily large libraries instead of pulling in a heavy dependency whole for one or two features, use only the parts you need, or consider a lighter alternative or your own implementation also avoid including duplicate libraries that do the same thing minify + tree-shaking at build time to remove unused dead code code-split to load only per-screen code don't ship every route's code on the first screen; split with dynamic import import at entry time not loading unused screens' code into memory at all is best excessive abstraction layers increase code size the same principle as 4 5 removing unnecessary dom wrappers applies to code 7 video & media memory management the core of a tv app is mostly video playback media uses a lot of memory, so managing it matters 7 1 always release media resources that finished/left playback if you only remove a <video> element from the screen and leave it, the decoder and buffers may remain release it definitively in this order function releasevideo video { video pause ; video removeattribute 'src' ; // remove the src attribute // if you used <source> child elements, remove those too video load ; // prompt release of internal buffers/decoder // if you used mse, also clean up sourcebuffer/mediasource } don't keep multiple <video> elements alive at once when implementing preview autoplay etc , release a preview video the moment it leaves the screen a tv has a limited number of hardware video decoders, and each decoder uses large buffers reusing a single <video> element is safer than creating and discarding one per content item 7 2 mse media source extensions buffer management if you implement adaptive streaming yourself, remove the buffer for already-played ranges with sourcebuffer remove otherwise the buffer keeps growing and eats memory cap the forward buffer prefetching minutes ahead is convenient but uses a lot of memory be conservative with buffer size, especially at 4k / high bitrate 7 3 subtitle / thumbnail tracks don't keep thumbnail-preview scrub-preview sprites fully resident; load/release only the ranges you need reclaim used subtitle tracks and blob urls with url revokeobjecturl a blob url is not released unless you explicitly revoke it const url = url createobjecturl blob ; // after use url revokeobjecturl url ; 8 data handling optimization fetch / json / cache the amount and handling of data fetched over the network directly affect memory usage 8 1 fetch only as much as you need server-side filtering & paging don't fetch thousands of list items at once; split them via paging / infinite scroll don't receive large responses containing fields the client won't use design the api so the server filters down to only the needed fields e g , graphql field selection, a rest fields= parameter fetching, parsing, and storing large data itself leads to excessive memory use, which in turn degrades performance 8 2 understand the cost of json parse json parse str turns a string into an object tree, taking memory for the parsed objects on top of the original string the larger the json, the more this double occupancy hurts don't keep holding the original string reference after parsing cut it to allow reclamation for very large datasets, consider streaming parsing or partial parsing avoid the pattern of parsing everything and holding it all 8 3 don't hold parse results whole for long rather than keeping the entire list api response in memory, transform it into the shape the screen needs a view-model and then discard the original response in infinite scroll, cap and clean up data for pages already passed far from the screen data, like the dom, is a target for "windowing " 8 4 efficient data formats for large, repetitive data, use a compact representation rather than a verbose format json is usually the standard on the web, but consider the following avoid unnecessarily nested or verbose json structures; keep key names and structure compact don't stuff binary data into json as base64 about 33% bloat ; receive it as a separate binary response or an arraybuffer if very large structured data is sent repeatedly, consider binary serialization e g , protobuf, cbor 8 5 cap your caches cap response caches, image caches, and computed-result caches with an lru limit so they don't grow without bound see 5 5 don't put large data in localstorage/sessionstorage; they have size limits and are synchronous apis bad for performance if you truly need large data, use indexeddb — and still manage a cap 9 canvas / webgl / web audio / worker cautions more powerful web apis can use a lot of memory and often hold resources gc won't reclaim automatically the following applies only if you use these apis directly — skip it if you don't 9 1 canvas 2d canvas back-buffer memory = width × height × 4 bytes don't create many large canvases for an unused canvas, shrink its size to width = height = 0 to reclaim the back buffer, and cut the reference creating a large array every frame with getimagedata/putimagedata causes memory churn reuse buffers 9 2 webgl webgl resources textures, buffers, programs, framebuffers are not reclaimed by gc automatically delete them explicitly deletetexture, deletebuffer, deleteprogram, deleteframebuffer when you no longer need the context, release it with getextension 'webgl_lose_context' losecontext textures use large gpu memory by the same principle as image bitmaps control texture size and count 9 3 web audio close an audiocontext with close after use don't leave many open a decoded audiobuffer can be large; cut the reference when done 9 4 web worker a worker has its own memory space terminate a finished worker with terminate ; leaving it keeps occupying memory passing large data to a worker copies it structured clone , creating two copies use a transferable e g , transferring ownership of an arraybuffer to avoid the copy worker postmessage buffer, [buffer] ; // transfer ownership of buffer → no copy 9 5 iframe each iframe loads its own document and resources, using a lot of memory create ad / external-widget iframes only when needed, and remove them from the dom to destroy them completely when done in closing tv web app memory optimization boils down to three principles create only as much as you show — images at display size, lists only as far as visible, data only as much as needed release the moment it's no longer needed — clean up listeners, timers, observers, media, dom, and caches along their lifecycle measure and verify on a real device — confirm memory doesn't trend upward across repeated open/close and long runs apply these three principles from the design stage, and you'll deliver a smooth, stable app experience to users ↑ back to top
Develop Smart TV
docweb app html5 memory optimization guide nature of this document this is a best-practice guide it is not intended to mandate compliance or to trigger any action based on compliance — use it as a reference for better app quality and user experience contents why memory matters for tv web apps understanding the memory model of web apps image and graphics memory optimization dom management and list/grid virtualization preventing memory leaks javascript memory and gc management video & media memory management data handling optimization fetch / json / cache canvas / webgl / web audio / worker cautions 1 why memory matters for tv web apps tvs have different memory constraints than smartphones or pcs understanding this difference is the starting point of optimization memory is a shared resource when one app uses too much memory, it isn't only that app that slows down — the whole tv degrades app switching gets slower, other apps in the background get killed, and system animations stutter core principle memory is managed, not borrowed make "allocate when needed, release the moment it's no longer needed" the default for every feature you design 2 understanding the memory model of web apps to optimize, you first need to know where a web app's memory goes unlike native apps, a web app's memory is spread across several layers, much of which is not directly visible to the developer 2 1 major memory-consuming areas area description developer control v8 js heap javascript objects, arrays, closures, functions, etc high dom / render tree dom nodes, render objects, computed style high decoded images not the compressed file, but the bitmap expanded for display high gpu memory textures/layers compositing layers, textures, canvas back buffer medium media buffers video/audio decode buffers, mse sourcebuffer medium network & cache http cache, fetch responses, string buffers medium engine overhead v8/blink internal structures, fonts, parsers, etc low 2 2 "compressed file size" is not "memory usage" this is one of the most important concepts for understanding memory usage even a 100 kb jpeg must be decompressed into a bitmap to be displayed most pixels take 4 bytes rgba so a single 1920×1080 image = about 8 3 mb of decode memory 1920 × 1080 × 4 ≈ 8,294,400 bytes a single 4k 3840×2160 image is about 33 mb "it's a small file, so it's fine" is a misconception the real memory is the number of pixels actually drawn on screen × 4 bytes the same applies to json when you json parse a 200 kb json string, the original string stays in memory while the parsed object tree is created on top of it the parse result can take several times more memory than the original 2 3 the v8 heap and garbage collection gc javascript is a gc language gc only reclaims objects that are no longer reachable their references are cut conversely, if a reference remains anywhere, the object is never reclaimed this is the root cause of web app memory leaks gc isn't free while gc runs, the main thread can briefly pause, which shows up as animation frame drops v8 uses a generational gc newly created objects are reclaimed cheaply in the young generation, so creating and discarding temporary objects in ordinary code is not itself a problem the place to watch is hot paths that run tens to hundreds of times per second animation loops, scroll/input handlers, tight loops creating a new object every time there makes even a cheap gc run frequently, causing frame jank so the fix is not to reduce allocations blindly, but to reuse objects only in hot paths see 6 1 the cause of a leak is not "circular references" per se, but "something is still referencing it, so gc can't reclaim it " javascript's gc reclaims even a cyclic structure a→b, b→a correctly once nothing outside references it; the same is true for cycles involving dom nodes real leaks happen when global variables, long-lived arrays/objects, closures, or unremoved event listeners keep holding an object see section 5 3 image and graphics memory optimization images are the single largest memory consumer in almost every tv web app just following the principles in this section resolves most memory problems avoid animated gifs — they use a lot of memory use css animations for simple ui motion, and if you truly need raster animation, use animated webp instead of gif 3 1 load images at the size you display most important the key is not to download an image larger than the size you display and shrink it on the device don't shrink a large original into a small area putting a 1920×1080 original into a 200×300 thumbnail slot looks small on screen, but you still download that large original and decode it at least once — wasting network, cpu, and peak memory download images resized on the server to the display size thumbnails at thumbnail size, backgrounds at background size don't count on the browser to shrink it for you the browser sometimes downscales an image to the display size, but not always, and the cost of downloading and expanding the large original is incurred regardless the reliable way to save memory is to receive an image that is already at the display size <!-- bad using a 4k original for a thumbnail --> <img src="poster_4k jpg" style="width 200px; height 300px"> <!-- → small on screen, but the 4k original is still downloaded and decoded wasted network / cpu / memory --> <!-- good serve an image sized for display from the server --> <img src="poster_200x300 jpg" width="200" height="300"> 3 2 don't load offscreen images; release them when not visible lazy loading don't load images not yet visible from scrolling load them only as they approach the viewport, via the loading="lazy" attribute or intersectionobserver <img src="poster jpg" loading="lazy" width="200" height="300" alt=" "> actively release images that leave the screen in a long tv grid, reclaim decode memory for images far from the viewport by clearing src or removing the element see section 4 on virtualization // release image memory for a card far from the viewport function releaseimage imgel { imgel removeattribute 'src' ; // or imgel src = ''; imgel removeattribute 'srcset' ; } applying content-visibility auto to large offscreen sections can defer their rendering/layout cost and associated memory offscreen-section { content-visibility auto; contain-intrinsic-size 400px 300px; /* size hint */ } 3 3 treat css background images the same way an image set via background-image also uses bitmap memory once decoded background images of hidden elements can still load, so make large backgrounds load only when shown — by attaching a class at that moment 3 4 control decode timing suddenly attaching a large image to the screen can trigger a synchronous decode on the main thread and cause jank use the decoding="async" attribute or the img decode promise to decode ahead of time, asynchronously, before display const img = new image ; img src = 'poster jpg'; await img decode ; // after decode completes container appendchild img ; // attach without a frame drop 3 5 watch out for web fonts web fonts can be as large a single consumer as images, yet are often overlooked the browser keeps a font's glyphs resident in memory, and receiving a separate file per weight/style multiplies that in particular, languages with thousands to tens of thousands of glyphs, such as cjk chinese, japanese, korean , can have a single full-glyph font file reaching several mb, so take special care first ask whether you even need a web font if the tv platform's built-in fonts are enough, not using a web font at all is the surest saving load only the weights/styles you need limit to regular/bold and don't download unused light, thin, italic, etc use subset fonts building a font file that contains only the characters you actually use greatly reduces resident memory the more glyphs a language has, the bigger the effect unicode-range prevents downloading unused ranges when you split into multiple files, but to reduce resident memory itself, the fundamental approach is to prepare a subset file that contains only the glyphs you need use font-display swap so font loading doesn't block text rendering better perceived performance to reduce transfer size, use the well-compressed woff2 /* apply a subset only the needed glyphs to a specific character range */ @font-face { font-family 'appfont'; src url 'app-latin-subset woff2' format 'woff2' ; unicode-range u+0000-00ff; /* basic latin only */ font-display swap; } 4 dom management and list/grid virtualization after images, the biggest driver of a tv web app's memory is the number of dom nodes tv apps are especially vulnerable because they typically have long grid/carousel structures with hundreds to thousands of content cards 4 1 every dom node is memory each dom element carries a node object, computed style, layout info, and if displayed a render layer if you put thousands of cards into the dom at once, all of them stay resident even when only a few are visible as the dom grows, style recalculation, layout, and compositing costs grow too, hurting performance 4 2 virtualize long lists windowing — do it virtualization is a must for long lists/grids keep only the visible items plus a small buffer actually in the dom, and recycle as the user scrolls key ideas render only the items visible in the viewport + a margin above and below, not the whole list remove from the dom or recycle elements that scroll out of view fake the full scroll height with a spacer element or a transform // conceptual example simple windowing with intersectionobserver const buffer = 5; // extra items above and below function renderwindow startindex, endindex, alldata, container { container textcontent = ''; // remove previous items → reclaim dom nodes & image memory const frag = document createdocumentfragment ; for let i = startindex - buffer; i <= endindex + buffer; i++ { if i < 0 || i >= alldata length continue; frag appendchild createcard alldata[i] ; } container appendchild frag ; } in a tv app, any list with more than ~100 items should almost always consider virtualization during validation, apps that "render thousands of cards as one big dom" are a classic memory-overrun case 4 3 recycle elements — the dom version of the object pool pattern same idea as the object pool 6 2 creating and discarding a card every time increases dom create/destroy and gc load instead, create a fixed number of dom nodes and just swap their content // create only as many card dom nodes as can be visible, then reuse them const pool = []; function getcard { return pool pop || createcard ; } function recycle card { card queryselector 'img' removeattribute 'src' ; // release image memory pool push card ; } 4 4 clean up the previous screen's dom on navigation in an spa, leaving the previous screen's dom in place keeps occupying memory on routing, remove the previous view's dom and release its listeners, timers, and observers together giving each screen component a paired mount and destroy , where destroy undoes everything it created listeners, timers, observers, dom , structurally prevents leaks see section 5 4 5 reduce excessive wrapper / shadow dom unnecessary abstraction layers increase node count cut meaningless <div> nesting and excessive wrapper components, and remove unneeded layers to keep the dom shallow and simple 4 6 beware compositing-layer gpu memory blowup separate from dom node count, the browser promotes some elements to their own compositing layers, managed as gpu textures each layer takes width × height × 4 bytes of gpu memory, by the same principle as a decoded image a single full-screen layer is about 8 mb fhd , so if layers grow to dozens or hundreds, a tv with tight gpu memory hits its limit quickly layers arise mainly from forced-promotion hints like will-change, transform translatez 0 / translate3d 0,0,0 , or from animated elements don't slap translatez 0 on every card on the belief that "promoting to a layer makes it faster " it instead wastes gpu memory and increases compositing cost turn will-change on only right before an animation and remove it when done leaving it on permanently keeps that many layers resident don't stack multiple full-screen layers front overlays, fade layers, etc use the devtools layers panel or the "layer borders" option to check the actual layer count and sizes rule promote layers "only when needed, only on the elements that need it " don't sprinkle hints out of habit 5 preventing memory leaks a memory leak is when an object that is no longer needed can't be reclaimed because something still references it, and it is fatal in long-running tv apps the patterns that cause leaks in web apps are well known 5 1 unremoved event listeners the most common cause a listener registered with addeventlistener keeps holding the target object and the callback and everything its closure captures unless you explicitly remove it in particular, listeners on long-lived objects like window and document stay until the app ends // bad the listener remains after the component is removed, holding the whole object graph window addeventlistener 'resize', this onresize ; // good 1 always remove in a matching pair window removeeventlistener 'resize', this onresize ; // good 2 clean up all at once with abortcontroller const controller = new abortcontroller ; window addeventlistener 'resize', onresize, { signal controller signal } ; element addeventlistener 'keydown', onkey, { signal controller signal } ; // on cleanup controller abort ; // removes every listener registered with this controller at once rule listeners you register when creating a component/screen must all be removed when destroying it making abortcontroller + signal your standard pattern reduces mistakes 5 2 reduce listeners with delegation in a tv grid with hundreds to thousands of cards, attaching a click/keydown listener to each card keeps as many callback closures resident as there are listeners, plus register/unregister cost every time a card is created or discarded instead, attach a single listener to a parent container and use event bubbling with event target to determine which card fired it event delegation the listener count drops to one, cutting both memory and cleanup burden // bad a listener per card → n callback closures resident cards foreach card => card addeventlistener 'click', onclick ; // good delegate to a single container → 1 listener grid addeventlistener 'click', e => { const card = e target closest ' card' ; if !card return; handleselect card dataset id ; } ; it pairs especially well with virtualization 4 2 and element recycling 4 3 even when you swap card dom, the container's listener stays, so you don't have to re-register a listener each time cleanup is also just removing the one container listener, which reduces the listener-leak risk from 5 1 5 3 unremoved timers and callbacks if setinterval, settimeout, or requestanimationframe reference objects in their callbacks, those objects stay alive as long as the timer does in particular, setinterval and a recursive requestanimationframe run forever unless you explicitly stop them const timerid = setinterval update, 1000 ; // cleanup clearinterval timerid ; let rafid = requestanimationframe loop ; // cleanup cancelanimationframe rafid ; always stop animation loops and polling timers when the screen goes to the background or is destroyed you can detect visibility with the visibilitychange event 5 4 detached dom nodes a node removed from the dom but still referenced by a javascript variable is not gc'd this is called "detached dom" and is a classic type of web app leak // bad const cache = {}; const list = document getelementbyid 'list' ; cache oldlist = list; // keeps a reference list remove ; // removed from the dom // removed from the dom, but cache oldlist still holds it, so it isn't reclaimed including all child nodes // good cache oldlist = null; // cut the reference so it can be reclaimed 5 5 global caches/arrays that grow without bound logs, event records, response caches, and so on grow without limit if you keep piling them into global arrays/objects always cap the size e g , lru or clear periodically because map preserves insertion order, deleting and re-inserting an item on each access keeps the "least recently used" item at the front, giving you a simple lru // a simple bounded lru cache const max = 50; const cache = new map ; function get key { if !cache has key return undefined; const value = cache get key ; cache delete key ; // delete, then cache set key, value ; // re-insert → most-recently-used moves to the back return value; } function put key, value { if cache has key cache delete key ; // reset order on update else if cache size >= max { cache delete cache keys next value ; // evict the least-recently-used front } cache set key, value ; } 5 6 large objects held by closures a closure captures variables from its outer scope a single callback can keep a huge data structure alive reference only the values you actually need inside the callback 5 7 use weakmap / weakref when you want to attach extra info to an object without affecting its lifetime, use weakmap when the key object disappears, the related entry is reclaimed automatically const metadata = new weakmap ; metadata set domnode, { lastfocused 0 } ; // when domnode is gc'd, this entry disappears too 5 8 release memory aggressively when backgrounded as seen in section 1, when memory is low the tv kills background apps if your app holds a lot of memory while off-screen the user switched to another app/input , it becomes the first to be killed and reloads from scratch on return, hurting ux so the moment your app becomes invisible, give back memory you don't currently need release offscreen images / decoded bitmaps 3 2 return videos/decoders not currently playing 7 1 clear caches you can rebuild 5 5 stop animation loops / polling timers 5 3 detect show/hide with visibilitychange document hidden release resources the moment the app is hidden, and restore only what's needed when it becomes visible again document addeventlistener 'visibilitychange', => { if document hidden { releaseoffscreenimages ; // release image bitmaps pauseandreleasevideos ; // return videos not currently playing stopanimationloops ; // stop raf / timers trimcaches ; // clear caches you can rebuild } else { restoreonresume ; // on return, re-prepare only what's needed } } ; rule preserve lightweight state such as scroll position and focus, but drop heavy resources bitmaps, buffers, caches in the background and rebuild them on return 5 9 how to diagnose leaks in chrome devtools' memory panel, take two or more heap snapshots and compare them comparison to find objects that keep growing filter by "detached" to directly inspect detached dom nodes open and close the same screen several times, then compare snapshots; objects that keep accumulating even after closing indicate a leak 6 javascript memory and gc management 6 1 suppress memory churn memory churn means creating and discarding many temporary objects in a short time this makes gc run often, leading to animation frame drops and performance degradation watch these places especially inside animation loops requestanimationframe inside scroll handlers and input remote-control key handlers inside frequently running for loops // bad a new object/array every frame function onframe { const pos = { x computex , y computey }; // new object every frame → gc pressure moveto pos ; requestanimationframe onframe ; } // good reuse the object const pos = { x 0, y 0 }; function onframe { pos x = computex ; pos y = computey ; moveto pos ; requestanimationframe onframe ; } to maintain 60 fps, the budget per frame is about 16 ms to stay within it, minimize allocations during the frame 6 2 object pool — use with care returning reusable objects particles, card view-models, etc to a pool instead of discarding them can reduce allocation/gc but a pool has its own management cost, and an oversized pool actually increases resident memory and gc load apply it only where allocation is a real bottleneck hot paths , after measuring 6 3 choose efficient data structures choosing the right data structure for the job saves memory for large numeric data, use a typedarray int32array, float32array, uint8array, etc instead of a plain array [] it stores the values themselves densely in contiguous memory without creating a separate object per element, so the difference is large compared with, for example, an array of {x, y} objects for frequent key-value lookups, map is more suitable and clearer than an object {} ; for membership only, use set when handling large arrays, don't overuse unnecessary copies slice, spread [ arr], concat each copy allocates new memory // bad a million coordinates as an array of objects const points = []; for let i = 0; i < 1_000_000; i++ points push { x 0, y 0 } ; // good a single typedarray x, y interleaved const points = new float32array 1_000_000 * 2 ; 6 4 watch strings when concatenating string fragments many times, collecting them in an array and joining once with join is safer for memory and performance don't keep a huge response string in its original form for long extract only what you need, then cut the reference to the original so it can be reclaimed 6 5 cut references explicitly assign null to a large object you no longer need to cut the reference so gc can reclaim it especially when the variable's scope is wide or long-lived this bigdata = null; // release the large data note to empty a value, obj prop = null is generally better than delete obj prop delete can break the engine's internal object optimizations and hurt performance 6 6 your app code bundle takes memory too so far we've covered data created at runtime images, dom, objects , but your app's javascript/css code itself uses memory v8 parses loaded scripts and keeps them resident, so the bigger the bundle, the higher the baseline footprint from startup the less code you load, the less resident memory don't include unnecessarily large libraries instead of pulling in a heavy dependency whole for one or two features, use only the parts you need, or consider a lighter alternative or your own implementation also avoid including duplicate libraries that do the same thing minify + tree-shaking at build time to remove unused dead code code-split to load only per-screen code don't ship every route's code on the first screen; split with dynamic import import at entry time not loading unused screens' code into memory at all is best excessive abstraction layers increase code size the same principle as 4 5 removing unnecessary dom wrappers applies to code 7 video & media memory management the core of a tv app is mostly video playback media uses a lot of memory, so managing it matters 7 1 always release media resources that finished/left playback if you only remove a <video> element from the screen and leave it, the decoder and buffers may remain release it definitively in this order function releasevideo video { video pause ; video removeattribute 'src' ; // remove the src attribute // if you used <source> child elements, remove those too video load ; // prompt release of internal buffers/decoder // if you used mse, also clean up sourcebuffer/mediasource } don't keep multiple <video> elements alive at once when implementing preview autoplay etc , release a preview video the moment it leaves the screen a tv has a limited number of hardware video decoders, and each decoder uses large buffers reusing a single <video> element is safer than creating and discarding one per content item 7 2 mse media source extensions buffer management if you implement adaptive streaming yourself, remove the buffer for already-played ranges with sourcebuffer remove otherwise the buffer keeps growing and eats memory cap the forward buffer prefetching minutes ahead is convenient but uses a lot of memory be conservative with buffer size, especially at 4k / high bitrate 7 3 subtitle / thumbnail tracks don't keep thumbnail-preview scrub-preview sprites fully resident; load/release only the ranges you need reclaim used subtitle tracks and blob urls with url revokeobjecturl a blob url is not released unless you explicitly revoke it const url = url createobjecturl blob ; // after use url revokeobjecturl url ; 8 data handling optimization fetch / json / cache the amount and handling of data fetched over the network directly affect memory usage 8 1 fetch only as much as you need server-side filtering & paging don't fetch thousands of list items at once; split them via paging / infinite scroll don't receive large responses containing fields the client won't use design the api so the server filters down to only the needed fields e g , graphql field selection, a rest fields= parameter fetching, parsing, and storing large data itself leads to excessive memory use, which in turn degrades performance 8 2 understand the cost of json parse json parse str turns a string into an object tree, taking memory for the parsed objects on top of the original string the larger the json, the more this double occupancy hurts don't keep holding the original string reference after parsing cut it to allow reclamation for very large datasets, consider streaming parsing or partial parsing avoid the pattern of parsing everything and holding it all 8 3 don't hold parse results whole for long rather than keeping the entire list api response in memory, transform it into the shape the screen needs a view-model and then discard the original response in infinite scroll, cap and clean up data for pages already passed far from the screen data, like the dom, is a target for "windowing " 8 4 efficient data formats for large, repetitive data, use a compact representation rather than a verbose format json is usually the standard on the web, but consider the following avoid unnecessarily nested or verbose json structures; keep key names and structure compact don't stuff binary data into json as base64 about 33% bloat ; receive it as a separate binary response or an arraybuffer if very large structured data is sent repeatedly, consider binary serialization e g , protobuf, cbor 8 5 cap your caches cap response caches, image caches, and computed-result caches with an lru limit so they don't grow without bound see 5 5 don't put large data in localstorage/sessionstorage; they have size limits and are synchronous apis bad for performance if you truly need large data, use indexeddb — and still manage a cap 9 canvas / webgl / web audio / worker cautions more powerful web apis can use a lot of memory and often hold resources gc won't reclaim automatically the following applies only if you use these apis directly — skip it if you don't 9 1 canvas 2d canvas back-buffer memory = width × height × 4 bytes don't create many large canvases for an unused canvas, shrink its size to width = height = 0 to reclaim the back buffer, and cut the reference creating a large array every frame with getimagedata/putimagedata causes memory churn reuse buffers 9 2 webgl webgl resources textures, buffers, programs, framebuffers are not reclaimed by gc automatically delete them explicitly deletetexture, deletebuffer, deleteprogram, deleteframebuffer when you no longer need the context, release it with getextension 'webgl_lose_context' losecontext textures use large gpu memory by the same principle as image bitmaps control texture size and count 9 3 web audio close an audiocontext with close after use don't leave many open a decoded audiobuffer can be large; cut the reference when done 9 4 web worker a worker has its own memory space terminate a finished worker with terminate ; leaving it keeps occupying memory passing large data to a worker copies it structured clone , creating two copies use a transferable e g , transferring ownership of an arraybuffer to avoid the copy worker postmessage buffer, [buffer] ; // transfer ownership of buffer → no copy 9 5 iframe each iframe loads its own document and resources, using a lot of memory create ad / external-widget iframes only when needed, and remove them from the dom to destroy them completely when done in closing tv web app memory optimization boils down to three principles create only as much as you show — images at display size, lists only as far as visible, data only as much as needed release the moment it's no longer needed — clean up listeners, timers, observers, media, dom, and caches along their lifecycle measure and verify on a real device — confirm memory doesn't trend upward across repeated open/close and long runs apply these three principles from the design stage, and you'll deliver a smooth, stable app experience to users ↑ back to top
Develop Smart Signage
docweb app html5 memory optimization guide nature of this document this is a best-practice guide it is not intended to mandate compliance or to trigger any action based on compliance — use it as a reference for better app quality and user experience contents why memory matters for tv web apps understanding the memory model of web apps image and graphics memory optimization dom management and list/grid virtualization preventing memory leaks javascript memory and gc management video & media memory management data handling optimization fetch / json / cache canvas / webgl / web audio / worker cautions 1 why memory matters for tv web apps tvs have different memory constraints than smartphones or pcs understanding this difference is the starting point of optimization memory is a shared resource when one app uses too much memory, it isn't only that app that slows down — the whole tv degrades app switching gets slower, other apps in the background get killed, and system animations stutter core principle memory is managed, not borrowed make "allocate when needed, release the moment it's no longer needed" the default for every feature you design 2 understanding the memory model of web apps to optimize, you first need to know where a web app's memory goes unlike native apps, a web app's memory is spread across several layers, much of which is not directly visible to the developer 2 1 major memory-consuming areas area description developer control v8 js heap javascript objects, arrays, closures, functions, etc high dom / render tree dom nodes, render objects, computed style high decoded images not the compressed file, but the bitmap expanded for display high gpu memory textures/layers compositing layers, textures, canvas back buffer medium media buffers video/audio decode buffers, mse sourcebuffer medium network & cache http cache, fetch responses, string buffers medium engine overhead v8/blink internal structures, fonts, parsers, etc low 2 2 "compressed file size" is not "memory usage" this is one of the most important concepts for understanding memory usage even a 100 kb jpeg must be decompressed into a bitmap to be displayed most pixels take 4 bytes rgba so a single 1920×1080 image = about 8 3 mb of decode memory 1920 × 1080 × 4 ≈ 8,294,400 bytes a single 4k 3840×2160 image is about 33 mb "it's a small file, so it's fine" is a misconception the real memory is the number of pixels actually drawn on screen × 4 bytes the same applies to json when you json parse a 200 kb json string, the original string stays in memory while the parsed object tree is created on top of it the parse result can take several times more memory than the original 2 3 the v8 heap and garbage collection gc javascript is a gc language gc only reclaims objects that are no longer reachable their references are cut conversely, if a reference remains anywhere, the object is never reclaimed this is the root cause of web app memory leaks gc isn't free while gc runs, the main thread can briefly pause, which shows up as animation frame drops v8 uses a generational gc newly created objects are reclaimed cheaply in the young generation, so creating and discarding temporary objects in ordinary code is not itself a problem the place to watch is hot paths that run tens to hundreds of times per second animation loops, scroll/input handlers, tight loops creating a new object every time there makes even a cheap gc run frequently, causing frame jank so the fix is not to reduce allocations blindly, but to reuse objects only in hot paths see 6 1 the cause of a leak is not "circular references" per se, but "something is still referencing it, so gc can't reclaim it " javascript's gc reclaims even a cyclic structure a→b, b→a correctly once nothing outside references it; the same is true for cycles involving dom nodes real leaks happen when global variables, long-lived arrays/objects, closures, or unremoved event listeners keep holding an object see section 5 3 image and graphics memory optimization images are the single largest memory consumer in almost every tv web app just following the principles in this section resolves most memory problems avoid animated gifs — they use a lot of memory use css animations for simple ui motion, and if you truly need raster animation, use animated webp instead of gif 3 1 load images at the size you display most important the key is not to download an image larger than the size you display and shrink it on the device don't shrink a large original into a small area putting a 1920×1080 original into a 200×300 thumbnail slot looks small on screen, but you still download that large original and decode it at least once — wasting network, cpu, and peak memory download images resized on the server to the display size thumbnails at thumbnail size, backgrounds at background size don't count on the browser to shrink it for you the browser sometimes downscales an image to the display size, but not always, and the cost of downloading and expanding the large original is incurred regardless the reliable way to save memory is to receive an image that is already at the display size <!-- bad using a 4k original for a thumbnail --> <img src="poster_4k jpg" style="width 200px; height 300px"> <!-- → small on screen, but the 4k original is still downloaded and decoded wasted network / cpu / memory --> <!-- good serve an image sized for display from the server --> <img src="poster_200x300 jpg" width="200" height="300"> 3 2 don't load offscreen images; release them when not visible lazy loading don't load images not yet visible from scrolling load them only as they approach the viewport, via the loading="lazy" attribute or intersectionobserver <img src="poster jpg" loading="lazy" width="200" height="300" alt=" "> actively release images that leave the screen in a long tv grid, reclaim decode memory for images far from the viewport by clearing src or removing the element see section 4 on virtualization // release image memory for a card far from the viewport function releaseimage imgel { imgel removeattribute 'src' ; // or imgel src = ''; imgel removeattribute 'srcset' ; } applying content-visibility auto to large offscreen sections can defer their rendering/layout cost and associated memory offscreen-section { content-visibility auto; contain-intrinsic-size 400px 300px; /* size hint */ } 3 3 treat css background images the same way an image set via background-image also uses bitmap memory once decoded background images of hidden elements can still load, so make large backgrounds load only when shown — by attaching a class at that moment 3 4 control decode timing suddenly attaching a large image to the screen can trigger a synchronous decode on the main thread and cause jank use the decoding="async" attribute or the img decode promise to decode ahead of time, asynchronously, before display const img = new image ; img src = 'poster jpg'; await img decode ; // after decode completes container appendchild img ; // attach without a frame drop 3 5 watch out for web fonts web fonts can be as large a single consumer as images, yet are often overlooked the browser keeps a font's glyphs resident in memory, and receiving a separate file per weight/style multiplies that in particular, languages with thousands to tens of thousands of glyphs, such as cjk chinese, japanese, korean , can have a single full-glyph font file reaching several mb, so take special care first ask whether you even need a web font if the tv platform's built-in fonts are enough, not using a web font at all is the surest saving load only the weights/styles you need limit to regular/bold and don't download unused light, thin, italic, etc use subset fonts building a font file that contains only the characters you actually use greatly reduces resident memory the more glyphs a language has, the bigger the effect unicode-range prevents downloading unused ranges when you split into multiple files, but to reduce resident memory itself, the fundamental approach is to prepare a subset file that contains only the glyphs you need use font-display swap so font loading doesn't block text rendering better perceived performance to reduce transfer size, use the well-compressed woff2 /* apply a subset only the needed glyphs to a specific character range */ @font-face { font-family 'appfont'; src url 'app-latin-subset woff2' format 'woff2' ; unicode-range u+0000-00ff; /* basic latin only */ font-display swap; } 4 dom management and list/grid virtualization after images, the biggest driver of a tv web app's memory is the number of dom nodes tv apps are especially vulnerable because they typically have long grid/carousel structures with hundreds to thousands of content cards 4 1 every dom node is memory each dom element carries a node object, computed style, layout info, and if displayed a render layer if you put thousands of cards into the dom at once, all of them stay resident even when only a few are visible as the dom grows, style recalculation, layout, and compositing costs grow too, hurting performance 4 2 virtualize long lists windowing — do it virtualization is a must for long lists/grids keep only the visible items plus a small buffer actually in the dom, and recycle as the user scrolls key ideas render only the items visible in the viewport + a margin above and below, not the whole list remove from the dom or recycle elements that scroll out of view fake the full scroll height with a spacer element or a transform // conceptual example simple windowing with intersectionobserver const buffer = 5; // extra items above and below function renderwindow startindex, endindex, alldata, container { container textcontent = ''; // remove previous items → reclaim dom nodes & image memory const frag = document createdocumentfragment ; for let i = startindex - buffer; i <= endindex + buffer; i++ { if i < 0 || i >= alldata length continue; frag appendchild createcard alldata[i] ; } container appendchild frag ; } in a tv app, any list with more than ~100 items should almost always consider virtualization during validation, apps that "render thousands of cards as one big dom" are a classic memory-overrun case 4 3 recycle elements — the dom version of the object pool pattern same idea as the object pool 6 2 creating and discarding a card every time increases dom create/destroy and gc load instead, create a fixed number of dom nodes and just swap their content // create only as many card dom nodes as can be visible, then reuse them const pool = []; function getcard { return pool pop || createcard ; } function recycle card { card queryselector 'img' removeattribute 'src' ; // release image memory pool push card ; } 4 4 clean up the previous screen's dom on navigation in an spa, leaving the previous screen's dom in place keeps occupying memory on routing, remove the previous view's dom and release its listeners, timers, and observers together giving each screen component a paired mount and destroy , where destroy undoes everything it created listeners, timers, observers, dom , structurally prevents leaks see section 5 4 5 reduce excessive wrapper / shadow dom unnecessary abstraction layers increase node count cut meaningless <div> nesting and excessive wrapper components, and remove unneeded layers to keep the dom shallow and simple 4 6 beware compositing-layer gpu memory blowup separate from dom node count, the browser promotes some elements to their own compositing layers, managed as gpu textures each layer takes width × height × 4 bytes of gpu memory, by the same principle as a decoded image a single full-screen layer is about 8 mb fhd , so if layers grow to dozens or hundreds, a tv with tight gpu memory hits its limit quickly layers arise mainly from forced-promotion hints like will-change, transform translatez 0 / translate3d 0,0,0 , or from animated elements don't slap translatez 0 on every card on the belief that "promoting to a layer makes it faster " it instead wastes gpu memory and increases compositing cost turn will-change on only right before an animation and remove it when done leaving it on permanently keeps that many layers resident don't stack multiple full-screen layers front overlays, fade layers, etc use the devtools layers panel or the "layer borders" option to check the actual layer count and sizes rule promote layers "only when needed, only on the elements that need it " don't sprinkle hints out of habit 5 preventing memory leaks a memory leak is when an object that is no longer needed can't be reclaimed because something still references it, and it is fatal in long-running tv apps the patterns that cause leaks in web apps are well known 5 1 unremoved event listeners the most common cause a listener registered with addeventlistener keeps holding the target object and the callback and everything its closure captures unless you explicitly remove it in particular, listeners on long-lived objects like window and document stay until the app ends // bad the listener remains after the component is removed, holding the whole object graph window addeventlistener 'resize', this onresize ; // good 1 always remove in a matching pair window removeeventlistener 'resize', this onresize ; // good 2 clean up all at once with abortcontroller const controller = new abortcontroller ; window addeventlistener 'resize', onresize, { signal controller signal } ; element addeventlistener 'keydown', onkey, { signal controller signal } ; // on cleanup controller abort ; // removes every listener registered with this controller at once rule listeners you register when creating a component/screen must all be removed when destroying it making abortcontroller + signal your standard pattern reduces mistakes 5 2 reduce listeners with delegation in a tv grid with hundreds to thousands of cards, attaching a click/keydown listener to each card keeps as many callback closures resident as there are listeners, plus register/unregister cost every time a card is created or discarded instead, attach a single listener to a parent container and use event bubbling with event target to determine which card fired it event delegation the listener count drops to one, cutting both memory and cleanup burden // bad a listener per card → n callback closures resident cards foreach card => card addeventlistener 'click', onclick ; // good delegate to a single container → 1 listener grid addeventlistener 'click', e => { const card = e target closest ' card' ; if !card return; handleselect card dataset id ; } ; it pairs especially well with virtualization 4 2 and element recycling 4 3 even when you swap card dom, the container's listener stays, so you don't have to re-register a listener each time cleanup is also just removing the one container listener, which reduces the listener-leak risk from 5 1 5 3 unremoved timers and callbacks if setinterval, settimeout, or requestanimationframe reference objects in their callbacks, those objects stay alive as long as the timer does in particular, setinterval and a recursive requestanimationframe run forever unless you explicitly stop them const timerid = setinterval update, 1000 ; // cleanup clearinterval timerid ; let rafid = requestanimationframe loop ; // cleanup cancelanimationframe rafid ; always stop animation loops and polling timers when the screen goes to the background or is destroyed you can detect visibility with the visibilitychange event 5 4 detached dom nodes a node removed from the dom but still referenced by a javascript variable is not gc'd this is called "detached dom" and is a classic type of web app leak // bad const cache = {}; const list = document getelementbyid 'list' ; cache oldlist = list; // keeps a reference list remove ; // removed from the dom // removed from the dom, but cache oldlist still holds it, so it isn't reclaimed including all child nodes // good cache oldlist = null; // cut the reference so it can be reclaimed 5 5 global caches/arrays that grow without bound logs, event records, response caches, and so on grow without limit if you keep piling them into global arrays/objects always cap the size e g , lru or clear periodically because map preserves insertion order, deleting and re-inserting an item on each access keeps the "least recently used" item at the front, giving you a simple lru // a simple bounded lru cache const max = 50; const cache = new map ; function get key { if !cache has key return undefined; const value = cache get key ; cache delete key ; // delete, then cache set key, value ; // re-insert → most-recently-used moves to the back return value; } function put key, value { if cache has key cache delete key ; // reset order on update else if cache size >= max { cache delete cache keys next value ; // evict the least-recently-used front } cache set key, value ; } 5 6 large objects held by closures a closure captures variables from its outer scope a single callback can keep a huge data structure alive reference only the values you actually need inside the callback 5 7 use weakmap / weakref when you want to attach extra info to an object without affecting its lifetime, use weakmap when the key object disappears, the related entry is reclaimed automatically const metadata = new weakmap ; metadata set domnode, { lastfocused 0 } ; // when domnode is gc'd, this entry disappears too 5 8 release memory aggressively when backgrounded as seen in section 1, when memory is low the tv kills background apps if your app holds a lot of memory while off-screen the user switched to another app/input , it becomes the first to be killed and reloads from scratch on return, hurting ux so the moment your app becomes invisible, give back memory you don't currently need release offscreen images / decoded bitmaps 3 2 return videos/decoders not currently playing 7 1 clear caches you can rebuild 5 5 stop animation loops / polling timers 5 3 detect show/hide with visibilitychange document hidden release resources the moment the app is hidden, and restore only what's needed when it becomes visible again document addeventlistener 'visibilitychange', => { if document hidden { releaseoffscreenimages ; // release image bitmaps pauseandreleasevideos ; // return videos not currently playing stopanimationloops ; // stop raf / timers trimcaches ; // clear caches you can rebuild } else { restoreonresume ; // on return, re-prepare only what's needed } } ; rule preserve lightweight state such as scroll position and focus, but drop heavy resources bitmaps, buffers, caches in the background and rebuild them on return 5 9 how to diagnose leaks in chrome devtools' memory panel, take two or more heap snapshots and compare them comparison to find objects that keep growing filter by "detached" to directly inspect detached dom nodes open and close the same screen several times, then compare snapshots; objects that keep accumulating even after closing indicate a leak 6 javascript memory and gc management 6 1 suppress memory churn memory churn means creating and discarding many temporary objects in a short time this makes gc run often, leading to animation frame drops and performance degradation watch these places especially inside animation loops requestanimationframe inside scroll handlers and input remote-control key handlers inside frequently running for loops // bad a new object/array every frame function onframe { const pos = { x computex , y computey }; // new object every frame → gc pressure moveto pos ; requestanimationframe onframe ; } // good reuse the object const pos = { x 0, y 0 }; function onframe { pos x = computex ; pos y = computey ; moveto pos ; requestanimationframe onframe ; } to maintain 60 fps, the budget per frame is about 16 ms to stay within it, minimize allocations during the frame 6 2 object pool — use with care returning reusable objects particles, card view-models, etc to a pool instead of discarding them can reduce allocation/gc but a pool has its own management cost, and an oversized pool actually increases resident memory and gc load apply it only where allocation is a real bottleneck hot paths , after measuring 6 3 choose efficient data structures choosing the right data structure for the job saves memory for large numeric data, use a typedarray int32array, float32array, uint8array, etc instead of a plain array [] it stores the values themselves densely in contiguous memory without creating a separate object per element, so the difference is large compared with, for example, an array of {x, y} objects for frequent key-value lookups, map is more suitable and clearer than an object {} ; for membership only, use set when handling large arrays, don't overuse unnecessary copies slice, spread [ arr], concat each copy allocates new memory // bad a million coordinates as an array of objects const points = []; for let i = 0; i < 1_000_000; i++ points push { x 0, y 0 } ; // good a single typedarray x, y interleaved const points = new float32array 1_000_000 * 2 ; 6 4 watch strings when concatenating string fragments many times, collecting them in an array and joining once with join is safer for memory and performance don't keep a huge response string in its original form for long extract only what you need, then cut the reference to the original so it can be reclaimed 6 5 cut references explicitly assign null to a large object you no longer need to cut the reference so gc can reclaim it especially when the variable's scope is wide or long-lived this bigdata = null; // release the large data note to empty a value, obj prop = null is generally better than delete obj prop delete can break the engine's internal object optimizations and hurt performance 6 6 your app code bundle takes memory too so far we've covered data created at runtime images, dom, objects , but your app's javascript/css code itself uses memory v8 parses loaded scripts and keeps them resident, so the bigger the bundle, the higher the baseline footprint from startup the less code you load, the less resident memory don't include unnecessarily large libraries instead of pulling in a heavy dependency whole for one or two features, use only the parts you need, or consider a lighter alternative or your own implementation also avoid including duplicate libraries that do the same thing minify + tree-shaking at build time to remove unused dead code code-split to load only per-screen code don't ship every route's code on the first screen; split with dynamic import import at entry time not loading unused screens' code into memory at all is best excessive abstraction layers increase code size the same principle as 4 5 removing unnecessary dom wrappers applies to code 7 video & media memory management the core of a tv app is mostly video playback media uses a lot of memory, so managing it matters 7 1 always release media resources that finished/left playback if you only remove a <video> element from the screen and leave it, the decoder and buffers may remain release it definitively in this order function releasevideo video { video pause ; video removeattribute 'src' ; // remove the src attribute // if you used <source> child elements, remove those too video load ; // prompt release of internal buffers/decoder // if you used mse, also clean up sourcebuffer/mediasource } don't keep multiple <video> elements alive at once when implementing preview autoplay etc , release a preview video the moment it leaves the screen a tv has a limited number of hardware video decoders, and each decoder uses large buffers reusing a single <video> element is safer than creating and discarding one per content item 7 2 mse media source extensions buffer management if you implement adaptive streaming yourself, remove the buffer for already-played ranges with sourcebuffer remove otherwise the buffer keeps growing and eats memory cap the forward buffer prefetching minutes ahead is convenient but uses a lot of memory be conservative with buffer size, especially at 4k / high bitrate 7 3 subtitle / thumbnail tracks don't keep thumbnail-preview scrub-preview sprites fully resident; load/release only the ranges you need reclaim used subtitle tracks and blob urls with url revokeobjecturl a blob url is not released unless you explicitly revoke it const url = url createobjecturl blob ; // after use url revokeobjecturl url ; 8 data handling optimization fetch / json / cache the amount and handling of data fetched over the network directly affect memory usage 8 1 fetch only as much as you need server-side filtering & paging don't fetch thousands of list items at once; split them via paging / infinite scroll don't receive large responses containing fields the client won't use design the api so the server filters down to only the needed fields e g , graphql field selection, a rest fields= parameter fetching, parsing, and storing large data itself leads to excessive memory use, which in turn degrades performance 8 2 understand the cost of json parse json parse str turns a string into an object tree, taking memory for the parsed objects on top of the original string the larger the json, the more this double occupancy hurts don't keep holding the original string reference after parsing cut it to allow reclamation for very large datasets, consider streaming parsing or partial parsing avoid the pattern of parsing everything and holding it all 8 3 don't hold parse results whole for long rather than keeping the entire list api response in memory, transform it into the shape the screen needs a view-model and then discard the original response in infinite scroll, cap and clean up data for pages already passed far from the screen data, like the dom, is a target for "windowing " 8 4 efficient data formats for large, repetitive data, use a compact representation rather than a verbose format json is usually the standard on the web, but consider the following avoid unnecessarily nested or verbose json structures; keep key names and structure compact don't stuff binary data into json as base64 about 33% bloat ; receive it as a separate binary response or an arraybuffer if very large structured data is sent repeatedly, consider binary serialization e g , protobuf, cbor 8 5 cap your caches cap response caches, image caches, and computed-result caches with an lru limit so they don't grow without bound see 5 5 don't put large data in localstorage/sessionstorage; they have size limits and are synchronous apis bad for performance if you truly need large data, use indexeddb — and still manage a cap 9 canvas / webgl / web audio / worker cautions more powerful web apis can use a lot of memory and often hold resources gc won't reclaim automatically the following applies only if you use these apis directly — skip it if you don't 9 1 canvas 2d canvas back-buffer memory = width × height × 4 bytes don't create many large canvases for an unused canvas, shrink its size to width = height = 0 to reclaim the back buffer, and cut the reference creating a large array every frame with getimagedata/putimagedata causes memory churn reuse buffers 9 2 webgl webgl resources textures, buffers, programs, framebuffers are not reclaimed by gc automatically delete them explicitly deletetexture, deletebuffer, deleteprogram, deleteframebuffer when you no longer need the context, release it with getextension 'webgl_lose_context' losecontext textures use large gpu memory by the same principle as image bitmaps control texture size and count 9 3 web audio close an audiocontext with close after use don't leave many open a decoded audiobuffer can be large; cut the reference when done 9 4 web worker a worker has its own memory space terminate a finished worker with terminate ; leaving it keeps occupying memory passing large data to a worker copies it structured clone , creating two copies use a transferable e g , transferring ownership of an arraybuffer to avoid the copy worker postmessage buffer, [buffer] ; // transfer ownership of buffer → no copy 9 5 iframe each iframe loads its own document and resources, using a lot of memory create ad / external-widget iframes only when needed, and remove them from the dom to destroy them completely when done in closing tv web app memory optimization boils down to three principles create only as much as you show — images at display size, lists only as far as visible, data only as much as needed release the moment it's no longer needed — clean up listeners, timers, observers, media, dom, and caches along their lifecycle measure and verify on a real device — confirm memory doesn't trend upward across repeated open/close and long runs apply these three principles from the design stage, and you'll deliver a smooth, stable app experience to users ↑ back to top
Develop Smart TV
docweb app html5 flash storage optimization guide terminology here, "flash" means the device's flash memory storage where the app is installed and stored it has nothing to do with adobe flash nature of this document this is a best-practice guide it is not intended to mandate compliance or to trigger any action based on compliance — use it as a reference for better app quality and user experience contents why storage size optimization matters what takes up space minimize bundle code size with build options image & graphics asset optimization fonts & other assets what not to bundle managing storage that accumulates after install 1 why storage size optimization matters a tv's flash storage is limited and shared by the system and many apps a large app package causes the following problems installs/updates are slower and more likely to fail the larger the size, the longer the download/write, and installs/updates can fail when storage is tight it pressures storage when one app takes a lot of space, there's less room for other apps to install and less system cache space, degrading the whole device's usability it leads to loading cost larger code/assets increase parse/decode load, lengthening startup and affecting ram usage too the problem doesn't end at install time the cache/stored data the app creates while running occupies the same flash even if you make the package small, occupied space keeps growing if you don't manage this conversely, keeping the app small makes installs/updates fast, reduces download traffic, frees storage, and improves startup performance core principle ① don't ship what you don't need · ② ship what you do need in its smallest form · ③ manage what accumulates after install · ④ automate this in your build pipeline if you rely on doing it by hand every time, something will always slip through this document is a companion to the memory optimization guide, which covers ram runtime memory making assets smaller reduces not only storage but also the runtime memory spent on decoding/parsing 2 what takes up space first, understand what dominates your app package's size usually the order of magnitude is as follows asset description main way to reduce images backgrounds, posters, icons, sprites resize · lightweight formats · compression section 4 javascript/css bundle app code + libraries minify · tree-shaking · dependency diet section 3 fonts web fonts especially cjk subset · woff2 section 5 local media intro videos, sound effects, etc minimize · compress · switch to streaming section 5 other data json and static files bundled in minimize · move to runtime fetch section 5 files that tag along source maps, tests/mocks, original images, unused assets exclude from packaging section 6 measure first use a bundle analyzer to see with your own eyes which modules/assets take up space before you touch anything bundle analysis webpack-bundle-analyzer, rollup-plugin-visualizer, source-map-explorer file assets sort your build output dist directory by file size and review the biggest first final package record the package size for each release to keep a trend this value directly determines the space it takes on the device often a handful of large items account for most of the size before polishing many small ones, it's more efficient to handle the largest assets first 3 minimize bundle code size with build options the javascript/css you load takes storage by itself most popular bundlers/frameworks provide size optimization by default in their production build, so simply turning the options on correctly yields a big win option names and defaults change between tool versions the config examples below are meant to convey the gist when applying them for real, check the current version's options in the official docs linked at the end of each subsection 3 1 common principles regardless of framework always ship a production build development builds include warnings, debug code, and source maps, which are large minify js with terser/esbuild, css with cssnano/esbuild — strip whitespace/comments and shorten identifiers tree-shaking remove unused code works well only with es modules import/export choose libraries that support tree-shaking esm, sideeffects false remove unused css use purgecss, or the purge/content settings of frameworks like tailwind, to drop classes you don't use exclude source maps from the package source map files are very large don't include them in the shipped package; store them separately if needed dependency diet don't pull in a heavy library whole for one or two features; use only the parts you need, or consider a lighter alternative or your own implementation also remove duplicate dependencies that do the same thing don't let multiple versions of the same library get bundled together as the dependency tree deepens, it's common for two or three different versions of the same library to be included check for duplicate versions with npm ls <package>, and unify versions dedupe, overrides/resolutions so only one copy remains verify with a bundle analyzer don't inline images as base64 base64 is about 33% larger than the raw bytes, and when mixed into a js/css bundle it also lives in runtime memory as a string set the bundler's inline threshold small or 0 and keep images as separate files webpack rule parser dataurlcondition maxsize, vite build assetsinlinelimit avoid excessive transpilation/polyfills lowering syntax the target platform already supports down-leveling needlessly grows the code set your build target to the target environment set a size budget and enforce it in the build define a baseline for total output size so the build warns/fails when exceeded — this structurally blocks size regressions size-limit, bundlesize; angular has built-in budgets — see 3 6 know precisely — the scope of code splitting splitting code per screen with dynamic import benefits initial load time and runtime memory, but does not reduce the total amount of code bundled into the package what reduces storage total size is tree-shaking, minify, removing dependencies, and removing unused css apply the two separately 3 2 webpack mode 'production' auto-enables terser minification, tree-shaking, scope hoisting optimization usedexports, optimization minimize true css css-minimizer-webpack-plugin analysis webpack-bundle-analyzer // webpack config js essentials module exports = { mode 'production', // apply production optimizations at once devtool false, // keep source maps out of the package optimization { usedexports true, // tree-shaking minimize true, // terser minification splitchunks { chunks 'all' }, // split common modules dedupe }, module { rules [ { test /\ png|jpe?g|webp|svg $/i, type 'asset/resource', // output as separate files, no base64 inlining }, ], }, }; official docs production · tree shaking 3 3 vite / rollup a vite production build vite build performs minify + tree-shaking by default build sourcemap false to exclude source maps build minify esbuild by default, or terser , build rollupoptions output manualchunks to shape chunks analysis rollup-plugin-visualizer // vite config js essentials export default { build { minify 'esbuild', // fast, strong minification sourcemap false, // exclude source maps from the package cssminify true, assetsinlinelimit 0, // disable base64 image inlining rollupoptions { output { manualchunks { vendor ['large-shared-library'] } }, }, }, }; official docs vite — building for production · rollup — configuration options 3 4 react always ship a production build node_env=production — development builds include warnings and validation code and are large keep dev-only tools tests, mocks, debug panels out of the production bundle if the runtime weight is a burden, consider an interface-compatible lightweight alternative e g , the preact family use react lazy + suspense for per-screen splitting benefits initial load/memory — see the note in 3 1 for the total-size perspective official docs build a react app from scratch 3 5 vue the production build removes development warnings and hints sfcs vue and <script setup> reduce unnecessary code at compile time reduce unused global component/plugin registrations, and import in a tree-shakable form official docs production deployment 3 6 angular build with the production configuration aot compilation and the build optimizer are enabled by default set bundle budgets so the build warns/fails when size exceeds a threshold, preventing size regressions // angular json essentials — cap bundle size "budgets" [ { "type" "initial", "maximumwarning" "500kb", "maximumerror" "1mb" } ] official docs building angular apps includes size budget configuration 4 image & graphics asset optimization images usually account for the largest share of an app package the key is to not create images you don't need, keep only one copy of what you do need, size it to the minimum needed for display, use the most efficient format, and compress it as much as possible the impact shrinks toward the bottom, so apply these from the top down 4 1 first, check whether it needs to be an image at all the smallest image is no image the following need no file at all if drawn with css or code solid/gradient backgrounds → background-color, linear-gradient rounded corners/borders/shadows → border-radius, border, box-shadow dividers/dotted lines → border, outline repeating patterns → repeating-linear-gradient simple shapes circles, triangles, badge backgrounds, ribbons → css or inline svg gauges/progress bars/simple charts → draw with css or canvas /* css instead of an image gradient background + rounded corners + shadow */ poster-overlay { background linear-gradient to top, rgba 0, 0, 0, 8 , transparent ; border-radius 8px; box-shadow 0 4px 12px rgba 0, 0, 0, 4 ; } it's common to turn a design mockup into a file just because it arrived as an image go through your asset list and ask "can this be done with css?" for each one not only does size drop, but color/size changes become easier too 4 2 keep one copy of an asset and handle variants with code keeping color/direction/state variants of the same graphic as separate files multiplies the asset count handle variants with css color variants → keep svg with fill="currentcolor" and control via css color for raster icons, use mask-image + background-color, or filter direction variants → don't keep left/right arrows as two files; use transform scalex -1 , and rotate 180deg for up/down rtl layout support works the same way state variants normal / focus / selected → instead of a per-state image set, change only color/size/opacity with css size variants → a single svg covers all sizes /* handle color/direction variants with one icon copy */ icon { color #999; } /* svg uses fill="currentcolor" */ icon focus, icon is-selected { color #fff; } icon--flip { transform scalex -1 ; } /* reuse the left arrow as a right arrow */ turning 24 icons into files across 3 colors × 2 directions yields 144 files reusing the same asset keeps it at 24 4 3 resize to display size don't bundle a 4k original for an image shown at 200×300 bundling a file pre-resized to the display size greatly reduces size if you need different assets per resolution fhd/4k , prepare only the sizes you actually use 4 4 prefer lightweight formats photos / complex images → webp recommended smaller than jpeg/png at equal quality it's widely supported by tv web engines, making it the safest choice even smaller alternative → avif higher compression, but it may not be supported depending on the web engine version always verify support on your target platform's chromium version, and use webp if you're unsure logos / icons / simple shapes → svg being vector, they're small and crisp regardless of resolution bundle multiple icons as an svg sprite animation → avoid gif animated gifs are large and use a lot of decode memory use css animations for simple ui motion loading spinners, emphasis effects , and animated webp when raster animation is truly required if you don't need transparency, use a format without an alpha channel jpeg/lossy webp 4 5 squeeze further with lossless/lossy compression tools even after choosing a format, re-compressing with a dedicated tool can reduce size further with no or minimal quality loss png lossless zopflipng powerful but slow , oxipng/optipng if the color count is low, pngquant palette-based lossy saves a lot jpeg mozjpeg cjpeg , jpegtran lossless re-compression webp cwebp lossy via -q, lossless via -lossless svg svgo remove metadata, redundant decimals, comments general strip unnecessary metadata such as exif # lossless png optimization zopflipng zopflipng -m in png out png # for pngs with few colors, palette lossy compression is far more effective pngquant --quality=65-85 --output out png in png # jpeg → webp photos lossy, quality 75-85 recommended cwebp -q 80 photo jpg -o photo webp # logo / transparent png → lossless webp cwebp -lossless logo png -o logo webp # svg optimization svgo icon svg -o icon min svg lossy vs lossless for photos, lossy compression webp/jpeg around quality 75-85 gives the best quality-per-byte use lossless or a palette pngquant for logos, transparent images, and ui elements that must stay crisp always check quality by eye after compression and adjust the quality value 4 6 automate it in the build pipeline image optimization is easy to forget if done by hand each time handle it automatically at build time general purpose the imagemin family of plugins imagemin-webp, imagemin-pngquant, imagemin-zopfli, imagemin-mozjpeg, imagemin-svgo node pipeline sharp fast resize + format conversion bundler plugins vite/webpack image-optimization plugins that convert/compress automatically at build time // example automate resize + webp conversion with sharp build script import sharp from 'sharp'; await sharp 'poster_original jpg' resize 400, 600 // resize to display size webp { quality 80 } // lightweight format + lossy compression tofile 'poster_400x600 webp' ; keep the originals separately optimization resize/lossy compression is irreversible, so keep the source originals in your repository/asset store and bundle the optimized versions only into the build output 5 fonts & other assets 5 1 fonts bundle only the weights/styles you truly need limit to regular/bold and exclude unused light, thin, italic use subset fonts that contain only the characters you actually use this is especially effective for cjk chinese/japanese/korean , where a full-glyph font can reach several mb use woff2 — the best-compressed font format if the platform's built-in fonts are enough, not bundling a web font at all is the surest saving 5 2 local media minimize the count and length of media intro videos, sound effects bundled into the package, and compress with an appropriate codec/bitrate where possible, don't bundle it locally — stream/download it at runtime to keep it out of the package size but you must also have a cleanup policy so fetched files don't keep piling up on the device section 7 5 3 other data minimize large json/static data bundled in, and if it isn't needed on the first screen, move it out of the package via a runtime fetch here too, cap the response cache so it doesn't grow without bound section 7 6 what not to bundle what you didn't ship needs no optimization no matter how much you shrink things with compression/resizing, nothing is a surer saving than leaving out features and files you don't need in the first place 6 1 re-examine the features and assets themselves the question that should come before technical optimization is "is this really needed?" as releases pile up, unused things accumulate low-usage features — if you have usage metrics, check them and remove or defer to the next release screens/features that are barely used dropping one feature often has more impact than compressing dozens of assets large decorative assets — intro videos, splash animations, full-screen background illustrations if it's a flourish users skip every time, it's not worth paying for in size frame-image animations — especially expensive first consider whether a css animation can give the same impression 4 1 experiment/event leftovers — a/b test variants, seasonal event assets, and pilot features are often left behind after they end this judgment is hard for a developer to make alone it's more effective to have a step that reviews "what can be dropped this time" together with planning/design before release 6 2 things that commonly tag along files that got in by accident often take more space than the assets you added on purpose removing such files has no effect on app behavior, so it's the lowest-risk, surest saving development source tree node_modules/, git/, build caches, dev config files source maps map files and the //# sourcemappingurl comments that point to them test/dev tools test files and snapshots, storybook, mock apis/sample data, debug panels design originals psd/ai/sketch files, un-optimized high-resolution original images — keep originals in the repository and bundle only the optimized versions documents readme, changelogs, bundles of dependency license text in the minimum form required if you have a notice obligation unused assets images, icons, fonts, and json no longer referenced after a ui refresh or plan change duplicate assets the same image included several times under different names comparing file hashes finds these easily unused locales translation files/region-specific assets for unsupported languages if you support many languages, consider loading only the selected language at runtime 6 3 use an "include list," not an "exclude list" listing what to exclude misses things every time a new file appears structure it as explicitly specifying only what to bundle configure the build so the output directory dist contains only the files needed to run, and package that directory as-is add a step just before packaging that prints the file list and sizes for a visual check unexpected files are usually caught at this step # show the 20 largest files in the output pre-release check find dist -type f -printf '%s\t%p\n' | sort -rn | head -20 # find duplicate files same content hash find dist -type f -exec md5sum {} + | sort | uniq -w32 -d put this check into your release script, and record the total output size alongside it — combined with the size budget from 3 1, it prevents size regressions 7 managing storage that accumulates after install storage isn't fixed at install time the cache/data the app creates as it runs occupies the same flash, and without a cap it keeps growing it's not rare for an app with a small install size to occupy several times that a few months later 7 1 what accumulates store what accumulates management point cache api / service worker image/js/api-response caches version the cache name; delete old-version caches indexeddb content lists, thumbnails, watch history cap item count/total; clean up old items localstorage settings, tokens, small state values don't put large data/images in it http cache network responses control lifetime via cache headers app data area downloaded media/thumbnails cap total downloads; provide a user delete option 7 2 how to do it set caps set limits on both count and total — e g , "thumbnail cache max 200 items / 20mb" — and when exceeded, evict the least recently used first lru set lifetimes give re-fetchable data content metadata, etc a ttl and delete it on expiry data kept "just in case it's needed" is the main cause of accumulation delete old-version caches on app update put a version in the cache name and remove the previous cache once the new version activates skip this cleanup and one copy of the cache piles up with every update check usage yourself read current usage with navigator storage estimate and clean up on your own when a threshold is crossed check support on your target web engine give users a way to delete offering "clear cache" in the settings screen lets users short on storage resolve it without uninstalling the app // remove old-version caches on app update service worker const cache_name = 'app-v12'; // bump the version each release self addeventlistener 'activate', event => { event waituntil caches keys then names => promise all names filter name => name !== cache_name map name => caches delete name // delete previous-version caches ; } ; // check usage and clean up on your own async function checkstorage { if !navigator storage? estimate return; const { usage } = await navigator storage estimate ; if usage > 30 * 1024 * 1024 { // e g over 30mb await trimthumbnailcache ; // delete least recently used items first } } if what you removed from the package just piles up in the cache instead, the saving disappears the strategy of moving large json/media to a runtime fetch 5 2, 5 3 leads to real storage savings only when a cap and cleanup policy are in place too in closing storage flash optimization comes down to four points don't ship what you don't need — start by clearing out unneeded features/decorative assets, remove unused code/css/dependencies/font weights, exclude dev files that tag along, and move large data/media to runtime ship what you do need in its smallest form — don't make an image out of what css can draw, handle variants of the same asset with code, and use production builds minify/tree-shaking , image resize/lightweight formats/compression, and font subsetting/woff2 manage what accumulates after install — put caps and lifetimes on cache/stored data, and clean up old-version caches on app update automate in the build pipeline and measure — bake image optimization and bundle minimization into the build, and keep watching the bundle analyzer and final package size to prevent size regressions a small app installs and updates fast, saves storage, and even starts faster ↑ back to top
We use cookies to improve your experience on our website and to show you relevant advertising. Manage you settings for our cookies below.
These cookies are essential as they enable you to move around the website. This category cannot be disabled.
These cookies collect information about how you use our website. for example which pages you visit most often. All information these cookies collect is used to improve how the website works.
These cookies allow our website to remember choices you make (such as your user name, language or the region your are in) and tailor the website to provide enhanced features and content for you.
You have successfully updated your cookie preferences.