<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Larry Zhu</title>
    <description>The latest articles on DEV Community by Larry Zhu (@larryzhu_china).</description>
    <link>https://dev.to/larryzhu_china</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1092960%2Fd6fd3fc7-12e6-4636-887c-7510b1306450.jpg</url>
      <title>DEV Community: Larry Zhu</title>
      <link>https://dev.to/larryzhu_china</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/larryzhu_china"/>
    <language>en</language>
    <item>
      <title>Frek, a new toy for free PR, come and contribute your creativity!</title>
      <dc:creator>Larry Zhu</dc:creator>
      <pubDate>Tue, 19 Mar 2024 05:36:28 +0000</pubDate>
      <link>https://dev.to/larryzhu_china/frek-a-new-toy-for-free-pr-come-and-contribute-your-creativity-809</link>
      <guid>https://dev.to/larryzhu_china/frek-a-new-toy-for-free-pr-come-and-contribute-your-creativity-809</guid>
      <description>&lt;p&gt;github: &lt;a href="https://github.com/LarryZhu-dev/frek"&gt;https://github.com/LarryZhu-dev/frek&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I created this warehouse yesterday and announced it to my friends. Soon, it received two forks. Today at noon, I received the first PR, which, although not very good, increased the chance of deleting half of the JS files outside of the C drive by 50%.&lt;br&gt;
I immediately updated the readme file to warn latecomers not to run this project easily.&lt;/p&gt;

&lt;p&gt;Anyone can submit any code to this repository, and any PR that can run normally will be merged. At present, it has just obtained two latest forks and has a chance to seize the sofa! You can design a logo for Frek and put it in readme (yes, any file can be modified!)&lt;/p&gt;

&lt;p&gt;Welcome developers from the dev forum to submit your ideas!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to deal with a smelly Qing Dynasty project? Refactor it with TypeScript!</title>
      <dc:creator>Larry Zhu</dc:creator>
      <pubDate>Fri, 04 Aug 2023 08:37:01 +0000</pubDate>
      <link>https://dev.to/larryzhu_china/how-to-deal-with-a-smelly-qing-dynasty-project-refactor-it-with-typescript-gkk</link>
      <guid>https://dev.to/larryzhu_china/how-to-deal-with-a-smelly-qing-dynasty-project-refactor-it-with-typescript-gkk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Multiple Image Warning: Enter with caution if you have limited data.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Background
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;Recently, the company asked us to add new features to an old project, specifically converting the previously free services into paid ones, and adding some additional functionalities. When I saw the project online, I had a bad feeling. Let's take a look at some screenshots:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ilXPL5RM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041324832.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ilXPL5RM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041324832.png" alt="Farm Digital Cloud Page" width="800" height="386"&gt;&lt;/a&gt;&lt;br&gt;
Farm Digital Cloud Page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UkePbkiA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041326636.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UkePbkiA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041326636.png" alt="Alarm Platform Page" width="800" height="383"&gt;&lt;/a&gt;&lt;br&gt;
Alarm Platform Page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XqvOGaGM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041325341.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XqvOGaGM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041325341.png" alt="Weather Monitoring Page" width="800" height="387"&gt;&lt;/a&gt;&lt;br&gt;
Weather Monitoring Page (NavBar disappeared, oh my 😅)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VtrGIdQA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041327367.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VtrGIdQA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041327367.png" alt="Meteorological Big Data Page" width="800" height="386"&gt;&lt;/a&gt;&lt;br&gt;
Meteorological Big Data Page (Another new project without NavBar)&lt;/p&gt;

&lt;p&gt;Not to mention the errors and overwhelming log messages. The code structure and directory organization are also extremely chaotic. It seems like a mishmash of components and views, making it challenging to differentiate between them. Have any of you encountered such an epic mess of directories?&lt;/p&gt;

