<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>前端設計｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/%E5%89%8D%E7%AB%AF%E8%A8%AD%E8%A8%88/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>前端設計｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/%E5%89%8D%E7%AB%AF%E8%A8%AD%E8%A8%88/</link><width>144</width><height>144</height></image>
    <description>林鼎淵（Dean Lin）的部落格：生成式 AI 企業內訓講師、外商資安公司軟體專家、7 本書作者。400 多篇文章用白話分享生成式 AI 實戰、Claude Code 與 Vibe Coding 教學、團隊合作與職場成長。</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <copyright>© 2020–2026 林鼎淵 Dean Lin</copyright>
    <lastBuildDate>Mon, 27 Sep 2021 08:27:06 +0800</lastBuildDate>
    <atom:link href="https://deanlin.net/tags/%E5%89%8D%E7%AB%AF%E8%A8%AD%E8%A8%88/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>[面試][前端]在使用後端的資料前，你有先做驗證嗎？</title>
      <link>https://deanlin.net/blog/202109/fullstack-career-notes-day-12/</link>
      <pubDate>Mon, 27 Sep 2021 08:27:06 +0800</pubDate>
      <guid>https://deanlin.net/blog/202109/fullstack-career-notes-day-12/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>職涯成長</category>
      <description>回想當年還是前端菜鳥時，我完全信任後端前輩回傳的資料；記得當年有個產品上線前的測試一切正常，但上線幾天後 PM 就接到客戶回報系統上有頁面顯示不全的 Bug；因為網頁前端是我負責的，所以第一個被抓去興師問罪。</description>
      <media:content url="https://deanlin.net/blog/202109/fullstack-career-notes-day-12/images/cover_hu_787c03eca8e89ac4.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<h2 id="筆者背鍋小故事">筆者背鍋小故事<a class="h-anchor" href="#%e7%ad%86%e8%80%85%e8%83%8c%e9%8d%8b%e5%b0%8f%e6%95%85%e4%ba%8b" aria-label="這個段落的連結"></a></h2>