&lt;p&gt;After being shocked by the directory structure, I prepared myself to look at the code. To my surprise, the Vue components are relatively well-written:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gVglLYXe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041341814.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gVglLYXe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041341814.png" alt="Vue Component" width="660" height="774"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(That pagination function was added later.) Well, it's acceptable, and the naming is quite standard. I can read through this in about ten minutes. Let's continue with another component:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CJhMYcWy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041344666.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CJhMYcWy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041344666.png" alt="Another Vue Component" width="629" height="787"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, this one is also decent, and along with the template, it's understandable. Let's see another one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZehX4lHz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041348567.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZehX4lHz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041348567.png" alt="One More Vue Component" width="694" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait? It's acceptable to have two functions that look similar, but shouldn't their functionality be similar too? The &lt;code&gt;addControl2&lt;/code&gt; and &lt;code&gt;addControl&lt;/code&gt; functions are completely different! While both may qualify as controls, their actual functionalities are not the same at all!&lt;/p&gt;

&lt;p&gt;Overall, the Vue components are acceptable, but maintaining a project like this would be extremely tiring (the screenshots are not an exception; every file has similar issues). After working on the changes for a week, I proposed a refactor, and to my surprise, the leadership approved it immediately and handed the task to me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Chosen Tech Stack
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since the old project suffered from variable and global variable pollution, improper route passing, and excessive usage of mixins, I decided to use TypeScript and Pinia for type and state management.&lt;/p&gt;

&lt;p&gt;The old project (Webpack) took about 20 seconds for cold starts or builds, with hot updates at 1-2 seconds, which is acceptable. As the website continuously used Alibaba Cloud's online deployment, I didn't specifically check the bundle size, but it's likely in the tens of MBs. Although these issues are not significant, optimizing static files and removing unused code is always beneficial. Nonetheless, I chose to use Vite for its speed.&lt;/p&gt;

&lt;p&gt;To address the variable pollution issue caused by mixins, Vuex, and Vue Router, I selected Vue 3, as it naturally discourages the use of mixins. The Composition API makes it easy to achieve all functionalities previously done using mixins in a more organized manner.&lt;/p&gt;

&lt;p&gt;For the new project, I simplified the routing and opted for a single route since the Alarm Platform was removed, and the core functionalities of the other two pages were merged into the Farm Digital Cloud. Therefore, the new version of the Farm Digital Cloud only requires one route to accommodate all functionalities. Additionally, I used the &lt;code&gt;pinia-plugin-persistedstate&lt;/code&gt; plugin to persist data globally with Pinia. I must clarify that many people are concerned about storing too much data locally, especially with full persistence like I did. However, when possible, storing some frequently used data or state information locally using &lt;code&gt;localStorage&lt;/code&gt; is the most efficient and performant way.&lt;/p&gt;

&lt;p&gt;The final tech stack includes: Vue 3 + Pinia + Vue Router + TypeScript.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Let's Get Started
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;As the project was already existing, most of the APIs were in place. We quickly sorted out the new requirements, and the backend team worked alongside me, resulting in a rapid development process. By the end of the first week, we had completed 99% of the entire project.&lt;/p&gt;

&lt;p&gt;Since there were no new design specifications for the refactored system, I had to rely on the rough style of the old project as a reference (as the logic and architecture were completely different, most parts had to be re-done). Finally, we created a cleaner and more refreshing front-end layout:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SgRu9JC_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041432536.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SgRu9JC_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041432536.png" alt="New Farm Digital Cloud Page" width="800" height="385"&gt;&lt;/a&gt;&lt;br&gt;
New Farm Digital Cloud Page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yD7oIXqX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041433733.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yD7oIXqX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041433733.png" alt="New Alarm Platform Page" width="800" height="486"&gt;&lt;/a&gt;&lt;br&gt;
New Alarm Platform Page&lt;/p&gt;

&lt;p&gt;The login page was also transformed into a lightweight popup for almost all functionalities.&lt;/p&gt;

&lt;p&gt;Here's how the complete project looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mx7xr22r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041435286.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mx7xr22r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041435286.png" alt="Complete Project" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comparing it to the old version:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OynIB2nW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041436730.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OynIB2nW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://glnf123456.obs.cidc-rp-13.joint.cmecloud.cn/fileUpload/202308041436730.png" alt="Old Version" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Refactor and Optimization
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Page Changes
&lt;/h4&gt;

&lt;p&gt;Clearly visible changes include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The addition of administrative area-level plots.&lt;/li&gt;
&lt;li&gt;No more categorization of sowing, unsown, and sample plots; instead, tags are used as badges.&lt;/li&gt;
&lt;li&gt;The removal of individual service item displays for each plot; now, the same area is shown when a plot is selected.&lt;/li&gt;
&lt;li&gt;The elimination of redundant charts, legends, map controls, and farming records.&lt;/li&gt;
&lt;li&gt;Disaster information is now part of the service items and not listed separately.&lt;/li&gt;
&lt;li&gt;The timeline is introduced as a replacement for the previous carousel.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Code Changes
&lt;/h4&gt;

&lt;p&gt;Less noticeable changes include:&lt;/p&gt;

&lt;h5&gt;
  
  
  Removal of all production environment logs
&lt;/h5&gt;

&lt;p&gt;The console is now clean without any logs in the production environment. All logs have been removed, and with TypeScript, runtime errors are minimal. We used &lt;code&gt;autofit.js&lt;/code&gt; for easy adaptation to any resolution of the design layout (invincible).&lt;/p&gt;

&lt;h5&gt;
  
  
  Removal of all third-party major UI component libraries
&lt;/h5&gt;

&lt;p&gt;We did not use any major UI component libraries (we don't care if you tree-shake or not). This resulted in an extremely compact project, with the bundle size being only 1MB+.&lt;/p&gt;

&lt;h5&gt;
  
  
  Clear code structure
&lt;/h5&gt;

&lt;p&gt;The code structure is clear. Though the content is relatively small right now, it's still evident that the structure is&lt;/p&gt;

&lt;p&gt;quite organized. We mostly followed the default structure created by Vite, and there are hardly any static files, which contributes to reducing the bundle size.&lt;/p&gt;

&lt;h5&gt;
  
  
  Global state persistence using Pinia
&lt;/h5&gt;

&lt;p&gt;Since we used Pinia for global state management throughout the project, we no longer had to worry about when to get or set data. Using stores, we can access and modify data at any time, significantly improving our development experience.&lt;/p&gt;

&lt;h5&gt;
  
  
  API Categorization and Encapsulation
&lt;/h5&gt;

&lt;p&gt;APIs were categorized and encapsulated, making it clear which vendor's API we are calling. TypeScript ensured that we don't miss or pass incorrect parameters.&lt;/p&gt;

&lt;h5&gt;
  
  
  Simplified interceptors
&lt;/h5&gt;

&lt;p&gt;We used minimal interceptors, as they are essentially error handlers that ensure the subsequent process does not crash. Therefore, we only implemented the simplest interceptors, which are very useful.&lt;/p&gt;

&lt;h5&gt;
  
  
  Simplified routing and component usage
&lt;/h5&gt;

&lt;p&gt;As it turned out, we didn't need to use routing transitions. All internal functionalities were presented as lightweight popups. The only redirect was to the payment page, which was part of another project. Our solution was to directly pass the user token to the payment page, straightforward and efficient.&lt;/p&gt;

&lt;h5&gt;
  
  
  MQTT-inspired Publish-Subscribe Paradigm
&lt;/h5&gt;

&lt;p&gt;We chose to fully rely on Vue 3's &lt;code&gt;watch&lt;/code&gt; function. Though it may seem challenging to read at first, it is actually modeled after the publish-subscribe mechanism of MQTT, where &lt;code&gt;watch&lt;/code&gt; acts as a subscribe function and &lt;code&gt;store.xxx&lt;/code&gt; as a topic. This approach makes the code easy to understand, and it's satisfying to use. If you need to subscribe to a data change and perform some actions, just use &lt;code&gt;watch&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Clearing redundant code
&lt;/h5&gt;

&lt;p&gt;There's no redundant code, none! Function and variable naming are clear and consistent. The primary focus is on clarity. Look at this piece of code; does it need any comments?&lt;/p&gt;

&lt;h5&gt;
  
  
  Coding conventions
&lt;/h5&gt;

&lt;p&gt;Consistent conventions, I cannot stress enough how important they are. This is a debounce function, it's well-written because I followed the convention!&lt;/p&gt;

&lt;h5&gt;
  
  
  Type definition using TypeScript
&lt;/h5&gt;

&lt;p&gt;Explicit types - defining types may take an extra five minutes, but it saves an hour during coding.&lt;/p&gt;

&lt;h5&gt;
  
  
  Development of lightweight essential components
&lt;/h5&gt;

&lt;p&gt;Custom components like selectors and toasts are developed to be lightweight. Only what's necessary is included; it's all about being lightweight.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Online Address
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;As the project is a live commercial project, I can provide the URL for you to check out and use:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://farm.sino-eco.com/website/sino_cloud/"&gt;https://farm.sino-eco.com/website/sino_cloud/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  All Done
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even though we made additional changes and new requirements after completing 99% in the first week, they were easily managed due to standardized development practices. Coding became enjoyable, and for such a lightweight project, we used a lightweight approach. There's no need to cut a sesame and lose a watermelon, being top-heavy and bottom-heavy, abandoning the core for peripherals, or going in the wrong direction. A frontend project only needs to ensure smooth rendering, no errors, and no crashes. Avoid overcomplicating things; just keep it simple and clean.&lt;/p&gt;

&lt;p&gt;About this refactoring experience, it was not only a technical learning process but also a conceptual advancement. Often, a frontend project only needs to ensure smooth rendering, no errors, and no crashes. Avoid overcomplicating things; just keep it simple and clean.&lt;/p&gt;

&lt;p&gt;I am Larry, let's keep striving together!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I’ve got it done. New tool Autofit.js makes web pages responsive and adaptive with just one line of code.</title>
      <dc:creator>Larry Zhu</dc:creator>
      <pubDate>Thu, 01 Jun 2023 02:15:35 +0000</pubDate>
      <link>https://dev.to/larryzhu_china/i-bring-a-front-end-adaptation-tool-from-china-2kk4</link>
      <guid>https://dev.to/larryzhu_china/i-bring-a-front-end-adaptation-tool-from-china-2kk4</guid>
      <description>&lt;p&gt;Hello everyone，you definitely don't know me,my name is Larry，A front-end engineer from China。&lt;/p&gt;

&lt;p&gt;Recently, I made an adaptive plugin that only has a 3kb size JavaScript file, but it can adapt to any resolution below the design draft. Let's take a look at how it is implemented。&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do I need to make it
&lt;/h3&gt;

&lt;p&gt;The adaptation of large visual screens is a clich é d topic, and now there are actually some big bang open-source adaptive plugins and tools. But why do I have to repeatedly build wheels? Because currently none of the adaptation tools on the market can achieve perfect results and produce similar products, the final implementation effect cannot escape the palm of the white edge. The solutions to the white edge problem are either too complex or will affect the dom structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three common methods
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Vw/vh scheme&lt;/strong&gt;&lt;br&gt;
Overview: Convert px proportionally to vw and vh based on the size of the design draft&lt;br&gt;
Advantages: It can dynamically calculate the width, height, font, etc. of charts, with high flexibility. When the screen ratio is inconsistent with the UI draft, there will be no white space on both sides&lt;br&gt;
Disadvantage: Each chart requires separate adaptation of font, spacing, and displacement, which is quite troublesome&lt;br&gt;
&lt;strong&gt;Scale scheme&lt;/strong&gt;&lt;br&gt;
Overview: It is also the most effective solution currently available&lt;br&gt;
Advantages: Low code size, simple adaptation, and no need to adapt separately in various charts after a single processing&lt;br&gt;
Disadvantage: Left blank, there is an event hot zone offset&lt;br&gt;
&lt;strong&gt;Rem+vw vh scheme&lt;/strong&gt;&lt;br&gt;
Overview: This name can be troublesome to hear. The specific method is to obtain the reference value of rem, dynamically calculate the font size of the HTML root element, and dynamically calculate font, spacing, displacement, etc. in the chart through vw and vh&lt;br&gt;
Advantages: Less adaptive code for layout and simple adaptation&lt;br&gt;
Disadvantage: Left blank, sometimes charts need to be individually adapted to the font&lt;/p&gt;

&lt;p&gt;Based on this background, I have decided to build a simple and user-friendly wheel.&lt;/p&gt;
&lt;h3&gt;
  
  
  My train of thought
&lt;/h3&gt;

&lt;p&gt;We know that when a website is displayed on a low resolution screen, some elements will be squeezed together, and using the scale scheme to scale proportionally will leave some blank space on the right or bottom (due to screen scale issues). If this blank space problem is solved, the scale scheme will be the best solution&lt;/p&gt;

&lt;p&gt;So, all we need to do is expand the size of the total container to match the browser. For example, if a white edge appears on the right side of the screen after scaling proportionally, we just need to add a little bit of the total container width and fill in the width of this white edge. The same applies when a white edge appears below&lt;/p&gt;

&lt;p&gt;So there is the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function keepFit(designWidth, designHeight, renderDom) {
  let clientHeight = document.documentElement.clientHeight;
  let clientWidth = document.documentElement.clientWidth;
  let scale = 1;
  if (clientWidth / clientHeight &amp;lt; designWidth / designHeight) {
    scale = (clientWidth / designWidth)
    document.querySelector(renderDom).style.height = `${clientHeight / scale}px`;
  } else {
    scale = (clientHeight / designHeight)
    document.querySelector(renderDom).style.width = `${clientWidth / scale}px`;
  }
  document.querySelector(renderDom).style.transform = `scale(${scale})`;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the renderDom element was mounted on the page, we called this method and found that the page was perfectly adapted. Based on this principle, we can apply this code to any front-end project, whether you are using React, Vue, or even jQuery&lt;/p&gt;

&lt;p&gt;Of course, I have packaged a plugin that not only has the most basic functions, but also helps you set the necessary styles. When you need to use it, you can directly install and use it&lt;/p&gt;

&lt;h3&gt;
  
  
  autofit. js was born
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmnmtlocl55w9bp73zq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmnmtlocl55w9bp73zq9.png" alt="autofit.js logo" width="300" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image is a logo that I have carefully designed for it (using vite's color scheme)，autofit.js has helped many front-end developers, especially some users with weak foundation,It is very popular in China，As of now, it has over 2000+ collections on the juejin forum (a China's developer forum) and ranked second on the collection list in March&lt;/p&gt;

&lt;p&gt;&lt;a href="https://juejin.cn/post/7224015103481118757"&gt;Posts on Juejin&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/995231030/autofit.js"&gt;autofit.js github homepage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/autofit.js"&gt;autofit.js NPM homepage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;autofit.js is still growing and currently supports: automatically adapting to resolutions below the design draft, setting the scaled text size separately, ignoring certain elements to not be scaled, setting the playback level of scaled elements separately, and so on&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;tips:&lt;br&gt;
If you encounter abnormal element position caused by scaling during use, it may be due to using the built-in responsive third-party UI library，If there is an event hot zone shift phenomenon on the map, you can try the ignore parameter to ignore the container elements of the map&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How to use it
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Download from NPM
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i autofit.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Import
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import autofit from 'autofit.js'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;start
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;autofit.init()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default parameter for init is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;autofit.init({
        designHeight: 929,
        designWidth: 1920,
        renderDom:"#app",
        resize: true
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default parameter is 1920 * 929 (i.e. 1080 without browser header), which can be called directly at project startup，If you use Vue and use a 1920 * 1080 screen, you can directly call autofit. init() without adding any parameters，If you are using any other framework or native development, You need to call autofit.init() when the renderDom element after it is mounted,&lt;/p&gt;

&lt;h3&gt;
  
  
  conclusion
&lt;/h3&gt;

&lt;p&gt;If you like my tool, I hope to get your star or likes support. If you have any suggestions or opinions, please leave a message below the post. If you encounter any problems while using, please leave a message below the post or go to Github to submit issues. I will reply to every issue carefully. If you have used autofit.js and find it useful, don't forget to recommend it to your friends.&lt;/p&gt;

&lt;p&gt;See you in the comments section —— Larry&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
  </channel>
</rss>