<p>回想當年還是前端菜鳥時，我完全信任後端前輩回傳的資料；記得當年有個產品上線前的測試一切正常，但上線幾天後 PM 就接到客戶回報系統上有頁面顯示不全的 Bug；因為網頁前端是我負責的，所以第一個被抓去興師問罪。</p>
<p>經驗不足的我在收到 Bug 後，先用本機的環境模擬客戶遇到的問題，但弄了老半天始終查不出問題發生的原因；最後到客戶的正式機上查看顯示不全的頁面，才發現原來是<mark>後端忘記更新正式機的 API 版本</mark>；把狀況跟後端的前輩溝通後，才順利解決這個 Bug。</p>
<p>為了避免這種狀況再次發生；之後在寫前端時，都會先驗證後端回傳的資料是否符合規定的 JSON 資料結構。</p>
<hr>
<h2 id="大綱">大綱<a class="h-anchor" href="#%e5%a4%a7%e7%b6%b1" aria-label="這個段落的連結"></a></h2>
<ol>
<li><strong>在使用後端的資料前，你有先做驗證嗎？</strong>
<ul>
<li>1.1 面試官為什麼會問？</li>
<li>1.2 面試官想從答案確認什麼？</li>
<li>1.3 筆者提供的簡答</li>
</ul>
</li>
<li><strong>回答問題所需具備的知識</strong>
<ul>
<li>2.1 認識「JSON schema」</li>
<li>2.2 安裝「jsonschema」並了解它的優點</li>
<li>2.3 「jsonschema」驗證範例</li>
</ul>
</li>
<li><strong>衍伸問題</strong>
<ul>
<li>3.1 前端開發時會考慮哪些問題</li>
</ul>
</li>
</ol>
<hr>
<h2 class="h-nomark" id="1-在使用後端的資料前你有先做驗證嗎">1. 在使用後端的資料前，你有先做驗證嗎？<a class="h-anchor" href="#1-%e5%9c%a8%e4%bd%bf%e7%94%a8%e5%be%8c%e7%ab%af%e7%9a%84%e8%b3%87%e6%96%99%e5%89%8d%e4%bd%a0%e6%9c%89%e5%85%88%e5%81%9a%e9%a9%97%e8%ad%89%e5%97%8e" aria-label="這個段落的連結"></a></h2>
<h3 class="h-nomark" id="11-面試官為什麼會問">1.1 面試官為什麼會問？<a class="h-anchor" href="#11-%e9%9d%a2%e8%a9%a6%e5%ae%98%e7%82%ba%e4%bb%80%e9%ba%bc%e6%9c%83%e5%95%8f" aria-label="這個段落的連結"></a></h3>
<p>這算是<mark>常見面試題</mark>，主要確認你的前端技術力，這類題目範圍非常廣泛；有興趣的朋友可以看我放在參考資源的「<a href="https://h5bp.org/Front-end-Developer-Interview-Questions/translations/chinese-traditional/">前端工程師面試問題集</a>」；因為問題太過廣泛，幾乎無從準備，所以面試時<mark>就看個人基本功夠不夠深，經手的專案有沒有用到了</mark>。</p>
<hr>
<h3 class="h-nomark" id="12-面試官想從答案確認什麼">1.2 面試官想從答案確認什麼？<a class="h-anchor" href="#12-%e9%9d%a2%e8%a9%a6%e5%ae%98%e6%83%b3%e5%be%9e%e7%ad%94%e6%a1%88%e7%a2%ba%e8%aa%8d%e4%bb%80%e9%ba%bc" aria-label="這個段落的連結"></a></h3>
<ul>
<li>你過去的專案是否有做這塊的基礎驗證</li>
<li>你的基本功是否紮實</li>
</ul>
<hr>
<h3 class="h-nomark" id="13-筆者提供的簡答">1.3 筆者提供的簡答<a class="h-anchor" href="#13-%e7%ad%86%e8%80%85%e6%8f%90%e4%be%9b%e7%9a%84%e7%b0%a1%e7%ad%94" aria-label="這個段落的連結"></a></h3>
<p>現在的專案採<mark>前後端分離的架構</mark>，在前端使用後端的資料前，我會先透過「jsonschema」這款套件<mark>驗證 JSON 資料結構</mark>，確認後端回傳的欄位是否齊全、格式是否正確；以此避免前端顯示有問題的資訊，在遇到問題時也可以<mark>快速釐清是前端還是後端造成的</mark>。</p>
<hr>
<h2 class="h-nomark" id="2-回答問題所需具備的知識">2. 回答問題所需具備的知識<a class="h-anchor" href="#2-%e5%9b%9e%e7%ad%94%e5%95%8f%e9%a1%8c%e6%89%80%e9%9c%80%e5%85%b7%e5%82%99%e7%9a%84%e7%9f%a5%e8%ad%98" aria-label="這個段落的連結"></a></h2>
<h3 class="h-nomark" id="21-認識json-schema">2.1 認識「JSON schema」<a class="h-anchor" href="#21-%e8%aa%8d%e8%ad%98json-schema" aria-label="這個段落的連結"></a></h3>
<p>在介紹套件前，先讓大家對「JSON schema」有一個基礎認知；它是一種基於 JSON 格式定義 JSON 資料結構的規範，下面放上一段範例讓大家快速了解：</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#ff7b72">const</span> person_schema <span style="color:#ff7b72;font-weight:bold">=</span> {
</span></span><span style="display:flex;"><span>  type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;object&#34;</span>,
</span></span><span style="display:flex;"><span>  properties<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>    name<span style="color:#ff7b72;font-weight:bold">:</span> { type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;string&#34;</span> },
</span></span><span style="display:flex;"><span>    age<span style="color:#ff7b72;font-weight:bold">:</span> { type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;number&#34;</span>, maximum<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">150</span> },
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  required<span style="color:#ff7b72;font-weight:bold">:</span> [<span style="color:#a5d6ff">&#34;name&#34;</span>, <span style="color:#a5d6ff">&#34;age&#34;</span>],
</span></span><span style="display:flex;"><span>};
</span></span></code></pre></div><p>我相信上面這個「JSON schema」應該是非常簡單易懂，他要求 JSON 的格式需要符合以下要求：</p>
<ul>
<li>name 為 string</li>
<li>age 為 number 且最大值不得超過 150</li>
<li>name 與 age 都是必需的</li>
</ul>
<hr>
<h3 class="h-nomark" id="22-安裝jsonschema並了解它的優點">2.2 安裝「jsonschema」並了解它的優點<a class="h-anchor" href="#22-%e5%ae%89%e8%a3%9djsonschema%e4%b8%a6%e4%ba%86%e8%a7%a3%e5%ae%83%e7%9a%84%e5%84%aa%e9%bb%9e" aria-label="這個段落的連結"></a></h3>
<p>現在有許多套件提供驗證 JSON 格式的功能，今天筆者用自己熟悉的套件：「<code>jsonschema</code>」來跟讀者們分享，了解使用的邏輯後，想換成其他套件都非常容易。</p>
<h4 id="安裝步驟">安裝步驟<a class="h-anchor" href="#%e5%ae%89%e8%a3%9d%e6%ad%a5%e9%a9%9f" aria-label="這個段落的連結"></a></h4>
<ul>
<li><strong>SETP 1</strong>：建立一個專案資料夾。</li>
<li><strong>SETP 2</strong>：在終端機輸入 <code>npm init</code> 初始化專案。</li>
<li><strong>SETP 3</strong>：在終端機輸入 <code>npm i jsonschema</code> 安裝套件。</li>
</ul>
<h4 id="套件優點">套件優點<a class="h-anchor" href="#%e5%a5%97%e4%bb%b6%e5%84%aa%e9%bb%9e" aria-label="這個段落的連結"></a></h4>
<p>如果後端 API 版本變更、 DB 的 Table 欄位變更沒有通知前端，前端頁面就可能發生新資料沒有位置放、舊資料部分欄位為空的狀況；如果沒有這個套件守護前端，工程師可能就要背黑鍋了。</p>
<ul>
<li>可以詳細定義要驗證的 JSON 資料結構，包含內部所有參數的型態（string/number/array/object）。</li>
<li>驗證到錯誤格式時，會明確說明錯誤的原因。</li>
<li>可客製化錯誤訊息，轉換成好理解的文字。</li>
<li>學習及使用非常直覺。</li>
</ul>
<hr>
<h3 class="h-nomark" id="23-jsonschema驗證範例">2.3 「jsonschema」驗證範例<a class="h-anchor" href="#23-jsonschema%e9%a9%97%e8%ad%89%e7%af%84%e4%be%8b" aria-label="這個段落的連結"></a></h3>
<ul>
<li>
<p><strong>SETP 1</strong>：在專案資料夾下建立「simple.js」來了解如何驗證 JSON 資料結構。</p>
</li>
<li>
<p><strong>STEP 2</strong>：以剛剛的 <code>person_schema</code> 作為範例來跟大家做講解，程式如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#ff7b72">var</span> Validator <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#34;jsonschema&#34;</span>).Validator;
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">var</span> v <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> Validator();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> personSchema <span style="color:#ff7b72;font-weight:bold">=</span> {
</span></span><span style="display:flex;"><span>  type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;object&#34;</span>,
</span></span><span style="display:flex;"><span>  properties<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>    name<span style="color:#ff7b72;font-weight:bold">:</span> { type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;string&#34;</span> },
</span></span><span style="display:flex;"><span>    age<span style="color:#ff7b72;font-weight:bold">:</span> { type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;number&#34;</span>, maximum<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">150</span> },
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  required<span style="color:#ff7b72;font-weight:bold">:</span> [<span style="color:#a5d6ff">&#34;name&#34;</span>, <span style="color:#a5d6ff">&#34;age&#34;</span>],
</span></span><span style="display:flex;"><span>};
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">var</span> person <span style="color:#ff7b72;font-weight:bold">=</span> {
</span></span><span style="display:flex;"><span>  name<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;baobao&#34;</span>,
</span></span><span style="display:flex;"><span>  age<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">14</span>,
</span></span><span style="display:flex;"><span>};
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">let</span> result <span style="color:#ff7b72;font-weight:bold">=</span> v.validate(person, personSchema);
</span></span><span style="display:flex;"><span>console.log(<span style="color:#a5d6ff">&#34;valid：&#34;</span> <span style="color:#ff7b72;font-weight:bold">+</span> result.valid);
</span></span><span style="display:flex;"><span>console.log(result);
</span></span></code></pre></div></li>
<li>
<p><strong>STEP 3</strong>：在終端機輸入 <code>node simple.js</code>，會看到如下的驗證結果：</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span>valid<span style="color:#f85149">：</span><span style="color:#79c0ff">true</span>
</span></span><span style="display:flex;"><span>ValidatorResult {
</span></span><span style="display:flex;"><span>  instance<span style="color:#ff7b72;font-weight:bold">:</span> { name<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;baobao&#39;</span>, age<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">14</span> },
</span></span><span style="display:flex;"><span>  schema<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;object&#39;</span>,
</span></span><span style="display:flex;"><span>      properties<span style="color:#ff7b72;font-weight:bold">:</span> { name<span style="color:#ff7b72;font-weight:bold">:</span> [Object], age<span style="color:#ff7b72;font-weight:bold">:</span> [Object] },
</span></span><span style="display:flex;"><span>      required<span style="color:#ff7b72;font-weight:bold">:</span> [ <span style="color:#a5d6ff">&#39;name&#39;</span>, <span style="color:#a5d6ff">&#39;age&#39;</span> ]
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  options<span style="color:#ff7b72;font-weight:bold">:</span> {},
</span></span><span style="display:flex;"><span>  path<span style="color:#ff7b72;font-weight:bold">:</span> [],
</span></span><span style="display:flex;"><span>  propertyPath<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;instance&#39;</span>,
</span></span><span style="display:flex;"><span>  errors<span style="color:#ff7b72;font-weight:bold">:</span> [],
</span></span><span style="display:flex;"><span>  throwError<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#79c0ff">undefined</span>,
</span></span><span style="display:flex;"><span>  throwFirst<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#79c0ff">undefined</span>,
</span></span><span style="display:flex;"><span>  throwAll<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#79c0ff">undefined</span>,
</span></span><span style="display:flex;"><span>  disableFormat<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#79c0ff">false</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></li>
<li>
<p><strong>STEP 4</strong>：了解輸出參數的意義</p>
<ul>
<li><strong>valid</strong>：用布林（boolean）型態回傳驗證是否通過（true/false）。</li>
<li><strong>instance</strong>：這是我們想要驗證的資料，此範例要驗證的資料是<code>person</code>這個變數。</li>
<li><strong>schema</strong>：我們提供驗證的規則（JSON schema）。</li>
<li><strong>errors</strong>：會以陣列的形式顯示驗證發現的錯誤，你可以透過這個參數在前端顯示錯誤原因；因此次驗證的資料結構正確，故回傳空陣列。</li>
</ul>
</li>
<li>
<p><strong>STEP 5</strong>：將<code>person</code>改為錯誤的資料結構：</p>
<ul>
<li>將必填參數<code>name</code>移除</li>
<li>把 age 的數字填寫<mark>超過最大值</mark></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#ff7b72">var</span> person <span style="color:#ff7b72;font-weight:bold">=</span> {
</span></span><span style="display:flex;"><span>  age<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">200</span>,
</span></span><span style="display:flex;"><span>};
</span></span></code></pre></div></li>
<li>
<p><strong>STEP 6</strong>：在終端機輸入 <code>node simple.js</code>，確認驗證結果的 errors 是否捕捉到錯誤。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span>errors<span style="color:#ff7b72;font-weight:bold">:</span> [
</span></span><span style="display:flex;"><span>    ValidationError {
</span></span><span style="display:flex;"><span>      path<span style="color:#ff7b72;font-weight:bold">:</span> [Array],
</span></span><span style="display:flex;"><span>      property<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;instance.age&#39;</span>,
</span></span><span style="display:flex;"><span>      message<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;must be less than or equal to 150&#39;</span>,
</span></span><span style="display:flex;"><span>      schema<span style="color:#ff7b72;font-weight:bold">:</span> [Object],
</span></span><span style="display:flex;"><span>      instance<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">200</span>,
</span></span><span style="display:flex;"><span>      name<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;maximum&#39;</span>,
</span></span><span style="display:flex;"><span>      argument<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">150</span>,
</span></span><span style="display:flex;"><span>      stack<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;instance.age must be less than or equal to 150&#39;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    ValidationError {
</span></span><span style="display:flex;"><span>      path<span style="color:#ff7b72;font-weight:bold">:</span> [],
</span></span><span style="display:flex;"><span>      property<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;instance&#39;</span>,
</span></span><span style="display:flex;"><span>      message<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;requires property &#34;name&#34;&#39;</span>,
</span></span><span style="display:flex;"><span>      schema<span style="color:#ff7b72;font-weight:bold">:</span> [Object],
</span></span><span style="display:flex;"><span>      instance<span style="color:#ff7b72;font-weight:bold">:</span> [Object],
</span></span><span style="display:flex;"><span>      name<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;required&#39;</span>,
</span></span><span style="display:flex;"><span>      argument<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;name&#39;</span>,
</span></span><span style="display:flex;"><span>      stack<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;instance requires property &#34;name&#34;&#39;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>],
</span></span></code></pre></div></li>
</ul>
<p>透過以上範例，相信大家都明白「jsonschema」套件的基礎使用方式，有興趣深入研究的朋友請參考<a href="https://www.npmjs.com/package/jsonschema">官網</a>文件；如果沒接觸過「JSON schema」的朋友建議自己手動實做看看，這算是非常重要的前端概念。</p>
<hr>
<h2 class="h-nomark" id="3-衍伸問題">3. 衍伸問題<a class="h-anchor" href="#3-%e8%a1%8d%e4%bc%b8%e5%95%8f%e9%a1%8c" aria-label="這個段落的連結"></a></h2>
<h3 class="h-nomark" id="31-前端開發時會考慮哪些問題">3.1 前端開發時會考慮哪些問題<a class="h-anchor" href="#31-%e5%89%8d%e7%ab%af%e9%96%8b%e7%99%bc%e6%99%82%e6%9c%83%e8%80%83%e6%85%ae%e5%93%aa%e4%ba%9b%e5%95%8f%e9%a1%8c" aria-label="這個段落的連結"></a></h3>
<blockquote>
<p>這就是個大哉問，每個人都有自己考慮的點，我建議回答自己擅長且真的有導入專案的部分，因為通常後續會有更深入的問題。</p>
</blockquote>
<p><mark>考點：透過一個廣泛的問題，了解你開發時最在意的點</mark></p>
<p>為了<mark>減少設計變更</mark>，在開始前會先請 UI/UX 設計好 <code>Wireframe</code>（<a href="https://www.figma.com/">Figma</a>），並向使用者說明流程<mark>取得共識</mark>，直到雙方確認都沒問題後再進入開發階段；為了讓網頁風格一致，前端在設計時會遵循 <code>Material Design</code>。</p>
<p>為了提升開發效率，會先思考哪個 <code>Framework</code> 較適合這個專案；在依照設計提供的 Protype 完成設計後，會先用<a href="https://medium.com/dean-lin/de5f9efe9f4c">Responsively</a>這款工具，確認網頁在<mark>不同解析度的裝置上是否會跑版</mark>。</p>
<p>完成前期開發後，會思考如何<mark>優化效能</mark>，像是用 lazy loading 提升頁面載入速度、減少頁面 Request 數量及 Response 時間，透過這些設計讓使用者有更好的體驗。</p>
<hr>
<p>感謝大家的閱讀，如果喜歡我的文章可以<code>訂閱</code>接收通知；如果有幫助到你，按<code>Like</code>可以讓我更有寫文的動力，我們明天見～</p>
<h3 id="參考資源">參考資源<a class="h-anchor" href="#%e5%8f%83%e8%80%83%e8%b3%87%e6%ba%90" aria-label="這個段落的連結"></a></h3>
<ol>
<li><a href="https://medium.com/dean-lin/a0940809a394#08eb">拒當前端黑鍋俠！用「jsonschema」來驗證後端回傳的 json 資料結構(筆者部落格)</a></li>
<li><a href="https://github.com/ajv-validator/ajv">ajv-validator/ajv</a></li>
<li><a href="https://github.com/Hsueh-Jen/blog/issues/2">驗證資料的好幫手 - JSON Schema Validator</a></li>
<li><a href="https://h5bp.org/Front-end-Developer-Interview-Questions/translations/chinese-traditional/">前端工程師面試問題集</a></li>
</ol>
<hr>
<hr>
<blockquote>
<p><img src="https://deanlin.net/blog/202109/fullstack-career-notes-day-12/images/fullstack-career-notes-day-12-01.webp" width="1024" height="233" alt="參考資源（圖 1）" fetchpriority="high" decoding="async"></p>
<p>在許多人的幫助下，本系列文章已成功出版，除了添加新的篇章，更完善了每個案例的應對進退；如果對現在的職涯感到迷茫，也許這本書能帶給你不一樣的觀點～</p>
<p><strong>天瓏書局：</strong> <a href="https://www.tenlong.com.tw/products/9786263334571">https://www.tenlong.com.tw/products/9786263334571</a></p>
</blockquote>
]]></content:encoded>
    </item>
  </channel>
</rss>
